+2010-02-19
+ * started integrating snapshot functionality into Supaplex game engine
+
2010-02-16
* fixed bug in native Supaplex engine that broke several demo solutions
* fixed bug with re-initializing already existing elements in function
-#define COMPILE_DATE_STRING "2010-02-18 09:22"
+#define COMPILE_DATE_STRING "2010-02-20 00:28"
}
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
{
- if (game_sp_info.LevelSolved &&
- !game_sp_info.GameOver) /* game won */
+ if (game_sp.LevelSolved &&
+ !game_sp.GameOver) /* game won */
{
PlayerWins(local_player);
- game_sp_info.GameOver = TRUE;
+ game_sp.GameOver = TRUE;
AllPlayersGone = TRUE;
}
- if (game_sp_info.GameOver) /* game lost */
+ if (game_sp.GameOver) /* game lost */
AllPlayersGone = TRUE;
}
}
else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
{
- if (game_sp_info.LevelSolved &&
- !game_sp_info.GameOver) /* game won */
+ if (game_sp.LevelSolved &&
+ !game_sp.GameOver) /* game won */
{
PlayerWins(local_player);
- game_sp_info.GameOver = TRUE;
+ game_sp.GameOver = TRUE;
AllPlayersGone = TRUE;
}
- if (game_sp_info.GameOver) /* game lost */
+ if (game_sp.GameOver) /* game lost */
AllPlayersGone = TRUE;
}
/* game engine snapshot handling functions */
/* ------------------------------------------------------------------------- */
-#define ARGS_ADDRESS_AND_SIZEOF(x) (&(x)), (sizeof(x))
-
struct EngineSnapshotInfo
{
/* runtime values for custom element collect score */
int belt_anim_mode[4 * NUM_BELT_PARTS];
};
-struct EngineSnapshotNodeInfo
-{
- void *buffer_orig;
- void *buffer_copy;
- int size;
-};
-
static struct EngineSnapshotInfo engine_snapshot_rnd;
-static ListNode *engine_snapshot_list = NULL;
static char *snapshot_level_identifier = NULL;
static int snapshot_level_nr = -1;
-void FreeEngineSnapshot()
-{
- while (engine_snapshot_list != NULL)
- deleteNodeFromList(&engine_snapshot_list, engine_snapshot_list->key,
- checked_free);
-
- setString(&snapshot_level_identifier, NULL);
- snapshot_level_nr = -1;
-}
-
static void SaveEngineSnapshotValues_RND()
{
static int belt_base_active_element[4] =
}
}
-static void SaveEngineSnapshotBuffer(void *buffer, int size)
-{
- struct EngineSnapshotNodeInfo *bi =
- checked_calloc(sizeof(struct EngineSnapshotNodeInfo));
-
- bi->buffer_orig = buffer;
- bi->buffer_copy = checked_malloc(size);
- bi->size = size;
-
- memcpy(bi->buffer_copy, buffer, size);
-
- addNodeToList(&engine_snapshot_list, NULL, bi);
-}
-
void SaveEngineSnapshot()
{
- FreeEngineSnapshot(); /* free previous snapshot, if needed */
-
- if (level_editor_test_game) /* do not save snapshots from editor */
+ /* do not save snapshots from editor */
+ if (level_editor_test_game)
return;
+ /* free previous snapshot buffers, if needed */
+ FreeEngineSnapshotBuffers();
+
/* copy some special values to a structure better suited for the snapshot */
SaveEngineSnapshotValues_RND();
SaveEngineSnapshotValues_EM();
+ SaveEngineSnapshotValues_SP();
/* save values stored in special snapshot structure */
SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(engine_snapshot_rnd));
SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(engine_snapshot_em));
+ SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(engine_snapshot_sp));
/* save further RND engine values */
snapshot_level_nr = level_nr;
#if 0
- ListNode *node = engine_snapshot_list;
+ ListNode *node = engine_snapshot_list_rnd;
int num_bytes = 0;
while (node != NULL)
#endif
}
-static void LoadEngineSnapshotBuffer(struct EngineSnapshotNodeInfo *bi)
-{
- memcpy(bi->buffer_orig, bi->buffer_copy, bi->size);
-}
-
void LoadEngineSnapshot()
{
- ListNode *node = engine_snapshot_list;
+ /* restore generically stored snapshot buffers */
- if (engine_snapshot_list == NULL)
- return;
-
- while (node != NULL)
- {
- LoadEngineSnapshotBuffer((struct EngineSnapshotNodeInfo *)node->content);
-
- node = node->next;
- }
+ LoadEngineSnapshotBuffers();
/* restore special values from snapshot structure */
LoadEngineSnapshotValues_RND();
LoadEngineSnapshotValues_EM();
+ LoadEngineSnapshotValues_SP();
}
boolean CheckEngineSnapshot()
int TEST_flag = 0;
+void RestorePlayfield()
+{
+ int x1 = mScrollX / TILEX - 2;
+ int y1 = mScrollY / TILEY - 2;
+ int x2 = mScrollX / TILEX + (SCR_FIELDX - 1) + 2;
+ int y2 = mScrollY / TILEY + (SCR_FIELDY - 1) + 2;
+ int x, y;
+
+ DrawFrameIfNeeded();
+
+ for (y = DisplayMinY; y <= DisplayMaxY; y++)
+ {
+ for (x = DisplayMinX; x <= DisplayMaxX; x++)
+ {
+ if (x >= x1 && x <= x2 && y >= y1 && y <= y2)
+ {
+ DrawFieldNoAnimated(x, y);
+ DrawFieldAnimated(x, y);
+ }
+ }
+ }
+}
static void ScrollPlayfield(int dx, int dy)
{
ScrollPlayfieldIfNeededExt(TRUE);
}
-void UpdatePlayfield()
+void UpdatePlayfield(boolean force_redraw)
{
int x, y;
#if 1
int element = LowByte(PlayField16[GetSI(x, y)]);
int graphic = GfxGraphic[x][y];
int sync_frame = GfxFrame[x][y];
-#if 1
- boolean redraw = FALSE;
-#else
- boolean redraw = TRUE; // !!! TEST ONLY -- ALWAYS REDRAW !!!
+ boolean redraw = force_redraw;
+
+#if 0
+ redraw = TRUE; // !!! TEST ONLY -- ALWAYS REDRAW !!!
#endif
if (graphic < 0)
extern void InitScrollPlayfield();
extern void UpdatePlayfield();
+extern void RestorePlayfield();
extern void DDScrollBuffer_Blt_Ext(Bitmap *);
extern void DDScrollBuffer_Blt();
{
#if 1
if (LeadOutCounter == 0 &&
- !game_sp_info.LevelSolved &&
- !game_sp_info.GameOver)
+ !game_sp.LevelSolved &&
+ !game_sp.GameOver)
#else
if (LeadOutCounter == 0)
#endif
#if 1
/* give Murphy some more time (LeadOutCounter) to reach the exit */
#else
- game_sp_info.GameOver = TRUE;
+ game_sp.GameOver = TRUE;
#endif
#endif
#if 1
#if 0
printf("::: *** %d, %d, %d\n", KillMurphyFlag,
- game_sp_info.LevelSolved, game_sp_info.GameOver);
+ game_sp.LevelSolved, game_sp.GameOver);
#endif
#if 0
if (KillMurphyFlag == 1 &&
- !game_sp_info.LevelSolved &&
- !game_sp_info.GameOver)
+ !game_sp.LevelSolved &&
+ !game_sp.GameOver)
{
#if 1
printf("::: DoGameStuff.c: !!!!!!!!!! GAME OVER !!!!!!!!!!\n");
#endif
- game_sp_info.GameOver = TRUE;
+ game_sp.GameOver = TRUE;
}
#endif
#endif
#if 1
/* if the game is not won when reaching this point, then it is lost */
- if (!game_sp_info.LevelSolved)
- game_sp_info.GameOver = TRUE;
+ if (!game_sp.LevelSolved)
+ game_sp.GameOver = TRUE;
#endif
#if 1
return;
#if 1
- if (!game_sp_info.LevelSolved)
+ if (!game_sp.LevelSolved)
printf("::: Murphy.c: !!!!!!!!!! LEVEL %d SOLVED !!!!!!!!!!\n",LevelNumber);
#endif
#if 1
- game_sp_info.LevelSolved = TRUE;
+ game_sp.LevelSolved = TRUE;
#endif
subSoundFXExit();
#define SP_NUM_LEVELS_PER_PACKAGE 111
-#define SP_PLAYFIELD_WIDTH 60
-#define SP_PLAYFIELD_HEIGHT 24
+#define SP_STD_PLAYFIELD_WIDTH 60
+#define SP_STD_PLAYFIELD_HEIGHT 24
#define SP_LEVEL_NAME_LEN 23
#define SP_MAX_SPECIAL_PORTS 10
#define SP_HEADER_SIZE 96
-#define SP_PLAYFIELD_SIZE (SP_PLAYFIELD_WIDTH * \
- SP_PLAYFIELD_HEIGHT)
-#define SP_LEVEL_SIZE (SP_HEADER_SIZE + SP_PLAYFIELD_SIZE)
+#define SP_STD_PLAYFIELD_SIZE (SP_STD_PLAYFIELD_WIDTH * \
+ SP_STD_PLAYFIELD_HEIGHT)
+#define SP_MAX_PLAYFIELD_SIZE (SP_MAX_PLAYFIELD_WIDTH * \
+ SP_MAX_PLAYFIELD_HEIGHT)
+#define SP_STD_LEVEL_SIZE (SP_HEADER_SIZE + SP_STD_PLAYFIELD_SIZE)
#if 0
#define SP_SCREEN_BUFFER_XSIZE (SCR_FIELDX + 2)
{
boolean LevelSolved;
boolean GameOver;
+
+ /* needed for engine snapshots */
+ int preceding_buffer_size;
};
struct DemoInfo_SP
struct EngineSnapshotInfo_SP
{
struct GameInfo_SP game_sp;
+
+ int PlayField16[SP_MAX_PLAYFIELD_SIZE + SP_HEADER_SIZE];
+ byte PlayField8[SP_MAX_PLAYFIELD_SIZE + SP_HEADER_SIZE];
+ byte DisPlayField[SP_MAX_PLAYFIELD_SIZE + SP_HEADER_SIZE];
+
+ int AnimationPosTable[SP_MAX_PLAYFIELD_SIZE];
+ byte AnimationSubTable[SP_MAX_PLAYFIELD_SIZE];
+ byte TerminalState[SP_MAX_PLAYFIELD_SIZE + SP_HEADER_SIZE];
};
/* ------------------------------------------------------------------------- */
extern struct GlobalInfo_SP global_sp_info;
-extern struct GameInfo_SP game_sp_info;
+extern struct GameInfo_SP game_sp;
extern struct LevelInfo_SP native_sp_level;
extern struct GraphicInfo_SP graphic_info_sp_object[TILE_MAX][8];
extern struct GraphicInfo_SP graphic_info_sp_player[MAX_PLAYERS][SPR_MAX][8];
char *empty_title = "-------- EMPTY --------";
int i, x, y;
- native_sp_level.width = SP_PLAYFIELD_WIDTH;
- native_sp_level.height = SP_PLAYFIELD_HEIGHT;
+ native_sp_level.width = SP_STD_PLAYFIELD_WIDTH;
+ native_sp_level.height = SP_STD_PLAYFIELD_HEIGHT;
for (x = 0; x < native_sp_level.width; x++)
for (y = 0; y < native_sp_level.height; y++)
preceding_buffer_size += 8; /* eight 16-bit integer values */
#endif
+ /* needed for engine snapshots */
+ game_sp.preceding_buffer_size = preceding_buffer_size;
+
LInfo = native_sp_level.header;
FieldWidth = native_sp_level.width;
strSuffixLower(filename, ".mpx"));
boolean demo_available = is_single_level_file;
boolean is_mpx_file = strSuffixLower(filename, ".mpx");
- int file_seek_pos = level_pos * SP_LEVEL_SIZE;
- int level_width = SP_PLAYFIELD_WIDTH;
- int level_height = SP_PLAYFIELD_HEIGHT;
+ int file_seek_pos = level_pos * SP_STD_LEVEL_SIZE;
+ int level_width = SP_STD_PLAYFIELD_WIDTH;
+ int level_height = SP_STD_PLAYFIELD_HEIGHT;
/* always start with reliable default values */
setLevelInfoToDefaults_SP();
multipart_xpos, multipart_ypos, multipart_level.header.LevelTitle);
#endif
- if (multipart_xpos * SP_PLAYFIELD_WIDTH > SP_MAX_PLAYFIELD_WIDTH ||
- multipart_ypos * SP_PLAYFIELD_HEIGHT > SP_MAX_PLAYFIELD_HEIGHT)
+ if (multipart_xpos * SP_STD_PLAYFIELD_WIDTH > SP_MAX_PLAYFIELD_WIDTH ||
+ multipart_ypos * SP_STD_PLAYFIELD_HEIGHT > SP_MAX_PLAYFIELD_HEIGHT)
{
Error(ERR_WARN, "multi-part level is too big -- ignoring part of it");
}
multipart_level.width = MAX(multipart_level.width,
- multipart_xpos * SP_PLAYFIELD_WIDTH);
+ multipart_xpos * SP_STD_PLAYFIELD_WIDTH);
multipart_level.height = MAX(multipart_level.height,
- multipart_ypos * SP_PLAYFIELD_HEIGHT);
+ multipart_ypos * SP_STD_PLAYFIELD_HEIGHT);
/* copy level part at the right position of multi-part level */
- for (x = 0; x < SP_PLAYFIELD_WIDTH; x++)
+ for (x = 0; x < SP_STD_PLAYFIELD_WIDTH; x++)
{
- for (y = 0; y < SP_PLAYFIELD_HEIGHT; y++)
+ for (y = 0; y < SP_STD_PLAYFIELD_HEIGHT; y++)
{
- int start_x = (multipart_xpos - 1) * SP_PLAYFIELD_WIDTH;
- int start_y = (multipart_ypos - 1) * SP_PLAYFIELD_HEIGHT;
+ int start_x = (multipart_xpos - 1) * SP_STD_PLAYFIELD_WIDTH;
+ int start_y = (multipart_ypos - 1) * SP_STD_PLAYFIELD_HEIGHT;
multipart_level.playfield[start_x + x][start_y + y] =
native_sp_level.playfield[x][y];
Bitmap *screenBitmap;
+struct EngineSnapshotInfo_SP engine_snapshot_sp;
+
static void init_struct_functions()
{
Stage.Blt = &DDScrollBuffer_Blt;
return (unsigned int) seed;
}
+
+
+/* ------------------------------------------------------------------------- */
+/* Supaplex game engine snapshot handling functions */
+/* ------------------------------------------------------------------------- */
+
+static ListNode *engine_snapshot_list_sp = NULL;
+
+void SaveEngineSnapshotValues_SP()
+{
+ int i;
+
+ engine_snapshot_sp.game_sp = game_sp;
+
+ /* these arrays have playfield-size dependent variable size */
+
+ for (i = 0; i < FieldWidth * FieldHeight + HeaderSize; i++)
+ engine_snapshot_sp.PlayField16[i] = PlayField16[i];
+ for (i = 0; i < FieldWidth * FieldHeight + HeaderSize; i++)
+ engine_snapshot_sp.PlayField8[i] = PlayField8[i];
+ for (i = 0; i < FieldWidth * FieldHeight + HeaderSize; i++)
+ engine_snapshot_sp.DisPlayField[i] = DisPlayField[i];
+
+ for (i = 0; i < FieldWidth * (FieldHeight - 2); i++)
+ engine_snapshot_sp.AnimationPosTable[i] = AnimationPosTable[i];
+ for (i = 0; i < FieldWidth * (FieldHeight - 2); i++)
+ engine_snapshot_sp.AnimationSubTable[i] = AnimationSubTable[i];
+ for (i = 0; i < FieldWidth * FieldHeight + HeaderSize; i++)
+ engine_snapshot_sp.TerminalState[i] = TerminalState[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(FileMax));
+
+ 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(DisplayWidth));
+ SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(DisplayHeight));
+
+ 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(UpdateTimeFlag));
+ SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(UpdatedFlag));
+ 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));
+}
+
+void LoadEngineSnapshotValues_SP()
+{
+ int i;
+
+ /* stored engine snapshot buffers already restored at this point */
+
+ game_sp = engine_snapshot_sp.game_sp;
+
+ /* these arrays have playfield-size dependent variable size */
+
+ for (i = 0; i < FieldWidth * FieldHeight + HeaderSize; i++)
+ PlayField16[i] = engine_snapshot_sp.PlayField16[i];
+ for (i = 0; i < FieldWidth * FieldHeight + HeaderSize; i++)
+ PlayField8[i] = engine_snapshot_sp.PlayField8[i];
+ for (i = 0; i < FieldWidth * FieldHeight + HeaderSize; i++)
+ DisPlayField[i] = engine_snapshot_sp.DisPlayField[i];
+
+ for (i = 0; i < FieldWidth * (FieldHeight - 2); i++)
+ AnimationPosTable[i] = engine_snapshot_sp.AnimationPosTable[i];
+ for (i = 0; i < FieldWidth * (FieldHeight - 2); i++)
+ AnimationSubTable[i] = engine_snapshot_sp.AnimationSubTable[i];
+ for (i = 0; i < FieldWidth * FieldHeight + HeaderSize; i++)
+ TerminalState[i] = engine_snapshot_sp.TerminalState[i];
+
+ RedrawPlayfield_SP(TRUE);
+}
#include "global.h"
-struct GameInfo_SP game_sp_info;
+struct GameInfo_SP game_sp;
struct LevelInfo_SP native_sp_level;
gfx.anim_random_frame = -1; // (use simple, ad-hoc random numbers)
- game_sp_info.LevelSolved = FALSE;
- game_sp_info.GameOver = FALSE;
+ game_sp.LevelSolved = FALSE;
+ game_sp.GameOver = FALSE;
menBorder.Checked = setup.sp_show_border_elements;
{
// subDisplayLevel();
- UpdatePlayfield();
+ if (force_redraw)
+ RestorePlayfield();
+
+ UpdatePlayfield(force_redraw);
BackToFront_SP();
}
text.c \
sound.c \
joystick.c \
+ snapshot.c \
toons.c \
pcx.c \
image.c \
gadgets.o \
text.o \
sound.o \
+ snapshot.o \
joystick.o \
toons.o \
pcx.o \
#include "gadgets.h"
#include "text.h"
#include "sound.h"
+#include "snapshot.h"
#include "joystick.h"
#include "toons.h"
#include "image.h"
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1995-2006 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* snapshot.c *
+***********************************************************/
+
+#include "snapshot.h"
+
+
+static ListNode *engine_snapshot_list = NULL;
+
+void SaveEngineSnapshotBuffer(void *buffer, int size)
+{
+ struct EngineSnapshotNodeInfo *bi =
+ checked_calloc(sizeof(struct EngineSnapshotNodeInfo));
+
+ bi->buffer_orig = buffer;
+ bi->buffer_copy = checked_malloc(size);
+ bi->size = size;
+
+ memcpy(bi->buffer_copy, buffer, size);
+
+ addNodeToList(&engine_snapshot_list, NULL, bi);
+}
+
+static void LoadEngineSnapshotBuffer(struct EngineSnapshotNodeInfo *bi)
+{
+ memcpy(bi->buffer_orig, bi->buffer_copy, bi->size);
+}
+
+void LoadEngineSnapshotBuffers()
+{
+ ListNode *node = engine_snapshot_list;
+
+ while (node != NULL)
+ {
+ LoadEngineSnapshotBuffer((struct EngineSnapshotNodeInfo *)node->content);
+
+ node = node->next;
+ }
+}
+
+void FreeEngineSnapshotBuffers()
+{
+ while (engine_snapshot_list != NULL)
+ deleteNodeFromList(&engine_snapshot_list, engine_snapshot_list->key,
+ checked_free);
+}
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1995-2006 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* snapshot.h *
+***********************************************************/
+
+#ifndef SNAPSHOT_H
+#define SNAPSHOT_H
+
+#include "system.h"
+#include "misc.h"
+
+
+/* needed for comfortably saving engine snapshot buffers */
+#define ARGS_ADDRESS_AND_SIZEOF(x) (&(x)), (sizeof(x))
+
+struct EngineSnapshotNodeInfo
+{
+ void *buffer_orig;
+ void *buffer_copy;
+ int size;
+};
+
+
+void SaveEngineSnapshotBuffer(void *buffer, int size);
+void LoadEngineSnapshotBuffers();
+void FreeEngineSnapshotBuffers();
+
+#endif /* SNAPSHOT_H */