game.scroll_delay_value =
MIN(MAX(MIN_SCROLL_DELAY, game.scroll_delay_value), MAX_SCROLL_DELAY);
- FreeEngineSnapshotList();
+ /* ---------- initialize game engine snapshots ---------------------------- */
+ for (i = 0; i < MAX_PLAYERS; i++)
+ game.snapshot.last_action[i] = 0;
+ game.snapshot.changed_action = FALSE;
+ game.snapshot.mode =
+ (strEqual(setup.engine_snapshot_mode, STR_SNAPSHOT_MODE_EVERY_STEP) ?
+ SNAPSHOT_MODE_EVERY_STEP :
+ strEqual(setup.engine_snapshot_mode, STR_SNAPSHOT_MODE_EVERY_MOVE) ?
+ SNAPSHOT_MODE_EVERY_MOVE : SNAPSHOT_MODE_OFF);
}
int get_num_special_action(int element, int action_first, int action_last)
game.restart_level = FALSE;
- SaveEngineSnapshotToList();
+ SaveEngineSnapshotToListInitial();
}
void UpdateEngineValues(int actual_scroll_x, int actual_scroll_y)
(player->is_snapping && !player_was_snapping) ||
(player->is_dropping && !player_was_dropping))
{
- SaveEngineSnapshotToList();
+ if (!SaveEngineSnapshotToList())
+ return;
player_was_moving = FALSE;
player_was_snapping = TRUE;
byte tape_action[MAX_PLAYERS];
int i;
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ struct PlayerInfo *player = &stored_player[i];
+
+ // allow engine snapshot if movement attempt was stopped
+ if ((game.snapshot.last_action[i] & KEY_MOTION) != 0 &&
+ (player->action & KEY_MOTION) == 0)
+ game.snapshot.changed_action = TRUE;
+
+ // allow engine snapshot in case of snapping/dropping attempt
+ if ((game.snapshot.last_action[i] & KEY_BUTTON) == 0 &&
+ (player->action & KEY_BUTTON) != 0)
+ game.snapshot.changed_action = TRUE;
+
+ game.snapshot.last_action[i] = player->action;
+ }
+
/* detect endless loops, caused by custom element programming */
if (recursion_loop_detected && recursion_loop_depth == 0)
{
{
ListNode *buffers = NULL;
- /* do not save snapshots from editor */
- if (level_editor_test_game)
- return NULL;
-
/* copy some special values to a structure better suited for the snapshot */
if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(scroll_x));
SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(scroll_y));
- /* save level identification information */
-
- setString(&snapshot_level_identifier, leveldir_current->identifier);
- snapshot_level_nr = level_nr;
-
#if 0
ListNode *node = engine_snapshot_list_rnd;
int num_bytes = 0;
/* finally save all snapshot buffers to single snapshot */
SaveSnapshotSingle(buffers);
+
+ /* save level identification information */
+ setString(&snapshot_level_identifier, leveldir_current->identifier);
+ snapshot_level_nr = level_nr;
}
-void SaveEngineSnapshotToList()
+static boolean SaveEngineSnapshotToListExt(boolean initial_snapshot)
{
+ boolean save_snapshot =
+ (initial_snapshot ||
+ (game.snapshot.mode == SNAPSHOT_MODE_EVERY_STEP) ||
+ (game.snapshot.mode == SNAPSHOT_MODE_EVERY_MOVE &&
+ game.snapshot.changed_action));
+
+ game.snapshot.changed_action = FALSE;
+
+ if (game.snapshot.mode == SNAPSHOT_MODE_OFF ||
+ tape.quick_resume ||
+ !save_snapshot)
+ return FALSE;
+
ListNode *buffers = SaveEngineSnapshotBuffers();
/* finally save all snapshot buffers to snapshot list */
SaveSnapshotToList(buffers);
+
+ return TRUE;
+}
+
+boolean SaveEngineSnapshotToList()
+{
+ return SaveEngineSnapshotToListExt(FALSE);
+}
+
+void SaveEngineSnapshotToListInitial()
+{
+ FreeEngineSnapshotList();
+
+ SaveEngineSnapshotToListExt(TRUE);
}
void LoadEngineSnapshotValues()
LoadEngineSnapshotValues();
}
-boolean CheckEngineSnapshot()
+boolean CheckEngineSnapshotSingle()
{
return (strEqual(snapshot_level_identifier, leveldir_current->identifier) &&
snapshot_level_nr == level_nr);
}
+boolean CheckEngineSnapshotList()
+{
+ return CheckSnapshotList();
+}
+
/* ---------- new game button stuff ---------------------------------------- */
FreeGadget(game_gadget[i]);
}
-void MapStopPlayButtons()
+static void MapGameButtonsAtSamePosition(int id)
{
- UnmapGadget(game_gadget[GAME_CTRL_ID_UNDO]);
- UnmapGadget(game_gadget[GAME_CTRL_ID_REDO]);
+ int i;
- MapGadget(game_gadget[GAME_CTRL_ID_STOP]);
- MapGadget(game_gadget[GAME_CTRL_ID_PLAY]);
+ for (i = 0; i < NUM_GAME_BUTTONS; i++)
+ if (i != id &&
+ gamebutton_info[i].pos->x == gamebutton_info[id].pos->x &&
+ gamebutton_info[i].pos->y == gamebutton_info[id].pos->y)
+ MapGadget(game_gadget[i]);
+}
+
+static void UnmapGameButtonsAtSamePosition(int id)
+{
+ int i;
+
+ for (i = 0; i < NUM_GAME_BUTTONS; i++)
+ if (i != id &&
+ gamebutton_info[i].pos->x == gamebutton_info[id].pos->x &&
+ gamebutton_info[i].pos->y == gamebutton_info[id].pos->y)
+ UnmapGadget(game_gadget[i]);
}
void MapUndoRedoButtons()
{
- UnmapGadget(game_gadget[GAME_CTRL_ID_STOP]);
- UnmapGadget(game_gadget[GAME_CTRL_ID_PLAY]);
+ UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_UNDO);
+ UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_REDO);
+ UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_PLAY);
MapGadget(game_gadget[GAME_CTRL_ID_UNDO]);
MapGadget(game_gadget[GAME_CTRL_ID_REDO]);
+ MapGadget(game_gadget[GAME_CTRL_ID_PLAY]);
+}
+
+void UnmapUndoRedoButtons()
+{
+ UnmapGadget(game_gadget[GAME_CTRL_ID_UNDO]);
+ UnmapGadget(game_gadget[GAME_CTRL_ID_REDO]);
+ UnmapGadget(game_gadget[GAME_CTRL_ID_PLAY]);
+
+ MapGameButtonsAtSamePosition(GAME_CTRL_ID_UNDO);
+ MapGameButtonsAtSamePosition(GAME_CTRL_ID_REDO);
+ MapGameButtonsAtSamePosition(GAME_CTRL_ID_PLAY);
}
void MapGameButtons()
for (i = 0; i < NUM_GAME_BUTTONS; i++)
if (i != GAME_CTRL_ID_UNDO &&
- i != GAME_CTRL_ID_REDO)
+ i != GAME_CTRL_ID_REDO &&
+ i != GAME_CTRL_ID_PLAY)
MapGadget(game_gadget[i]);
}
RedrawPlayfield();
UpdateAndDisplayGameControlValues();
+ DrawCompleteVideoDisplay();
DrawVideoDisplay(VIDEO_STATE_TIME_ON, TapeTime);
DrawVideoDisplay(VIDEO_STATE_FRAME_ON, FrameCounter);
+ DrawVideoDisplay((tape.single_step ? VIDEO_STATE_1STEP_ON :
+ VIDEO_STATE_1STEP_OFF), 0);
BackToFront();
}
void GameUndo(int steps)
{
- if (!CheckEngineSnapshot())
+ if (!CheckEngineSnapshotList())
return;
LoadEngineSnapshot_Undo(steps);
void GameRedo(int steps)
{
- if (!CheckEngineSnapshot())
+ if (!CheckEngineSnapshotList())
return;
LoadEngineSnapshot_Redo(steps);
SendToServer_ContinuePlaying();
else
#endif
- {
- tape.pausing = FALSE;
- DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF, 0);
- }
+ TapeTogglePause(TAPE_TOGGLE_MANUAL);
}
break;