+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
-#define COMPILE_DATE_STRING "[2006-08-24 00:46]"
+#define COMPILE_DATE_STRING "[2006-08-28 22:47]"
break;
case EVENT_KEYRELEASE:
+#if 1
+ ClearPlayerAction();
+#else
key_joystick_mapping = 0;
+#endif
break;
default:
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();
if (tape.playing || keyboard)
newbutton = ((joy & JOY_BUTTON) != 0);
+#if 1
+ if (local_player->LevelSolved_GameEnd && newbutton)
+#else
if (AllPlayersGone && newbutton)
+#endif
{
GameEnd();
#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))
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;
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);
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);
}
if (local_player->LevelSolved_SaveTape)
{
+#if 0
TapeStop();
+#endif
SaveTape(tape.level_nr); /* ask to save tape */
}
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 */
{
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);
}
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;
}
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;
}
/* ------------------------------------------------------------------------- */
-/* 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];
};
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++)
{
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++)
{
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)
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
void RaiseScoreElement(int);
void RequestQuitGame(boolean);
+unsigned int InitEngineRandom_RND(long);
+unsigned int RND(int);
+
void FreeEngineSnapshot();
void LoadEngineSnapshot();
void SaveEngineSnapshot();
int screen_x;
int screen_y;
int frame;
+ short **Boom;
+ short **Cave;
+ short **Next;
+ short **Draw;
};
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 *);
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++)
{
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];
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];
InitCounter();
InitRND(NEW_RANDOMIZE);
- InitSimpleRND(NEW_RANDOMIZE);
+ InitSimpleRandom(NEW_RANDOMIZE);
InitJoysticks();
/* 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)
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
}
/* 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
/* 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;
}
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)
{
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)
{
if (reset_delay)
{
animstart_delay = Counter();
- animstart_delay_value = SimpleRND(3000);
+ animstart_delay_value = GetSimpleRandom(3000);
reset_delay = FALSE;
}
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);
extern int AllPlayersGone;
extern int TimeFrames, TimePlayed, TimeLeft, TapeTime;
-extern boolean SiebAktiv;
-extern int SiebCount;
extern boolean network_player_action_received;
tape.quick_resume = FALSE;
TapeAppendRecording();
+
+ if (!CheckEngineSnapshot())
+ SaveEngineSnapshot();
}
}
}
if (game_status != GAME_MODE_PLAYING && game_status != GAME_MODE_MAIN)
return;
- if (CheckEngineSnapshot())
+ if (1 && CheckEngineSnapshot())
{
TapeStartGamePlaying();
button_status = MB_RELEASED;
+#if 1
+ ClearEventQueue();
+#endif
+
while (still_wait)
{
if (PendingEvent())
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)