rnd-20100220-1-src
authorHolger Schemel <info@artsoft.org>
Fri, 19 Feb 2010 23:31:14 +0000 (00:31 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:58:38 +0000 (10:58 +0200)
* started integrating snapshot functionality into Supaplex game engine

16 files changed:
ChangeLog
src/conftime.h
src/game.c
src/game_sp/DDScrollBuffer.c
src/game_sp/DDScrollBuffer.h
src/game_sp/DoGameStuff.c
src/game_sp/MainGameLoop.c
src/game_sp/Murphy.c
src/game_sp/export.h
src/game_sp/file.c
src/game_sp/init.c
src/game_sp/main.c
src/libgame/Makefile
src/libgame/libgame.h
src/libgame/snapshot.c [new file with mode: 0644]
src/libgame/snapshot.h [new file with mode: 0644]

index 59251bf1af90c9330cfa6b07e9d414c83cbd8f7d..bb3788ef19df3a0f01028ebe03c0fc7439f8d2c4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+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
index 04dec544a3df97dc53f176817ed84d6e02695548..9c1189a4b2e57316132613fef5ef0d6574848892 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "2010-02-18 09:22"
+#define COMPILE_DATE_STRING "2010-02-20 00:28"
index f8b9a085891166c4db14cdb306e9546810c87800..cf7193f87cafe33d5009ae32ac232b784fbb3bb0 100644 (file)
@@ -12058,17 +12058,17 @@ static void CheckLevelTime()
   }
   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;
   }
 
@@ -12268,17 +12268,17 @@ void GameActions()
   }
   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;
   }
 
@@ -16413,8 +16413,6 @@ unsigned int RND(int max)
 /* game engine snapshot handling functions                                   */
 /* ------------------------------------------------------------------------- */
 
-#define ARGS_ADDRESS_AND_SIZEOF(x)             (&(x)), (sizeof(x))
-
 struct EngineSnapshotInfo
 {
   /* runtime values for custom element collect score */
@@ -16428,28 +16426,10 @@ struct EngineSnapshotInfo
   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] =
@@ -16535,36 +16515,26 @@ static void LoadEngineSnapshotValues_RND()
   }
 }
 
-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 */
 
@@ -16638,7 +16608,7 @@ void SaveEngineSnapshot()
   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)
@@ -16652,29 +16622,17 @@ void SaveEngineSnapshot()
 #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()
index 5a89919c320bc0982be26a0b3d365d535c6f680f..544b169e4f69731e54174e108fdc5ec773989529 100644 (file)
@@ -39,6 +39,28 @@ boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
 
 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)
 {
@@ -184,7 +206,7 @@ void InitScrollPlayfield()
   ScrollPlayfieldIfNeededExt(TRUE);
 }
 
-void UpdatePlayfield()
+void UpdatePlayfield(boolean force_redraw)
 {
   int x, y;
 #if 1
@@ -198,10 +220,10 @@ void UpdatePlayfield()
       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)
index 402cdcadf0e7206ddfa86ae40c4cdc9f4f7b23dd..aaaf63abca0fc33f9037c9dcf53c1c9f16dadd84 100644 (file)
@@ -22,6 +22,7 @@ extern int TEST_flag;
 
 extern void InitScrollPlayfield();
 extern void UpdatePlayfield();
+extern void RestorePlayfield();
 
 extern void DDScrollBuffer_Blt_Ext(Bitmap *);
 extern void DDScrollBuffer_Blt();
index 8e7d8830c9dc360fa294616da41450cdf098c5f9..81f4a9546becbef16c27058cd7d70e6998385250 100644 (file)
@@ -77,8 +77,8 @@ int subDoGameStuff()
   {
 #if 1
     if (LeadOutCounter == 0 &&
-       !game_sp_info.LevelSolved &&
-       !game_sp_info.GameOver)
+       !game_sp.LevelSolved &&
+       !game_sp.GameOver)
 #else
     if (LeadOutCounter == 0)
 #endif
@@ -101,7 +101,7 @@ int subDoGameStuff()
 #if 1
       /* give Murphy some more time (LeadOutCounter) to reach the exit */
 #else
-      game_sp_info.GameOver = TRUE;
+      game_sp.GameOver = TRUE;
 #endif
 
 #endif
@@ -110,19 +110,19 @@ int subDoGameStuff()
 #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
index 60a479db7c6ec9056ce2541e7743139efa34222d..028c861e03a5741f44a9eccff4d84465340cfed1 100644 (file)
@@ -293,8 +293,8 @@ locExitMainGameLoop:
 
 #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
