20130313
[gdash.git] / src / cave / gamecontrol.cpp
blobdd6a45dd09e607c612d7b3abfc7678d0fe1d63d7
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 #include "config.h"
18 #include <glib.h>
19 #include <glib/gi18n.h>
21 #include "cave/cavestored.hpp"
22 #include "cave/caverendered.hpp"
23 #include "cave/caveset.hpp"
24 #include "settings.hpp"
25 #include "sound/sound.hpp"
26 #include "misc/util.hpp"
28 #include "cave/gamecontrol.hpp"
31 /* prepare cave, gfx buffer */
32 #define GAME_INT_LOAD_CAVE -74
33 /* show description/note of cave. */
34 #define GAME_INT_SHOW_STORY -73
35 /* waiting fire button after showing the story. */
36 #define GAME_INT_SHOW_STORY_WAIT -72
37 /* after clicking, when the story seen. */
38 #define GAME_INT_STORY_CLICKED -71
39 /* start uncovering */
40 #define GAME_INT_START_UNCOVER -70
41 /* ...70 frames until full uncover... */
42 #define GAME_INT_UNCOVER_ALL -1
43 /* normal running state. */
44 #define GAME_INT_CAVE_RUNNING 0
45 /* add points for remaining time */
46 #define GAME_INT_CHECK_BONUS_TIME 1
47 /* ...2..99 = wait and do nothing, after adding time */
48 #define GAME_INT_WAIT_BEFORE_COVER 2
49 /* start covering */
50 #define GAME_INT_COVER_START 100
51 /* ... 8 frames of cover animation */
52 #define GAME_INT_COVER_ALL 108
54 /// The default constructor which fills members with some initial values.
55 GameControl::GameControl() :
56 player_score(0),
57 player_lives(0),
58 caveset(NULL),
59 played_cave(NULL),
60 original_cave(NULL),
61 bonus_life_flash(0),
62 animcycle(0),
63 story_shown(false),
64 replay_record(NULL),
65 replay_from(NULL),
66 cave_num(0),
67 level_num(0),
68 milliseconds_game(0),
69 milliseconds_anim(0),
70 state_counter(GAME_INT_LOAD_CAVE) {
73 GameControl::~GameControl() {
74 /* stop sounds */
75 gd_sound_off();
77 if (played_cave)
78 delete played_cave;
79 if (replay_record)
80 delete replay_record;
84 /// Create a full game from the caveset.
85 /// @returns A newly allocated GameControl. Free with delete.
86 GameControl *GameControl::new_normal(CaveSet *caveset, std::string player_name, int cave, int level) {
87 GameControl *g=new GameControl;
89 g->type=TYPE_NORMAL;
91 g->caveset=caveset;
92 g->player_name=player_name;
93 g->cave_num=cave;
94 g->level_num=level;
95 g->player_lives=g->caveset->initial_lives;
96 g->story_shown=false;
98 return g;
101 /// Create a new game of a single snapshow.
102 /// @returns A newly allocated GameControl. Free with delete.
103 GameControl *GameControl::new_snapshot(const CaveRendered *snapshot) {
104 GameControl *g=new GameControl;
106 g->played_cave=new CaveRendered(*snapshot);
107 g->type=TYPE_SNAPSHOT;
109 return g;
112 /// Create a new game to test in the editor.
113 /// @returns A newly allocated GameControl. Free with delete.
114 GameControl *GameControl::new_test(CaveStored *cave, int level) {
115 GameControl *g=new GameControl;
117 g->original_cave=cave;
118 g->level_num=level;
119 g->type=TYPE_TEST;
121 return g;
124 /// Create a cave replay.
125 /// @returns A newly allocated GameControl. Free with delete.
126 GameControl *GameControl::new_replay(CaveSet *caveset, CaveStored *cave, CaveReplay *replay) {
127 GameControl *g=new GameControl;
129 g->caveset=caveset;
130 g->original_cave=cave;
131 g->replay_from=replay;
132 g->type=TYPE_REPLAY;
134 return g;
138 /// Add a bonus life (if live number is not more than maximum number of lives.
139 /// Only feasible for normal games, not for replays or tests.
140 /// @param inform_user If set to true, will also show bonus life flash. Sometimes this
141 /// is not desired (after completing an intermission, for example).
142 void GameControl::add_bonus_life(bool inform_user) {
143 /* only inform about bonus life when playing a game */
144 /* or when testing the cave (so the user can see that a bonus life can be earned in that cave */
145 if (type==TYPE_NORMAL || type==TYPE_TEST)
146 if (inform_user) {
147 gd_sound_play_bonus_life();
148 bonus_life_flash=100;
151 /* really increment number of lifes? only in a real game, nowhere else. */
152 if (type==TYPE_NORMAL && player_lives<caveset->maximum_lives)
153 /* only add a life, if lives is >0. lives==0 is a test run or a snapshot, no bonus life then. */
154 /* also, obey max number of bonus lives. */
155 player_lives++;
158 /// Increment score of the player.
159 /// Store in the game score, in player score, and also in the replay, if any.
160 /// If a bonus life is got, show bonus life flash.
161 void GameControl::increment_score(int increment) {
162 int i=0;
164 if (caveset)
165 i=player_score/caveset->bonus_life_score;
166 player_score+=increment;
167 cave_score+=increment;
168 if (replay_record) /* also record to replay */
169 replay_record->score+=increment;
170 if (caveset && player_score/caveset->bonus_life_score>i)
171 add_bonus_life(true); /* if score crossed bonus_life_score point boundary, player won a bonus life */
175 /// Load the cave.
176 /// The role of this function greatly depends on the GameControl type.
177 /// The cave might be loaded from a caveset, it might be just a copy of a CaveRendered given.
178 void GameControl::load_cave() {
179 guint32 seed;
181 /* delete gfx buffer */
182 gfx_buffer.remove();
183 covered.remove();
185 /* load the cave */
186 cave_score=0;
187 switch (type) {
188 case TYPE_NORMAL:
189 /* delete previous cave */
190 delete played_cave;
192 /* specified cave from memory; render the cave with a randomly selected seed */
193 original_cave=&caveset->cave(cave_num);
194 seed=g_random_int_range(0, GD_CAVE_SEED_MAX);
195 played_cave=new CaveRendered(*original_cave, level_num, seed); /* for playing: seed=random */
196 played_cave->setup_for_game();
197 if (played_cave->intermission && played_cave->intermission_instantlife)
198 add_bonus_life(false);
200 /* create replay */
201 replay_record=new CaveReplay;
202 replay_record->level=played_cave->rendered_on+1; /* compatibility with bdcff - level=1 is written in file */
203 replay_record->seed=played_cave->render_seed;
204 replay_record->checksum=gd_cave_adler_checksum(*played_cave); /* calculate a checksum for this cave */
205 replay_record->recorded_with=PACKAGE_STRING; // name of gdash and version
206 replay_record->player_name=player_name;
207 replay_record->date=gd_get_current_date_time();
208 break;
210 case TYPE_TEST:
211 g_assert(original_cave!=NULL);
213 /* delete previous try */
214 delete played_cave;
216 seed=g_random_int_range(0, GD_CAVE_SEED_MAX);
217 played_cave=new CaveRendered(*original_cave, level_num, seed); /* for playing: seed=random */
218 played_cave->setup_for_game();
219 break;
221 case TYPE_SNAPSHOT:
222 /* if a snapshot or test is requested, that one... just create a copy */
223 /* copy already created in new_game, so nothing to do here. */
224 g_assert(played_cave!=NULL);
225 g_assert(original_cave==NULL);
226 break;
228 case TYPE_REPLAY:
229 g_assert(replay_from!=NULL);
230 g_assert(played_cave==NULL);
232 replay_record=NULL;
233 replay_from->rewind();
234 replay_no_more_movements=0;
236 /* -1 is because level=1 is in bdcff for level 1, and internally we number levels from 0 */
237 played_cave=new CaveRendered(*original_cave, replay_from->level-1, replay_from->seed);
238 played_cave->setup_for_game();
239 break;
241 case TYPE_CONTINUE_REPLAY:
242 g_assert_not_reached();
243 break;
246 milliseconds_anim=0;
247 milliseconds_game=0; /* set game timer to zero, too */
248 state_counter=GAME_INT_SHOW_STORY;
252 /// Gives a snapshot of the currently played cave.
253 /// @return The snapshot, free with delete.
254 CaveRendered *GameControl::create_snapshot() const {
255 /* make an exact copy */
256 return new CaveRendered(*played_cave);
260 /// For games, calculate the next cave number and level number.
261 /// Called from main_int(), in a normal game, when the cave
262 /// is successfully finished (or not successfully, but it is an
263 /// intermission).
264 /// This does NOT load the new cave, just calculates its number.
265 void GameControl::select_next_level_indexes() {
266 cave_num++; /* next cave */
268 /* if no more caves at this level, back to first one */
269 if (cave_num>=caveset->caves.size()) {
270 cave_num=0;
271 level_num++; /* but now more difficult */
272 if (level_num>4)
273 /* if level 5 finished, back to first cave, same difficulty (original game behaviour) */
274 level_num=4;
277 /* show story. */
278 /* if the user fails to solve the cave, the story will not be shown again */
279 story_shown=false;
284 * functions for different states.
287 /// Show story for a cave, if it has not been already shown.
288 GameControl::State GameControl::show_story() {
289 State return_state;
291 /* if we have a story... */
292 /* and user settings permit showing that... etc */
293 if (gd_show_story && !story_shown && type==TYPE_NORMAL && original_cave->story!="") {
294 played_cave->clear_sounds(); /* to stop cover sound from previous cave; there should be no cover sound when the user reads the story */
295 gd_sound_play_sounds(played_cave->sound1, played_cave->sound2, played_cave->sound3);
296 state_counter=GAME_INT_SHOW_STORY_WAIT;
297 return_state=STATE_SHOW_STORY;
298 story_shown=true; /* so the story will not be shown again, for example when the cave is not solved and played again. */
299 } else {
300 /* if no story */
301 state_counter=GAME_INT_STORY_CLICKED;
302 return_state=STATE_NOTHING;
305 return return_state;
308 /// Start uncover animation. Create gfx buffers.
309 void GameControl::start_uncover() {
310 /* create gfx buffer. fill with "invalid" */
311 gfx_buffer.set_size(played_cave->w, played_cave->h, -1);
312 /* cover all cells of cave */
313 covered.set_size(played_cave->w, played_cave->h, true);
315 /* to play cover sound */
316 played_cave->clear_sounds();
317 played_cave->sound_play(GD_S_COVER, played_cave->player_x, played_cave->player_y);
318 gd_sound_play_sounds(played_cave->sound1, played_cave->sound2, played_cave->sound3);
320 /* advance to next state */
321 state_counter+=1;
324 /// One frame of the uncover animation.
325 void GameControl::uncover_animation() {
326 /* original game uncovered one cell per line each frame.
327 * we have different cave sizes, so uncover width*height/40 random cells each frame. (original was width=40).
328 * this way the uncovering is the same speed also for intermissions. */
329 for (int j=0; j<played_cave->w*played_cave->h/40; j++)
330 covered(g_random_int_range(0, played_cave->w), g_random_int_range(0, played_cave->h))=false;
331 state_counter+=1; /* as we did something, advance the counter. */
335 /// Uncover all cells of cave, and switch in to the normal cave running state.
336 void GameControl::uncover_all() {
337 covered.fill(false);
339 /* to stop uncover sound. */
340 played_cave->clear_sounds();
341 gd_sound_play_sounds(played_cave->sound1, played_cave->sound2, played_cave->sound3);
343 state_counter=GAME_INT_CAVE_RUNNING;
347 /// One frame of the cover animation.
348 void GameControl::cover_animation() {
349 /* covering eight times faster than uncovering. */
350 for (int j=0; j<played_cave->w*played_cave->h*8/40; j++)
351 covered(g_random_int_range(0, played_cave->w), g_random_int_range(0, played_cave->h))=true;
353 state_counter+=1; /* as we did something, advance the counter. */
357 /// Iterate the cave.
358 /// @param millisecs_elapsed The number of milliseconds elapsed since the last call.
359 /// @param fast_forward If set to true, cave will be iterated at 25fps, regardless of cave speed calculated by the cave.
360 /// @param player_move The direction of move, by keypresses.
361 /// @param fire If the user pressed the fire.
362 /// @param suicide If the user pressed the suicide button.
363 /// @param restart If the user requested a cave restart.
364 GameControl::State GameControl::iterate_cave(int millisecs_elapsed, bool fast_forward, GdDirectionEnum player_move, bool fire, bool suicide, bool restart) {
365 State return_state;
367 int irl_cavespeed; // caveset in real life. if fast_forward is enabled, we ignore the speed of the cave (but it thinks it runs at normal speed)
368 if (!fast_forward)
369 irl_cavespeed=played_cave->speed; /* cave speed in ms, like 175ms/frame */
370 else
371 irl_cavespeed=40; /* if fast forward, ignore cave speed, and go as 25 iterations/sec */
373 /* if we are playing a replay, but the user intervents, continue as a snapshot. */
374 /* do not trigger this for fire, as it would not be too intuitive. */
375 if (type==TYPE_REPLAY)
376 if (player_move!=MV_STILL) {
377 type=TYPE_CONTINUE_REPLAY;
378 replay_from=NULL;
381 /* ANYTHING EXCEPT A TIMEOUT, WE ITERATE THE CAVE */
382 /* iterate cave */
383 return_state=STATE_NOTHING; /* normally nothing happes. but if we iterate, this might change. */
384 milliseconds_game+=millisecs_elapsed;
386 /* decide if cave will be iterated. */
387 if (played_cave->player_state!=GD_PL_TIMEOUT && milliseconds_game>=irl_cavespeed) {
388 // ok, cave has to be iterated.
390 /* IF PLAYING FROM REPLAY, OVERWRITE KEYPRESS VARIABLES FROM REPLAY */
391 if (type==TYPE_REPLAY) {
392 /* if the user does touch the keyboard, we immediately exit replay, and he can continue playing */
393 bool result=replay_from->get_next_movement(player_move, fire, suicide);
394 /* if could not get move from snapshot, continue from keyboard input. */
395 if (!result)
396 replay_no_more_movements++;
397 /* if no more available movements, and the user does not do anything, we cover cave and stop game. */
398 if (replay_no_more_movements>15)
399 state_counter=GAME_INT_COVER_START;
402 milliseconds_game -= irl_cavespeed;
403 // if recording the replay, now store the movement
404 if (replay_record)
405 replay_record->store_movement(player_move, fire, suicide);
407 PlayerState player_state_prev = played_cave->player_state;
409 // cave iterate gives us a new player move, which might have diagonal movements removed
410 player_move=played_cave->iterate(player_move, fire, suicide);
412 if (played_cave->score)
413 increment_score(played_cave->score);
414 return_state = STATE_LABELS_CHANGED; /* as we iterated, the score and the like could have been changed. */
415 if (player_state_prev != GD_PL_TIMEOUT && played_cave->player_state==GD_PL_TIMEOUT)
416 return_state = STATE_TIMEOUT_NOW; /* and if the cave timeouted at this exact moment, that is a special case. */
418 gd_sound_play_sounds(played_cave->sound1, played_cave->sound2, played_cave->sound3);
421 if (played_cave->player_state==GD_PL_EXITED) {
422 /* start adding points for remaining time */
423 state_counter=GAME_INT_CHECK_BONUS_TIME;
424 played_cave->clear_sounds();
425 played_cave->sound_play(GD_S_FINISHED, played_cave->player_x, played_cave->player_y); /* play cave finished sound */
426 gd_sound_play_sounds(played_cave->sound1, played_cave->sound2, played_cave->sound3);
429 /* player died and user presses fire -> try again */
430 /* time out and user presses fire -> try again */
431 /* user requests cave restart (when stuck under stones) -> try again */
432 if (((played_cave->player_state==GD_PL_DIED || played_cave->player_state==GD_PL_TIMEOUT) && fire) || restart) {
433 if (type==TYPE_NORMAL && player_lives==0) {
434 /* wait some time - this is a game over */
435 state_counter=GAME_INT_WAIT_BEFORE_COVER;
437 else {
438 /* start cover animation immediately */
439 state_counter=GAME_INT_COVER_START;
443 return return_state;
446 /// After adding bonus points, we wait some time before starting to cover.
447 /// This is the FIRST frame... so we check for game over and maybe jump there.
448 /// If no more lives, game is over.
449 GameControl::State GameControl::wait_before_cover() {
450 State return_state;
452 state_counter+=1; /* 40ms elapsed, advance counter */
453 if (type==TYPE_NORMAL && player_lives==0)
454 return_state=STATE_NO_MORE_LIVES;
455 else
456 return_state=STATE_NOTHING;
458 return return_state;
461 /// Add some bonus scores.
462 /// This may advance the state, or not - depending on if there is still cave time left.
463 GameControl::State GameControl::check_bonus_score() {
464 State return_state;
466 /* player exited, but some time remained. now count bonus points. */
467 /* if time remaining, bonus points are added. do not start animation yet. */
468 if (played_cave->time>0) {
469 // cave time is mult'd by timing factor, which is 1000 or 1200, depending on cave pal setting.
470 // we do not really care this here, but have to multiply.
471 if (played_cave->time>60*played_cave->timing_factor) { /* if much time (>60s) remained, fast counter :) */
472 played_cave->time-=9*played_cave->timing_factor; /* decrement by nine each frame, so it also looks like a fast counter. 9 is 8+1! */
473 increment_score(played_cave->timevalue*9);
474 } else {
475 played_cave->time-=played_cave->timing_factor; /* subtract number of "milliseconds" - nothing to do with gameplay->millisecs! */
476 increment_score(played_cave->timevalue); /* higher levels get more bonus points per second remained */
478 // maybe we we substracted too much (remaining time was fraction of a second)
479 if (played_cave->time<0)
480 played_cave->time=0;
482 else
483 /* if no more points, start waiting a bit, and later start covering. */
484 state_counter=GAME_INT_WAIT_BEFORE_COVER;
486 /* play bonus sound - which is the same as the seconds sound, when only <10 seconds left */
487 played_cave->set_seconds_sound();
488 gd_sound_play_sounds(played_cave->sound1, played_cave->sound2, played_cave->sound3);
489 return_state=STATE_LABELS_CHANGED;
491 return return_state;
494 /// After finishing the cave cover animation, decide what to do next.
495 /// For a normal game, manage replays, and select next level.
496 /// For testing, do nothing, as the cave will be reloaded.
497 /// For other types, signal GameControl finish.
498 GameControl::State GameControl::finished_covering() {
499 State return_state;
500 gfx_buffer.remove();
501 covered.remove();
503 /* if this is a normal game: */
504 if (type==TYPE_NORMAL) {
505 // if the replay was successful, or it has some length which makes sense, add it to the cave.
506 if (replay_record->success || replay_record->length()>=16)
507 caveset->cave(cave_num).replays.push_back(*replay_record);
508 delete replay_record;
509 replay_record=0;
511 switch (played_cave->player_state) {
512 case GD_PL_EXITED:
513 // one life extra for completing intermission
514 if (played_cave->intermission && played_cave->intermission_rewardlife)
515 add_bonus_life(false);
516 // we also have added points for remaining time -> now check for highscore
517 caveset->cave(cave_num).highscore.add(player_name, cave_score);
518 break;
519 case GD_PL_DIED:
520 case GD_PL_TIMEOUT:
521 if (!played_cave->intermission && player_lives>0) // normal cave, died -> lives decreased
522 player_lives--;
523 break;
525 case GD_PL_LIVING:
526 case GD_PL_NOT_YET:
527 break;
529 /* if successful or this was an intermission, advance to next level.
530 * for intermissions, there is only one chance given, so always go to next. */
531 if (played_cave->player_state == GD_PL_EXITED || played_cave->intermission)
532 select_next_level_indexes();
534 if (player_lives>0)
535 return_state=STATE_NOTHING;
536 else
537 return_state=STATE_GAME_OVER;
539 else
540 if (type == TYPE_TEST) {
541 /* if testing, start again. do nothing, cave will be reloaded. */
542 return_state = STATE_NOTHING;
544 else
545 /* for snapshots and replays and the like, this is the end. */
546 return_state=STATE_STOP;
548 /* load next cave on next call. */
549 state_counter = GAME_INT_LOAD_CAVE;
550 return return_state;
554 /// The main_int function, which controls the whole working of a GameControl.
555 /// @param millisecs_elapsed The number of milliseconds elapsed since the last call.
556 /// @param player_move The direction of move, by keypresses.
557 /// @param fire If the user pressed the fire.
558 /// @param suicide If the user pressed the suicide button.
559 /// @param restart If the user requested a cave restart.
560 /// @param allow_iterate If the game is paused by the user, this prevents the cave from iterating. But the cells are still animated!
561 /// @param fast_forward If set to true, cave will be iterated at 25fps, regardless of cave speed calculated by the cave.
562 GameControl::State GameControl::main_int(int millisecs_elapsed, GdDirectionEnum player_move, bool fire, bool suicide, bool restart, bool allow_iterate, bool fast_forward) {
563 State return_state;
565 milliseconds_anim+=millisecs_elapsed; /* keep track of time */
566 bool is_animation_frame=false; /* set to true, if this will be an animation frame */
567 if (milliseconds_anim>=40) { /* 40 ms -> 25 fps */
568 is_animation_frame=true;
569 milliseconds_anim-=40;
570 if (bonus_life_flash > 0) /* bonus life - frames */
571 bonus_life_flash--;
572 animcycle = (animcycle+1) % 8;
576 if (state_counter<GAME_INT_LOAD_CAVE) {
577 /* cannot be less than uncover start. */
578 g_assert_not_reached();
580 else
581 if (state_counter==GAME_INT_LOAD_CAVE) {
582 /* do our tasks associated with loading a new cave. */
583 /* the caller will not know about this yet */
584 load_cave();
585 return_state=STATE_CAVE_LOADED;
587 else
588 if (state_counter==GAME_INT_SHOW_STORY) {
589 /* for normal game, every cave can have a long string of description/story. show that. */
590 return_state=show_story();
592 else
593 if (state_counter==GAME_INT_SHOW_STORY_WAIT) {
594 /* if we are showing the story, we are waiting for the user to press fire. nothing else */
595 /* if user presses fire (or maybe esc), proceed with loading the cave. */
596 if (fire || restart)
597 state_counter=GAME_INT_STORY_CLICKED;
598 return_state=STATE_SHOW_STORY_WAIT;
600 else
601 if (state_counter==GAME_INT_STORY_CLICKED) {
602 state_counter=GAME_INT_START_UNCOVER;
603 return_state=STATE_PREPARE_FIRST_FRAME;
605 else
606 if (state_counter==GAME_INT_START_UNCOVER) {
607 /* the very beginning. this will be the first cave frame drawn by the caller. */
608 start_uncover();
609 /* very important: tell the caller that we loaded a new cave. */
610 /* size of the cave might be new, colors might be new, and so on. */
611 return_state=STATE_FIRST_FRAME;
613 else
614 if (state_counter<GAME_INT_UNCOVER_ALL) {
615 /* uncover animation */
616 if (is_animation_frame)
617 uncover_animation();
618 /* if fast uncover animation in test requested, do 3 more times */
619 if (type == TYPE_TEST && gd_fast_uncover_in_test)
620 for (unsigned i = 0; i < 3 && state_counter<GAME_INT_UNCOVER_ALL; ++i)
621 uncover_animation();
622 return_state=STATE_NOTHING;
624 else
625 if (state_counter==GAME_INT_UNCOVER_ALL) {
626 /* time to uncover the whole cave. */
627 uncover_all();
628 return_state=STATE_NOTHING;
630 else
631 if (state_counter==GAME_INT_CAVE_RUNNING) {
632 /* normal. */
633 if (allow_iterate)
634 return_state=iterate_cave(millisecs_elapsed, fast_forward, player_move, fire, suicide, restart);
635 else
636 return_state=STATE_NOTHING;
638 else
639 if (state_counter==GAME_INT_CHECK_BONUS_TIME) {
640 /* before covering, we check for time bonus score */
641 if (is_animation_frame) {
642 check_bonus_score();
643 return_state=STATE_LABELS_CHANGED;
645 else
646 return_state=STATE_NOTHING;
648 else
649 if (state_counter==GAME_INT_WAIT_BEFORE_COVER) {
650 /* after adding bonus points, we wait some time before starting to cover. this is the FIRST frame... so we check for game over and maybe jump there */
651 /* if no more lives, game is over. */
652 if (is_animation_frame)
653 return_state=wait_before_cover();
654 else
655 return_state=STATE_NOTHING;
657 else
658 if (state_counter>GAME_INT_WAIT_BEFORE_COVER && state_counter<GAME_INT_COVER_START) {
659 /* after adding bonus points, we wait some time before starting to cover. ... and the other frames. */
660 /* here we do nothing, but wait */
661 if (is_animation_frame)
662 state_counter+=1; /* 40ms elapsed, advance counter */
663 return_state=STATE_NOTHING;
665 else
666 /* starting to cover. start cover sound. */
667 if (state_counter==GAME_INT_COVER_START) {
669 played_cave->clear_sounds();
670 played_cave->sound_play(GD_S_COVER, played_cave->player_x, played_cave->player_y);
671 /* to play cover sound */
672 gd_sound_play_sounds(played_cave->sound1, played_cave->sound2, played_cave->sound3);
674 state_counter+=1;
675 return_state=STATE_NOTHING;
677 else
678 /* covering. */
679 if (state_counter>GAME_INT_COVER_START && state_counter<GAME_INT_COVER_ALL) {
680 if (is_animation_frame)
681 cover_animation();
682 return_state=STATE_NOTHING;
684 else
685 if (state_counter==GAME_INT_COVER_ALL) {
686 /* cover all */
687 covered.fill(true);
689 state_counter+=1;
690 return_state=STATE_NOTHING;
692 else {
693 return_state=finished_covering();
696 return return_state;