{ "game.button.gfx.play.width", "30" },
{ "game.button.gfx.play.height", "30" },
{ "game.button.gfx.play.pressed_xoffset", "-100" },
+
+ { "game.button.gfx.undo", "RocksDoor.png" },
+ { "game.button.gfx.undo.x", "405" },
+ { "game.button.gfx.undo.y", "215" },
+ { "game.button.gfx.undo.width", "30" },
+ { "game.button.gfx.undo.height", "30" },
+ { "game.button.gfx.undo.pressed_yoffset", "30" },
+ { "game.button.gfx.redo", "RocksDoor.png" },
+ { "game.button.gfx.redo.x", "465" },
+ { "game.button.gfx.redo.y", "215" },
+ { "game.button.gfx.redo.width", "30" },
+ { "game.button.gfx.redo.height", "30" },
+ { "game.button.gfx.redo.pressed_yoffset", "30" },
+
+ { "game.button.gfx.save", UNDEFINED_FILENAME },
+ { "game.button.gfx.load", UNDEFINED_FILENAME },
+
{ "game.button.gfx.sound_music", "RocksDoor.png" },
{ "game.button.gfx.sound_music.x", "305" },
{ "game.button.gfx.sound_music.y", "245" },
{ "game.button.gfx.sound_simple.pressed_xoffset", "-100" },
{ "game.button.gfx.sound_simple.active_yoffset", "-30" },
- { "game.button.gfx.save", UNDEFINED_FILENAME },
- { "game.button.gfx.load", UNDEFINED_FILENAME },
-
{ "tape.button.gfx.eject", "RocksDoor.png" },
{ "tape.button.gfx.eject.x", "305" },
{ "tape.button.gfx.eject.y", "357" },
{ "game.button.pause.y", "215" },
{ "game.button.play.x", "65" },
{ "game.button.play.y", "215" },
+ { "game.button.undo.x", "5" },
+ { "game.button.undo.y", "215" },
+ { "game.button.redo.x", "65" },
+ { "game.button.redo.y", "215" },
+ { "game.button.save.x", "-1" },
+ { "game.button.save.y", "-1" },
+ { "game.button.load.x", "-1" },
+ { "game.button.load.y", "-1" },
{ "game.button.sound_music.x", "5" },
{ "game.button.sound_music.y", "245" },
{ "game.button.sound_loops.x", "35" },
{ "game.button.sound_loops.y", "245" },
{ "game.button.sound_simple.x", "65" },
{ "game.button.sound_simple.y", "245" },
- { "game.button.save.x", "-1" },
- { "game.button.save.y", "-1" },
- { "game.button.load.x", "-1" },
- { "game.button.load.y", "-1" },
{ "tape.button.eject.x", "5" },
{ "tape.button.eject.y", "77" },
extern void PlayLevelSound_EM(int, int, int, int);
extern void InitGraphicInfo_EM(void);
-extern void CheckSingleStepMode_EM(byte action[], int, boolean, boolean);
+extern void CheckSingleStepMode_EM(byte action[], int,
+ boolean, boolean, boolean);
void SetGfxAnimation_EM(struct GraphicInfo_EM *, int, int, int, int);
void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *, int, int, int, int);
void HandleButton(int mx, int my, int button, int button_nr)
{
static int old_mx = 0, old_my = 0;
+ boolean button_hold = FALSE;
if (button < 0)
{
mx = old_mx;
my = old_my;
button = -button;
+ button_hold = TRUE;
}
else
{
}
#if defined(PLATFORM_ANDROID)
+ // !!! for now, do not handle gadgets when playing -- maybe fix this !!!
if (game_status != GAME_MODE_PLAYING &&
HandleGadgets(mx, my, button))
{
}
#endif
+ if (button_hold && game_status == GAME_MODE_PLAYING && tape.pausing)
+ return;
+
/* do not use scroll wheel button events for anything other than gadgets */
if (IS_WHEEL_BUTTON(button_nr))
return;
void HandleNoEvent()
{
- if (button_status && game_status != GAME_MODE_PLAYING)
+ // if (button_status && game_status != GAME_MODE_PLAYING)
+ if (button_status && (game_status != GAME_MODE_PLAYING || tape.pausing))
{
HandleButton(0, 0, -button_status, button_status);
}
#include "init.h"
#include "tools.h"
#include "screens.h"
+#include "events.h"
#include "files.h"
#include "tape.h"
#include "network.h"
#define GAME_CTRL_ID_STOP 0
#define GAME_CTRL_ID_PAUSE 1
#define GAME_CTRL_ID_PLAY 2
-#define SOUND_CTRL_ID_MUSIC 3
-#define SOUND_CTRL_ID_LOOPS 4
-#define SOUND_CTRL_ID_SIMPLE 5
-#define GAME_CTRL_ID_SAVE 6
-#define GAME_CTRL_ID_LOAD 7
+#define GAME_CTRL_ID_UNDO 3
+#define GAME_CTRL_ID_REDO 4
+#define GAME_CTRL_ID_SAVE 5
+#define GAME_CTRL_ID_LOAD 6
+#define SOUND_CTRL_ID_MUSIC 7
+#define SOUND_CTRL_ID_LOOPS 8
+#define SOUND_CTRL_ID_SIMPLE 9
-#define NUM_GAME_BUTTONS 8
+#define NUM_GAME_BUTTONS 10
/* forward declaration for internal use */
setup.scroll_delay ? setup.scroll_delay_value : 0);
game.scroll_delay_value =
MIN(MAX(MIN_SCROLL_DELAY, game.scroll_delay_value), MAX_SCROLL_DELAY);
+
+ FreeEngineSnapshotList();
}
int get_num_special_action(int element, int action_first, int action_last)
}
game.restart_level = FALSE;
+
+ SaveEngineSnapshotToList();
}
void UpdateEngineValues(int actual_scroll_x, int actual_scroll_y)
}
}
+static void CheckSaveEngineSnapshot(struct PlayerInfo *player)
+{
+ static boolean player_was_moving = FALSE;
+ static boolean player_was_snapping = FALSE;
+ static boolean player_was_dropping = FALSE;
+
+ if (!tape.recording)
+ return;
+
+ if ((!player->is_moving && player_was_moving) ||
+ (player->MovPos == 0 && player_was_moving) ||
+ (player->is_snapping && !player_was_snapping) ||
+ (player->is_dropping && !player_was_dropping))
+ {
+ SaveEngineSnapshotToList();
+
+ player_was_moving = FALSE;
+ player_was_snapping = TRUE;
+ player_was_dropping = TRUE;
+ }
+ else
+ {
+ if (player->is_moving)
+ player_was_moving = TRUE;
+
+ if (!player->is_snapping)
+ player_was_snapping = FALSE;
+
+ if (!player->is_dropping)
+ player_was_dropping = FALSE;
+ }
+}
+
static void CheckSingleStepMode(struct PlayerInfo *player)
{
if (tape.single_step && tape.recording && !tape.pausing)
SnapField(player, 0, 0); /* stop snapping */
}
}
+
+ CheckSaveEngineSnapshot(player);
}
static byte PlayerActions(struct PlayerInfo *player, byte player_action)
if (tape.single_step && tape.recording && !tape.pausing &&
!player->programmed_action)
TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+
+ if (!player->programmed_action)
+ CheckSaveEngineSnapshot(player);
}
}
}
}
-void FreeEngineSnapshot()
+void FreeEngineSnapshotSingle()
{
- FreeEngineSnapshotBuffers();
+ FreeSnapshotSingle();
setString(&snapshot_level_identifier, NULL);
snapshot_level_nr = -1;
}
-void SaveEngineSnapshot()
+void FreeEngineSnapshotList()
{
+ FreeSnapshotList();
+}
+
+ListNode *SaveEngineSnapshotBuffers()
+{
+ ListNode *buffers = NULL;
+
/* do not save snapshots from editor */
if (level_editor_test_game)
- return;
-
- /* free previous snapshot buffers, if needed */
- FreeEngineSnapshotBuffers();
+ return NULL;
/* copy some special values to a structure better suited for the snapshot */
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
SaveEngineSnapshotValues_EM();
if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
- SaveEngineSnapshotValues_SP();
+ SaveEngineSnapshotValues_SP(&buffers);
/* save values stored in special snapshot structure */
if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(engine_snapshot_rnd));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(engine_snapshot_rnd));
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(engine_snapshot_em));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(engine_snapshot_em));
if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(engine_snapshot_sp));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(engine_snapshot_sp));
/* save further RND engine values */
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(stored_player));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(game));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(tape));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ZX));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ZY));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ExitX));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ExitY));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(FrameCounter));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(TimeFrames));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(TimePlayed));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(TimeLeft));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(TapeTime));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScreenMovDir));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScreenMovPos));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScreenGfxPos));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScrollStepSize));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(AllPlayersGone));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(AmoebaCnt));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(AmoebaCnt2));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(Feld));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MovPos));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MovDir));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MovDelay));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ChangeDelay));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ChangePage));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(CustomValue));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(Store));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(Store2));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(StorePlayer));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(Back));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(AmoebaNr));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(WasJustMoving));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(WasJustFalling));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(CheckCollision));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(CheckImpact));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(Stop));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(Pushed));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ChangeCount));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ChangeEvent));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ExplodePhase));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ExplodeDelay));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ExplodeField));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(RunnerVisit));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(PlayerVisit));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(GfxFrame));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(GfxRandom));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(GfxElement));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(GfxAction));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(GfxDir));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(scroll_x));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(scroll_y));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(stored_player));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(game));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(tape));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ZX));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ZY));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ExitX));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ExitY));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(FrameCounter));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(TimeFrames));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(TimePlayed));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(TimeLeft));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(TapeTime));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ScreenMovDir));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ScreenMovPos));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ScreenGfxPos));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ScrollStepSize));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(AllPlayersGone));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(AmoebaCnt));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(AmoebaCnt2));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(Feld));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(MovPos));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(MovDir));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(MovDelay));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ChangeDelay));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ChangePage));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(CustomValue));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(Store));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(Store2));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(StorePlayer));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(Back));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(AmoebaNr));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(WasJustMoving));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(WasJustFalling));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(CheckCollision));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(CheckImpact));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(Stop));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(Pushed));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ChangeCount));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ChangeEvent));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ExplodePhase));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ExplodeDelay));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ExplodeField));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(RunnerVisit));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(PlayerVisit));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(GfxFrame));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(GfxRandom));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(GfxElement));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(GfxAction));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(GfxDir));
+
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(scroll_x));
+ SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(scroll_y));
/* save level identification information */
printf("::: size of engine snapshot: %d bytes\n", num_bytes);
#endif
+
+ return buffers;
+}
+
+void SaveEngineSnapshotSingle()
+{
+ ListNode *buffers = SaveEngineSnapshotBuffers();
+
+ /* finally save all snapshot buffers to single snapshot */
+ SaveSnapshotSingle(buffers);
}
-void LoadEngineSnapshot()
+void SaveEngineSnapshotToList()
{
- /* restore generically stored snapshot buffers */
+ ListNode *buffers = SaveEngineSnapshotBuffers();
- LoadEngineSnapshotBuffers();
+ /* finally save all snapshot buffers to snapshot list */
+ SaveSnapshotToList(buffers);
+}
+void LoadEngineSnapshotValues()
+{
/* restore special values from snapshot structure */
if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
LoadEngineSnapshotValues_SP();
}
+void LoadEngineSnapshotSingle()
+{
+ LoadSnapshotSingle();
+
+ LoadEngineSnapshotValues();
+}
+
+void LoadEngineSnapshot_Undo()
+{
+ LoadSnapshotFromList_Older();
+
+ LoadEngineSnapshotValues();
+}
+
+void LoadEngineSnapshot_Redo()
+{
+ LoadSnapshotFromList_Newer();
+
+ LoadEngineSnapshotValues();
+}
+
boolean CheckEngineSnapshot()
{
return (strEqual(snapshot_level_identifier, leveldir_current->identifier) &&
GAME_CTRL_ID_PLAY, "play game"
},
{
- IMG_GAME_BUTTON_GFX_SOUND_MUSIC, &game.button.sound_music,
- SOUND_CTRL_ID_MUSIC, "background music on/off"
+ IMG_GAME_BUTTON_GFX_UNDO, &game.button.undo,
+ GAME_CTRL_ID_UNDO, "undo step"
},
{
- IMG_GAME_BUTTON_GFX_SOUND_LOOPS, &game.button.sound_loops,
- SOUND_CTRL_ID_LOOPS, "sound loops on/off"
- },
- {
- IMG_GAME_BUTTON_GFX_SOUND_SIMPLE, &game.button.sound_simple,
- SOUND_CTRL_ID_SIMPLE, "normal sounds on/off"
+ IMG_GAME_BUTTON_GFX_REDO, &game.button.redo,
+ GAME_CTRL_ID_REDO, "redo step"
},
{
IMG_GAME_BUTTON_GFX_SAVE, &game.button.save,
{
IMG_GAME_BUTTON_GFX_LOAD, &game.button.load,
GAME_CTRL_ID_LOAD, "load game"
+ },
+ {
+ IMG_GAME_BUTTON_GFX_SOUND_MUSIC, &game.button.sound_music,
+ SOUND_CTRL_ID_MUSIC, "background music on/off"
+ },
+ {
+ IMG_GAME_BUTTON_GFX_SOUND_LOOPS, &game.button.sound_loops,
+ SOUND_CTRL_ID_LOOPS, "sound loops on/off"
+ },
+ {
+ IMG_GAME_BUTTON_GFX_SOUND_SIMPLE, &game.button.sound_simple,
+ SOUND_CTRL_ID_SIMPLE, "normal sounds on/off"
}
};
checked = FALSE;
event_mask = GD_EVENT_RELEASED;
}
+ else if (id == GAME_CTRL_ID_UNDO ||
+ id == GAME_CTRL_ID_REDO)
+ {
+ button_type = GD_TYPE_NORMAL_BUTTON;
+ checked = FALSE;
+ event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
+ }
else
{
button_type = GD_TYPE_CHECK_BUTTON;
FreeGadget(game_gadget[i]);
}
+void MapStopPlayButtons()
+{
+ UnmapGadget(game_gadget[GAME_CTRL_ID_UNDO]);
+ UnmapGadget(game_gadget[GAME_CTRL_ID_REDO]);
+
+ MapGadget(game_gadget[GAME_CTRL_ID_STOP]);
+ MapGadget(game_gadget[GAME_CTRL_ID_PLAY]);
+}
+
+void MapUndoRedoButtons()
+{
+ UnmapGadget(game_gadget[GAME_CTRL_ID_STOP]);
+ UnmapGadget(game_gadget[GAME_CTRL_ID_PLAY]);
+
+ MapGadget(game_gadget[GAME_CTRL_ID_UNDO]);
+ MapGadget(game_gadget[GAME_CTRL_ID_REDO]);
+}
+
void MapGameButtons()
{
int i;
for (i = 0; i < NUM_GAME_BUTTONS; i++)
- MapGadget(game_gadget[i]);
+ if (i != GAME_CTRL_ID_UNDO &&
+ i != GAME_CTRL_ID_REDO)
+ MapGadget(game_gadget[i]);
}
void UnmapGameButtons()
redraw_mask &= ~REDRAW_ALL;
}
+void GameUndoRedoExt()
+{
+ ClearPlayerAction();
+
+ tape.pausing = TRUE;
+
+ RedrawPlayfield();
+ UpdateAndDisplayGameControlValues();
+
+ DrawVideoDisplay(VIDEO_STATE_TIME_ON, TapeTime);
+ DrawVideoDisplay(VIDEO_STATE_FRAME_ON, FrameCounter);
+
+ BackToFront();
+}
+
+void GameUndo()
+{
+ if (!CheckEngineSnapshot())
+ return;
+
+ LoadEngineSnapshot_Undo();
+
+ GameUndoRedoExt();
+}
+
+void GameRedo()
+{
+ if (!CheckEngineSnapshot())
+ return;
+
+ LoadEngineSnapshot_Redo();
+
+ GameUndoRedoExt();
+}
+
static void HandleGameButtonsExt(int id)
{
boolean handle_game_buttons =
}
break;
+ case GAME_CTRL_ID_UNDO:
+ GameUndo();
+ break;
+
+ case GAME_CTRL_ID_REDO:
+ GameRedo();
+ break;
+
+ case GAME_CTRL_ID_SAVE:
+ TapeQuickSave();
+ break;
+
+ case GAME_CTRL_ID_LOAD:
+ TapeQuickLoad();
+ break;
+
case SOUND_CTRL_ID_MUSIC:
if (setup.sound_music)
{
}
break;
- case GAME_CTRL_ID_SAVE:
- TapeQuickSave();
- break;
-
- case GAME_CTRL_ID_LOAD:
- TapeQuickLoad();
- break;
-
default:
break;
}
struct XY pause;
struct XY play;
- struct XY sound_music;
- struct XY sound_loops;
- struct XY sound_simple;
+ struct XY undo;
+ struct XY redo;
struct XY save;
struct XY load;
+
+ struct XY sound_music;
+ struct XY sound_loops;
+ struct XY sound_simple;
};
struct GameInfo
unsigned int InitEngineRandom_RND(int);
unsigned int RND(int);
-void FreeEngineSnapshot();
-void LoadEngineSnapshot();
-void SaveEngineSnapshot();
+void FreeEngineSnapshotSingle();
+void FreeEngineSnapshotList();
+void LoadEngineSnapshotSingle();
+void SaveEngineSnapshotSingle();
+void SaveEngineSnapshotToList();
boolean CheckEngineSnapshot();
void CreateGameButtons();
void FreeGameButtons();
+void MapStopPlayButtons();
+void MapUndoRedoButtons();
void MapGameButtons();
void UnmapGameButtons();
void RedrawGameButtons();
}
game_em.any_player_moving = FALSE;
+ game_em.any_player_snapping = FALSE;
game_em.last_moving_player = 0; /* default: first player */
for (i = 0; i < MAX_PLAYERS; i++)
struct GameInfo_EM
{
boolean any_player_moving;
+ boolean any_player_snapping;
int last_moving_player;
int last_player_direction[MAX_PLAYERS];
};
void GameActions_EM(byte action[MAX_PLAYERS], boolean warp_mode)
{
int i;
- boolean player_is_dropping = FALSE;
+ boolean any_player_dropping = FALSE;
RandomEM = RandomEM * 129 + 1;
ply[i].dynamite &&
ply[i].dynamite_cnt > 0 &&
ply[i].dynamite_cnt < 5)
- player_is_dropping = TRUE;
+ any_player_dropping = TRUE;
CheckSingleStepMode_EM(action, frame, game_em.any_player_moving,
- player_is_dropping);
+ game_em.any_player_snapping, any_player_dropping);
game_animscreen();
int i;
game_em.any_player_moving = FALSE;
+ game_em.any_player_snapping = FALSE;
/* must test for death and actually kill separately */
for (i = 0; i < MAX_PLAYERS; i++)
}
else /* player wants to snap */
{
- player_digfield(ply, dx, dy);
+ game_em.any_player_snapping = player_digfield(ply, dx, dy);
}
}
extern void RedrawPlayfield_SP(boolean);
extern void LoadEngineSnapshotValues_SP();
-extern void SaveEngineSnapshotValues_SP();
+extern void SaveEngineSnapshotValues_SP(ListNode **);
extern int map_key_RND_to_SP(int);
extern int map_key_SP_to_RND(int);
/* Supaplex game engine snapshot handling functions */
/* ------------------------------------------------------------------------- */
-void SaveEngineSnapshotValues_SP()
+void SaveEngineSnapshotValues_SP(ListNode **buffers)
{
int i;
/* store special data into engine snapshot buffers */
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(FieldWidth));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(FieldHeight));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(FieldMax));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(LevelMax));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(TimerVar));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(RandomSeed));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(TerminalMaxCycles));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(mScrollX));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(mScrollY));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(mScrollX_last));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(mScrollY_last));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScreenScrollXPos));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScreenScrollYPos));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(DisplayMinX));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(DisplayMinY));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(DisplayMaxX));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(DisplayMaxY));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(InfotronsNeeded));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(KillMurphyFlag));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MurphyMoveCounter));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MurphyExplodePos));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(SplitMoveFlag));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(RedDiskReleaseMurphyPos));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MurphyPosIndex));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MurphyXPos));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MurphyYPos));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MurphyScreenXPos));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MurphyScreenYPos));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MurphyVarFaceLeft));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(RedDiskCount));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(RedDiskReleaseFlag));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(MovingPictureSequencePhase));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(RedDiskReleasePhase));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScratchGravity));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(GravityFlag));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(SnikSnaksElectronsFrozen));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(YellowDisksExploded));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(YawnSleepCounter));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(LeadOutCounter));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(GfxElementLast));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(GfxGraphicLast));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(GfxGraphic));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(GfxFrame));
-
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScrollMinX));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScrollMinY));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScrollMaxX));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScrollMaxY));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScrollX));
- SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(ScrollY));
-
- SaveEngineSnapshotBuffer(&PlayField16[-game_sp.preceding_buffer_size],
- game_sp.preceding_buffer_size * sizeof(int));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(FieldWidth));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(FieldHeight));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(FieldMax));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(LevelMax));
+
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(TimerVar));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(RandomSeed));
+
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(TerminalMaxCycles));
+
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(mScrollX));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(mScrollY));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(mScrollX_last));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(mScrollY_last));
+
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(ScreenScrollXPos));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(ScreenScrollYPos));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(DisplayMinX));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(DisplayMinY));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(DisplayMaxX));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(DisplayMaxY));
+
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(InfotronsNeeded));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(KillMurphyFlag));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(MurphyMoveCounter));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(MurphyExplodePos));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(SplitMoveFlag));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(RedDiskReleaseMurphyPos));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(MurphyPosIndex));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(MurphyXPos));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(MurphyYPos));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(MurphyScreenXPos));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(MurphyScreenYPos));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(MurphyVarFaceLeft));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(RedDiskCount));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(RedDiskReleaseFlag));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(MovingPictureSequencePhase));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(RedDiskReleasePhase));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(ScratchGravity));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(GravityFlag));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(SnikSnaksElectronsFrozen));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(YellowDisksExploded));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(YawnSleepCounter));
+
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(LeadOutCounter));
+
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(GfxElementLast));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(GfxGraphicLast));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(GfxGraphic));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(GfxFrame));
+
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(ScrollMinX));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(ScrollMinY));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(ScrollMaxX));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(ScrollMaxY));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(ScrollX));
+ SaveSnapshotBuffer(buffers, ARGS_ADDRESS_AND_SIZEOF(ScrollY));
+
+ SaveSnapshotBuffer(buffers, &PlayField16[-game_sp.preceding_buffer_size],
+ game_sp.preceding_buffer_size * sizeof(int));
}
void LoadEngineSnapshotValues_SP()
node_new->key = getStringCopy(key);
node_new->content = content;
node_new->next = *node_first;
+
+ if (*node_first)
+ (*node_first)->prev = node_new;
+
*node_first = node_new;
}
if (strEqual((*node_first)->key, key))
{
checked_free((*node_first)->key);
+
if (destructor_function)
destructor_function((*node_first)->content);
+
+ if ((*node_first)->next)
+ (*node_first)->next->prev = (*node_first)->prev;
+
+ checked_free(*node_first);
+
*node_first = (*node_first)->next;
}
else
#include "snapshot.h"
-static ListNode *engine_snapshot_list = NULL;
+static ListNode *snapshot_single = NULL;
+static ListNode *snapshot_list = NULL;
+static ListNode *snapshot_current = NULL;
-void SaveEngineSnapshotBuffer(void *buffer, int size)
+static int num_snapshots_in_list = 0;
+
+
+#ifdef DEBUG
+#define DEBUG_SNAPSHOTS 0
+#endif
+
+
+// -----------------------------------------------------------------------------
+// functions for handling buffers for a single snapshot
+// -----------------------------------------------------------------------------
+
+void SaveSnapshotBuffer(ListNode **snapshot_buffers, void *buffer, int size)
{
- struct EngineSnapshotNodeInfo *bi =
- checked_calloc(sizeof(struct EngineSnapshotNodeInfo));
+ struct SnapshotNodeInfo *bi =
+ checked_calloc(sizeof(struct SnapshotNodeInfo));
bi->buffer_orig = buffer;
bi->buffer_copy = checked_malloc(size);
memcpy(bi->buffer_copy, buffer, size);
- addNodeToList(&engine_snapshot_list, NULL, bi);
+ addNodeToList(snapshot_buffers, NULL, bi);
}
-static void LoadEngineSnapshotBuffer(struct EngineSnapshotNodeInfo *bi)
+static void LoadSnapshotBuffer(struct SnapshotNodeInfo *bi)
{
memcpy(bi->buffer_orig, bi->buffer_copy, bi->size);
}
-void LoadEngineSnapshotBuffers()
+void LoadSnapshotBuffers(ListNode *snapshot_buffers)
+{
+ while (snapshot_buffers != NULL)
+ {
+ LoadSnapshotBuffer((struct SnapshotNodeInfo *)snapshot_buffers->content);
+
+ snapshot_buffers = snapshot_buffers->next;
+ }
+}
+
+void FreeSnapshotBuffers(ListNode *snapshot_buffers)
+{
+ while (snapshot_buffers != NULL)
+ deleteNodeFromList(&snapshot_buffers, snapshot_buffers->key, checked_free);
+}
+
+// -----------------------------------------------------------------------------
+// functions for handling one of several snapshots
+// -----------------------------------------------------------------------------
+
+static void FreeSnapshotExt(void *snapshot_buffers_ptr)
+{
+ FreeSnapshotBuffers(snapshot_buffers_ptr);
+}
+
+void FreeSnapshotSingle()
+{
+ FreeSnapshotBuffers(snapshot_single);
+
+ snapshot_single = NULL;
+}
+
+void FreeSnapshotList_UpToNode(ListNode *node)
+{
+ while (snapshot_list != node)
+ {
+ deleteNodeFromList(&snapshot_list, snapshot_list->key, FreeSnapshotExt);
+
+ num_snapshots_in_list--;
+ }
+}
+
+void FreeSnapshotList()
+{
+ FreeSnapshotList_UpToNode(NULL);
+
+ snapshot_current = NULL;
+}
+
+void SaveSnapshotSingle(ListNode *snapshot_buffers)
+{
+ if (snapshot_single)
+ FreeSnapshotSingle();
+
+ snapshot_single = snapshot_buffers;
+}
+
+void SaveSnapshotToList(ListNode *snapshot_buffers)
{
- ListNode *node = engine_snapshot_list;
+ if (snapshot_current != snapshot_list)
+ FreeSnapshotList_UpToNode(snapshot_current);
+
+ addNodeToList(&snapshot_list, i_to_a(num_snapshots_in_list),
+ snapshot_buffers);
- while (node != NULL)
+ snapshot_current = snapshot_list;
+
+ num_snapshots_in_list++;
+
+#if DEBUG_SNAPSHOTS
+ printf("::: SaveSnapshotToList() [%s]\n", snapshot_current->key);
+#endif
+}
+
+boolean LoadSnapshotSingle()
+{
+ if (snapshot_single)
{
- LoadEngineSnapshotBuffer((struct EngineSnapshotNodeInfo *)node->content);
+ LoadSnapshotBuffers(snapshot_single);
- node = node->next;
+ return TRUE;
}
+
+ return FALSE;
}
-void FreeEngineSnapshotBuffers()
+boolean LoadSnapshotFromList_Older()
{
- while (engine_snapshot_list != NULL)
- deleteNodeFromList(&engine_snapshot_list, engine_snapshot_list->key,
- checked_free);
+ if (snapshot_current->next)
+ {
+ snapshot_current = snapshot_current->next;
+
+ LoadSnapshotBuffers(snapshot_current->content);
+
+#if DEBUG_SNAPSHOTS
+ printf("::: LoadSnapshotFromList_Older() [%s]\n", snapshot_current->key);
+#endif
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+boolean LoadSnapshotFromList_Newer()
+{
+ if (snapshot_current->prev)
+ {
+ snapshot_current = snapshot_current->prev;
+
+ LoadSnapshotBuffers(snapshot_current->content);
+
+#if DEBUG_SNAPSHOTS
+ printf("::: LoadSnapshotFromList_Newer() [%s]\n", snapshot_current->key);
+#endif
+
+ return TRUE;
+ }
+
+ return FALSE;
}
/* needed for comfortably saving engine snapshot buffers */
#define ARGS_ADDRESS_AND_SIZEOF(x) (&(x)), (sizeof(x))
-struct EngineSnapshotNodeInfo
+struct SnapshotNodeInfo
{
void *buffer_orig;
void *buffer_copy;
};
-void SaveEngineSnapshotBuffer(void *buffer, int size);
-void LoadEngineSnapshotBuffers();
-void FreeEngineSnapshotBuffers();
+void SaveSnapshotBuffer(ListNode **, void *, int);
+void LoadSnapshotBuffers(ListNode *);
+void FreeSnapshotBuffers(ListNode *);
+
+void SaveSnapshotSingle();
+void SaveSnapshotToList();
+boolean LoadSnapshotSingle();
+boolean LoadSnapshotFromList_Older();
+boolean LoadSnapshotFromList_Newer();
+void FreeSnapshotSingle();
+void FreeSnapshotList();
#endif /* SNAPSHOT_H */
{
char *key;
void *content;
+ struct ListNode *prev;
struct ListNode *next;
};
typedef struct ListNode ListNode;
TapeAppendRecording();
if (!CheckEngineSnapshot())
- SaveEngineSnapshot();
+ SaveEngineSnapshotSingle();
}
}
+
+ if (tape.pausing)
+ MapUndoRedoButtons();
+ else
+ MapStopPlayButtons();
}
void TapeStartPlaying()
}
if (SaveTapeChecked(tape.level_nr))
- SaveEngineSnapshot();
+ SaveEngineSnapshotSingle();
}
void TapeQuickLoad()
{
TapeStartGamePlaying();
- LoadEngineSnapshot();
+ LoadEngineSnapshotSingle();
DrawCompleteVideoDisplay();
#endif
}
+void CheckSaveEngineSnapshot_EM(byte action[MAX_PLAYERS], int frame,
+ boolean any_player_moving,
+ boolean any_player_snapping,
+ boolean any_player_dropping)
+{
+ static boolean player_was_waiting = TRUE;
+
+ if (!tape.recording)
+ return;
+
+ if (frame == 0 && !any_player_dropping)
+ {
+ if (!player_was_waiting)
+ {
+ SaveEngineSnapshotToList();
+
+ player_was_waiting = TRUE;
+ }
+ }
+ else if (any_player_moving || any_player_snapping || any_player_dropping)
+ {
+ player_was_waiting = FALSE;
+ }
+}
+
+void CheckSaveEngineSnapshot_SP(boolean murphy_is_waiting,
+ boolean murphy_is_dropping)
+{
+ static boolean player_was_waiting = FALSE;
+
+ if (!tape.recording)
+ return;
+
+ if (murphy_is_waiting)
+ {
+ if (!player_was_waiting)
+ {
+ SaveEngineSnapshotToList();
+
+ player_was_waiting = TRUE;
+ }
+ }
+ else
+ {
+ player_was_waiting = FALSE;
+ }
+}
+
void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
boolean any_player_moving,
- boolean player_is_dropping)
+ boolean any_player_snapping,
+ boolean any_player_dropping)
{
if (tape.single_step && tape.recording && !tape.pausing)
- if (frame == 0 && !player_is_dropping)
+ if (frame == 0 && !any_player_dropping)
TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+
+ CheckSaveEngineSnapshot_EM(action, frame, any_player_moving,
+ any_player_snapping, any_player_dropping);
}
void CheckSingleStepMode_SP(boolean murphy_is_waiting,
if (tape.single_step && tape.recording && !tape.pausing)
if (murphy_is_waiting)
TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+
+ CheckSaveEngineSnapshot_SP(murphy_is_waiting, murphy_is_dropping);
}
void getGraphicSource_SP(struct GraphicInfo_SP *g_sp,
// printf("::: new_tilesize_var != TILESIZE_VAR\n");
// changing tile size invalidates scroll values of engine snapshots
- FreeEngineSnapshot();
+ FreeEngineSnapshotSingle();
// changing tile size requires update of graphic mapping for EM engine
init_em_graphics = TRUE;