index e104a5c7d1b4b4d3fd8f32010d941363dd2e58fa..f42d8da94168d1a3482023feed86a270a5ad3d48 100644 (file)
@@ -1073,12 +1073,12 @@ loc_g_6756:
     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();
index f54bb28aee2c012a4b1405d5e4a0a630147393ba..bfeab9dd4973bfdee398ddfa100044dbe47b5c19 100644 (file)
 
 #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)
@@ -87,6 +89,9 @@ struct GameInfo_SP
 {
   boolean LevelSolved;
   boolean GameOver;
+
+  /* needed for engine snapshots */
+  int preceding_buffer_size;
 };
 
 struct DemoInfo_SP
@@ -132,6 +137,14 @@ struct GraphicInfo_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];
 };
 
 
@@ -140,7 +153,7 @@ struct EngineSnapshotInfo_SP
 /* ------------------------------------------------------------------------- */
 
 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];
index 2ba322d7e476a0e6fe28e53eaded20a30f278149..5a525214b44576414d5e68a76578e6316d15aa6d 100644 (file)
@@ -13,8 +13,8 @@ void setLevelInfoToDefaults_SP()
   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++)
@@ -110,6 +110,9 @@ void copyInternalEngineVars_SP()
     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;
@@ -416,9 +419,9 @@ boolean LoadNativeLevel_SP(char *filename, int level_pos)
                                  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();
@@ -611,8 +614,8 @@ boolean LoadNativeLevel_SP(char *filename, int level_pos)
           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");
 
@@ -620,17 +623,17 @@ boolean LoadNativeLevel_SP(char *filename, int level_pos)
     }
 
     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];
index 5fb36f19d265af74699fea4965436e30d51822c2..76e690e159383f53e07bf4ed2f47acf9756c9ba5 100644 (file)
@@ -7,6 +7,8 @@ Bitmap *sp_objects;
 
 Bitmap *screenBitmap;
 
+struct EngineSnapshotInfo_SP engine_snapshot_sp;
+
 static void init_struct_functions()
 {
   Stage.Blt           = &DDScrollBuffer_Blt;
@@ -76,3 +78,128 @@ unsigned int InitEngineRandom_SP(long seed)
 
   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);
+}
index 38e54a364c238537c3472fe3c576c6a60ee01722..f30aa0dbbb5e8cd8f4c743f7c58064a6e62720ce 100644 (file)
@@ -3,7 +3,7 @@
 #include "global.h"
 
 
-struct GameInfo_SP game_sp_info;
+struct GameInfo_SP game_sp;
 struct LevelInfo_SP native_sp_level;
 
 
@@ -19,8 +19,8 @@ void InitGameEngine_SP()
 
   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;
 
@@ -65,7 +65,10 @@ void RedrawPlayfield_SP(boolean force_redraw)
 {
   // subDisplayLevel();
 
-  UpdatePlayfield();
+  if (force_redraw)
+    RestorePlayfield();
+
+  UpdatePlayfield(force_redraw);
 
   BackToFront_SP();
 }
index 6148a9850eea68621ed487abca8a02bc2927eecb..140e9fd9a5bb6aebd65b494ce3363042b361ecc4 100644 (file)
@@ -13,6 +13,7 @@ SRCS =        system.c        \
        text.c          \
        sound.c         \
        joystick.c      \
+       snapshot.c      \
        toons.c         \
        pcx.c           \
        image.c         \
@@ -28,6 +29,7 @@ OBJS =        system.o        \
        gadgets.o       \
        text.o          \
        sound.o         \
+       snapshot.o      \
        joystick.o      \
        toons.o         \
        pcx.o           \
index 6f4c20c29e248d3f77eea1c9ec1fc04436c32926..d1f05c82fe561e07c112e9c4aaf0c97dc5608546 100644 (file)
@@ -23,6 +23,7 @@
 #include "gadgets.h"
 #include "text.h"
 #include "sound.h"
+#include "snapshot.h"
 #include "joystick.h"
 #include "toons.h"
 #include "image.h"
diff --git a/src/libgame/snapshot.c b/src/libgame/snapshot.c
new file mode 100644 (file)
index 0000000..d28ae34
--- /dev/null
@@ -0,0 +1,55 @@
+/***********************************************************
+* 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);
+}
diff --git a/src/libgame/snapshot.h b/src/libgame/snapshot.h
new file mode 100644 (file)
index 0000000..706fc05
--- /dev/null
@@ -0,0 +1,36 @@
+/***********************************************************
+* 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 */