From ac86d841daa4ecafff3128110a1db109e03fb355 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 28 Aug 2006 22:49:38 +0200 Subject: [PATCH] rnd-20060828-1-src * fixed bug in GameWon() when level contains no exit (like in Sokoban) --- ChangeLog | 3 + src/conftime.h | 2 +- src/events.c | 14 +++++ src/game.c | 141 ++++++++++++++++++++++++++++++++++++++----- src/game.h | 6 ++ src/game_em/export.h | 6 +- src/game_em/init.c | 4 +- src/game_em/input.c | 24 ++++++-- src/init.c | 2 +- src/libgame/misc.c | 28 +++++++++ src/libgame/misc.h | 11 ++-- src/libgame/toons.c | 14 ++--- src/main.h | 2 - src/tape.c | 5 +- src/tools.c | 8 ++- 15 files changed, 228 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef7d0b25..e1a10406 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2006-08-28 + * fixed bug in GameWon() when level contains no exit (like in Sokoban) + 2006-08-23 * added engine snapshot functionality for instant tape reloading (this only works for the last tape saved using "quick save", and does not diff --git a/src/conftime.h b/src/conftime.h index b906aa53..2d59984d 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2006-08-24 00:46]" +#define COMPILE_DATE_STRING "[2006-08-28 22:47]" diff --git a/src/events.c b/src/events.c index d42acf56..65b06803 100644 --- a/src/events.c +++ b/src/events.c @@ -245,7 +245,11 @@ void ClearEventQueue() break; case EVENT_KEYRELEASE: +#if 1 + ClearPlayerAction(); +#else key_joystick_mapping = 0; +#endif break; default: @@ -700,8 +704,14 @@ void HandleKey(Key key, int key_status) return; } +#if 1 + if (game_status == GAME_MODE_PLAYING && + local_player->LevelSolved_GameEnd && + (key == KSYM_Return || key == setup.shortcut.toggle_pause)) +#else if (game_status == GAME_MODE_PLAYING && AllPlayersGone && (key == KSYM_Return || key == setup.shortcut.toggle_pause)) +#endif { GameEnd(); @@ -1045,7 +1055,11 @@ void HandleJoystick() if (tape.playing || keyboard) newbutton = ((joy & JOY_BUTTON) != 0); +#if 1 + if (local_player->LevelSolved_GameEnd && newbutton) +#else if (AllPlayersGone && newbutton) +#endif { GameEnd(); diff --git a/src/game.c b/src/game.c index 489c476b..05a0b9ab 100644 --- a/src/game.c +++ b/src/game.c @@ -142,7 +142,7 @@ #define GET_DX_FROM_DIR(d) ((d) == MV_LEFT ? -1 : (d) == MV_RIGHT ? 1 : 0) #define GET_DY_FROM_DIR(d) ((d) == MV_UP ? -1 : (d) == MV_DOWN ? 1 : 0) -#define INIT_GFX_RANDOM() (SimpleRND(1000000)) +#define INIT_GFX_RANDOM() (GetSimpleRandom(1000000)) #define GET_NEW_PUSH_DELAY(e) ( (element_info[e].push_delay_fixed) + \ RND(element_info[e].push_delay_random)) @@ -2671,12 +2671,14 @@ void GameWon() static int game_over_delay = 0; int game_over_delay_value = 50; - /* do not start end game actions before the player stops moving (to exit) */ - if (local_player->MovPos) - return; - if (!local_player->LevelSolved_GameEnd) { + int i; + + /* do not start end game actions before the player stops moving (to exit) */ + if (local_player->MovPos) + return; + local_player->LevelSolved_GameEnd = TRUE; local_player->LevelSolved_SaveTape = tape.recording; local_player->LevelSolved_SaveScore = !tape.playing; @@ -2684,6 +2686,10 @@ void GameWon() if (tape.auto_play) /* tape might already be stopped here */ tape.auto_play_level_solved = TRUE; +#if 1 + TapeStop(); +#endif + game_over_delay = game_over_delay_value; time = time_final = (level.time == 0 ? TimePlayed : TimeLeft); @@ -2730,6 +2736,19 @@ void GameWon() DrawLevelField(ExitX, ExitY); } + for (i = 0; i < MAX_PLAYERS; i++) + { + struct PlayerInfo *player = &stored_player[i]; + + if (player->present) + { + RemovePlayer(player); + + /* player disappears */ + DrawLevelField(player->jx, player->jy); + } + } + PlaySound(SND_GAME_WINNING); } @@ -2770,7 +2789,9 @@ void GameEnd() if (local_player->LevelSolved_SaveTape) { +#if 0 TapeStop(); +#endif SaveTape(tape.level_nr); /* ask to save tape */ } @@ -7207,7 +7228,7 @@ void EdelsteinFunkeln(int x, int y) return; if (MovDelay[x][y] == 0) /* next animation frame */ - MovDelay[x][y] = 11 * !SimpleRND(500); + MovDelay[x][y] = 11 * !GetSimpleRandom(500); if (MovDelay[x][y] != 0) /* wait some time before next frame */ { @@ -8672,11 +8693,11 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) player->frame_counter_bored = FrameCounter + game.player_boring_delay_fixed + - SimpleRND(game.player_boring_delay_random); + GetSimpleRandom(game.player_boring_delay_random); player->frame_counter_sleeping = FrameCounter + game.player_sleeping_delay_fixed + - SimpleRND(game.player_sleeping_delay_random); + GetSimpleRandom(game.player_sleeping_delay_random); InitPlayerGfxAnimation(player, ACTION_WAITING, move_dir); } @@ -8732,10 +8753,10 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) player->anim_delay_counter = graphic_info[special_graphic].anim_delay_fixed + - SimpleRND(graphic_info[special_graphic].anim_delay_random); + GetSimpleRandom(graphic_info[special_graphic].anim_delay_random); player->post_delay_counter = graphic_info[special_graphic].post_delay_fixed + - SimpleRND(graphic_info[special_graphic].post_delay_random); + GetSimpleRandom(graphic_info[special_graphic].post_delay_random); player->special_action_sleeping = special_action; } @@ -8758,16 +8779,16 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) if (player->anim_delay_counter == 0 && player->post_delay_counter == 0) { int special_action = - ACTION_BORING_1 + SimpleRND(player->num_special_action_bored); + ACTION_BORING_1 + GetSimpleRandom(player->num_special_action_bored); int special_graphic = el_act_dir2img(player->artwork_element, special_action, move_dir); player->anim_delay_counter = graphic_info[special_graphic].anim_delay_fixed + - SimpleRND(graphic_info[special_graphic].anim_delay_random); + GetSimpleRandom(graphic_info[special_graphic].anim_delay_random); player->post_delay_counter = graphic_info[special_graphic].post_delay_fixed + - SimpleRND(graphic_info[special_graphic].post_delay_random); + GetSimpleRandom(graphic_info[special_graphic].post_delay_random); player->special_action_bored = special_action; } @@ -12413,14 +12434,55 @@ void RequestQuitGame(boolean ask_if_really_quit) /* ------------------------------------------------------------------------- */ -/* game engine snapshot handling */ +/* random generator functions */ +/* ------------------------------------------------------------------------- */ + +unsigned int InitEngineRandom_RND(long seed) +{ + game.num_random_calls = 0; + +#if 0 + unsigned int rnd_seed = InitEngineRandom(seed); + + printf("::: START RND: %d\n", rnd_seed); + + return rnd_seed; +#else + + return InitEngineRandom(seed); + +#endif + +} + +unsigned int RND(int max) +{ + if (max > 0) + { + game.num_random_calls++; + + return GetEngineRandom(max); + } + + return 0; +} + + +/* ------------------------------------------------------------------------- */ +/* game engine snapshot handling functions */ /* ------------------------------------------------------------------------- */ #define ARGS_ADDRESS_AND_SIZEOF(x) (&(x)), (sizeof(x)) struct EngineSnapshotInfo { + /* runtime values for custom element collect score */ int collect_score[NUM_CUSTOM_ELEMENTS]; + + /* runtime values for group element choice position */ + int choice_pos[NUM_GROUP_ELEMENTS]; + + /* runtime values for belt position animations */ int belt_graphic[4 * NUM_BELT_PARTS]; int belt_anim_mode[4 * NUM_BELT_PARTS]; }; @@ -12459,7 +12521,18 @@ static void SaveEngineSnapshotValues_RND() int i, j; for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - engine_snapshot_rnd.collect_score[i] = element_info[i].collect_score; + { + int element = EL_CUSTOM_START + i; + + engine_snapshot_rnd.collect_score[i] = element_info[element].collect_score; + } + + for (i = 0; i < NUM_GROUP_ELEMENTS; i++) + { + int element = EL_GROUP_START + i; + + engine_snapshot_rnd.choice_pos[i] = element_info[element].group->choice_pos; + } for (i = 0; i < 4; i++) { @@ -12473,14 +12546,30 @@ static void SaveEngineSnapshotValues_RND() engine_snapshot_rnd.belt_anim_mode[i * 4 + j] = anim_mode; } } + +#if 0 + printf("::: SAVE: %d RNDs\n", game.num_random_calls); +#endif } static void LoadEngineSnapshotValues_RND() { + unsigned long num_random_calls = game.num_random_calls; int i, j; for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - element_info[i].collect_score = engine_snapshot_rnd.collect_score[i]; + { + int element = EL_CUSTOM_START + i; + + element_info[element].collect_score = engine_snapshot_rnd.collect_score[i]; + } + + for (i = 0; i < NUM_GROUP_ELEMENTS; i++) + { + int element = EL_GROUP_START + i; + + element_info[element].group->choice_pos = engine_snapshot_rnd.choice_pos[i]; + } for (i = 0; i < 4; i++) { @@ -12492,6 +12581,26 @@ static void LoadEngineSnapshotValues_RND() graphic_info[graphic].anim_mode = anim_mode; } } + +#if 0 + printf("::: LOADING ... : %d RNDs\n", num_random_calls); +#endif + + InitRND(tape.random_seed); + for (i = 0; i < num_random_calls; i++) + RND(1); + + if (game.num_random_calls != num_random_calls) + { + Error(ERR_RETURN, "number of random calls out of sync"); + Error(ERR_RETURN, "number of random calls should be %d", num_random_calls); + Error(ERR_RETURN, "number of random calls is %d", game.num_random_calls); + Error(ERR_EXIT, "this should not happen -- please debug"); + } + +#if 0 + printf("::: LOADED: %d RNDs\n", num_random_calls); +#endif } static void SaveEngineSnapshotBuffer(void *buffer, int size) diff --git a/src/game.h b/src/game.h index a18b6247..45323679 100644 --- a/src/game.h +++ b/src/game.h @@ -86,6 +86,9 @@ struct GameInfo int centered_player_nr; int centered_player_nr_next; boolean set_centered_player; + + /* values for random number generator initialization after snapshot */ + unsigned long num_random_calls; }; struct PlayerInfo @@ -239,6 +242,9 @@ void RaiseScore(int); void RaiseScoreElement(int); void RequestQuitGame(boolean); +unsigned int InitEngineRandom_RND(long); +unsigned int RND(int); + void FreeEngineSnapshot(); void LoadEngineSnapshot(); void SaveEngineSnapshot(); diff --git a/src/game_em/export.h b/src/game_em/export.h index 495aa918..20987253 100644 --- a/src/game_em/export.h +++ b/src/game_em/export.h @@ -701,6 +701,10 @@ struct EngineSnapshotInfo_EM int screen_x; int screen_y; int frame; + short **Boom; + short **Cave; + short **Next; + short **Draw; }; @@ -720,7 +724,7 @@ extern void em_close_all(); extern void InitGameEngine_EM(); extern void GameActions_EM(byte *, boolean); -extern unsigned int InitEngineRND_EM(long); +extern unsigned int InitEngineRandom_EM(long); extern void setLevelInfoToDefaults_EM(); extern boolean LoadNativeLevel_EM(char *); diff --git a/src/game_em/init.c b/src/game_em/init.c index a756d24a..b5a0e033 100644 --- a/src/game_em/init.c +++ b/src/game_em/init.c @@ -369,11 +369,11 @@ void sound_play(void) memset(play, 0, sizeof(play)); } -unsigned int InitEngineRND_EM(long seed) +unsigned int InitEngineRandom_EM(long seed) { if (seed == NEW_RANDOMIZE) { - int simple_rnd = SimpleRND(1000); + int simple_rnd = GetSimpleRandom(1000); int i; for (i = 0; i < simple_rnd || RandomEM == NEW_RANDOMIZE; i++) diff --git a/src/game_em/input.c b/src/game_em/input.c index 68ba21f0..cc703ba9 100644 --- a/src/game_em/input.c +++ b/src/game_em/input.c @@ -167,12 +167,19 @@ void SaveEngineSnapshotValues_EM() { int i, j, k; - engine_snapshot_em.RandomEM = RandomEM; engine_snapshot_em.game_em = game_em; engine_snapshot_em.lev = lev; + + engine_snapshot_em.RandomEM = RandomEM; + engine_snapshot_em.frame = frame; + engine_snapshot_em.screen_x = screen_x; engine_snapshot_em.screen_y = screen_y; - engine_snapshot_em.frame = frame; + + engine_snapshot_em.Boom = Boom; + engine_snapshot_em.Cave = Cave; + engine_snapshot_em.Next = Next; + engine_snapshot_em.Draw = Draw; for (i = 0; i < 4; i++) engine_snapshot_em.ply[i] = ply[i]; @@ -181,18 +188,25 @@ void SaveEngineSnapshotValues_EM() for (j = 0; j < HEIGHT; j++) for (k = 0; k < WIDTH; k++) engine_snapshot_em.Array[i][j][k] = Array[i][j][k]; - } void LoadEngineSnapshotValues_EM() { int i, j, k; - RandomEM = engine_snapshot_em.RandomEM; game_em = engine_snapshot_em.game_em; + lev = engine_snapshot_em.lev; + + RandomEM = engine_snapshot_em.RandomEM; + frame = engine_snapshot_em.frame; + screen_x = engine_snapshot_em.screen_x; screen_y = engine_snapshot_em.screen_y; - frame = engine_snapshot_em.frame; + + Boom = engine_snapshot_em.Boom; + Cave = engine_snapshot_em.Cave; + Next = engine_snapshot_em.Next; + Draw = engine_snapshot_em.Draw; for (i = 0; i < 4; i++) ply[i] = engine_snapshot_em.ply[i]; diff --git a/src/init.c b/src/init.c index f5581896..eb6b0374 100644 --- a/src/init.c +++ b/src/init.c @@ -4762,7 +4762,7 @@ void OpenAll() InitCounter(); InitRND(NEW_RANDOMIZE); - InitSimpleRND(NEW_RANDOMIZE); + InitSimpleRandom(NEW_RANDOMIZE); InitJoysticks(); diff --git a/src/libgame/misc.c b/src/libgame/misc.c index ae54541f..916ce2bd 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -328,8 +328,17 @@ void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay) /* random generator functions */ /* ------------------------------------------------------------------------- */ +#if 0 +static int foo = -1; +#endif + unsigned int init_random_number(int nr, long seed) { +#if 0 + if (nr == 0) + foo = 0; +#endif + if (seed == NEW_RANDOMIZE) { #if defined(TARGET_SDL) @@ -349,7 +358,26 @@ unsigned int init_random_number(int nr, long seed) unsigned int get_random_number(int nr, int max) { +#if 0 + if (max > 0) + { + long int rnd_raw = random_linux_libc(nr); + unsigned int rnd = rnd_raw % max; + + if (nr == 0) + { + printf("::: %d: %d [%d MOD %d]\n", foo++, rnd, rnd_raw, max); + } + + return rnd; + } + else + { + return 0; + } +#else return (max > 0 ? random_linux_libc(nr) % max : 0); +#endif } diff --git a/src/libgame/misc.h b/src/libgame/misc.h index 1bafb463..009350c0 100644 --- a/src/libgame/misc.h +++ b/src/libgame/misc.h @@ -27,10 +27,13 @@ /* values for InitRND() */ #define NEW_RANDOMIZE -1 -#define InitEngineRND(seed) init_random_number(0, seed) -#define InitSimpleRND(seed) init_random_number(1, seed) -#define RND(max) get_random_number(0, max) -#define SimpleRND(max) get_random_number(1, max) +#define RANDOM_ENGINE 0 +#define RANDOM_SIMPLE 1 + +#define InitEngineRandom(seed) init_random_number(RANDOM_ENGINE, seed) +#define InitSimpleRandom(seed) init_random_number(RANDOM_SIMPLE, seed) +#define GetEngineRandom(max) get_random_number(RANDOM_ENGINE, max) +#define GetSimpleRandom(max) get_random_number(RANDOM_SIMPLE, max) /* values for Error() */ #define ERR_RETURN 0 diff --git a/src/libgame/toons.c b/src/libgame/toons.c index 0b7ca552..c5f1ff39 100644 --- a/src/libgame/toons.c +++ b/src/libgame/toons.c @@ -65,7 +65,7 @@ int getAnimationFrame(int num_frames, int delay, int mode, int start_frame, /* note: expect different frames for the same delay cycle! */ if (gfx.anim_random_frame < 0) - frame = SimpleRND(num_frames); + frame = GetSimpleRandom(num_frames); else frame = gfx.anim_random_frame % num_frames; } @@ -182,11 +182,11 @@ boolean AnimateToon(int toon_nr, boolean restart) else if (strEqual(anim->position, "bottom")) pos_y = pos_bottom; else if (strEqual(anim->position, "upper")) - pos_y = SimpleRND(pos_bottom / 2); + pos_y = GetSimpleRandom(pos_bottom / 2); else if (strEqual(anim->position, "lower")) - pos_y = pos_bottom / 2 + SimpleRND(pos_bottom / 2); + pos_y = pos_bottom / 2 + GetSimpleRandom(pos_bottom / 2); else - pos_y = SimpleRND(pos_bottom); + pos_y = GetSimpleRandom(pos_bottom); if (direction == MV_RIGHT) { @@ -210,7 +210,7 @@ boolean AnimateToon(int toon_nr, boolean restart) else if (strEqual(anim->position, "right")) pos_x = pos_right; else - pos_x = SimpleRND(pos_right); + pos_x = GetSimpleRandom(pos_right); if (direction == MV_DOWN) { @@ -354,7 +354,7 @@ void HandleAnimation(int mode) if (reset_delay) { animstart_delay = Counter(); - animstart_delay_value = SimpleRND(3000); + animstart_delay_value = GetSimpleRandom(3000); reset_delay = FALSE; } @@ -363,7 +363,7 @@ void HandleAnimation(int mode) if (!DelayReached(&animstart_delay, animstart_delay_value)) return; - toon_nr = SimpleRND(screen_info.num_toons); + toon_nr = GetSimpleRandom(screen_info.num_toons); } anim_restart = reset_delay = AnimateToon(toon_nr, anim_restart); diff --git a/src/main.h b/src/main.h index f2b28442..a88e12b8 100644 --- a/src/main.h +++ b/src/main.h @@ -2397,8 +2397,6 @@ extern int ExitX, ExitY; extern int AllPlayersGone; extern int TimeFrames, TimePlayed, TimeLeft, TapeTime; -extern boolean SiebAktiv; -extern int SiebCount; extern boolean network_player_action_received; diff --git a/src/tape.c b/src/tape.c index 90435c48..a7bd35ee 100644 --- a/src/tape.c +++ b/src/tape.c @@ -677,6 +677,9 @@ void TapeTogglePause(boolean toggle_manual) tape.quick_resume = FALSE; TapeAppendRecording(); + + if (!CheckEngineSnapshot()) + SaveEngineSnapshot(); } } } @@ -945,7 +948,7 @@ void TapeQuickLoad() if (game_status != GAME_MODE_PLAYING && game_status != GAME_MODE_MAIN) return; - if (CheckEngineSnapshot()) + if (1 && CheckEngineSnapshot()) { TapeStartGamePlaying(); diff --git a/src/tools.c b/src/tools.c index 298a98bf..23a25510 100644 --- a/src/tools.c +++ b/src/tools.c @@ -2226,6 +2226,10 @@ void WaitForEventToContinue() button_status = MB_RELEASED; +#if 1 + ClearEventQueue(); +#endif + while (still_wait) { if (PendingEvent()) @@ -5306,9 +5310,9 @@ int getGameFrameDelay_EM(int native_em_game_frame_delay) unsigned int InitRND(long seed) { if (level.game_engine_type == GAME_ENGINE_TYPE_EM) - return InitEngineRND_EM(seed); + return InitEngineRandom_EM(seed); else - return InitEngineRND(seed); + return InitEngineRandom_RND(seed); } void InitGraphicInfo_EM(void) -- 2.34.1