changed gcc optimization level from "-O3" to "-O2" for releases
[rocksndiamonds.git] / src / libgame / snapshot.c
index 43a42c34d50920813717c73314337aba168a6ad8..cd83dc5be1636470983d559a334dad309e96b2f9 100644 (file)
@@ -4,7 +4,7 @@
 // (c) 1995-2014 by Artsoft Entertainment
 //                         Holger Schemel
 //                 info@artsoft.org
-//                 http://www.artsoft.org/
+//                 https://www.artsoft.org/
 // ----------------------------------------------------------------------------
 // snapshot.c
 // ============================================================================
 #include "snapshot.h"
 
 
-static ListNode *snapshot_single = NULL;
-static ListNode *snapshot_list = NULL;
-static ListNode *snapshot_current = NULL;
-
-static int num_snapshots_in_list = 0;
-
 #ifdef DEBUG
 #define DEBUG_SNAPSHOTS                        0
 #endif
 
-#if DEBUG_SNAPSHOTS
+static ListNode *snapshot_single = NULL;
+static ListNode *snapshot_list = NULL;
+static ListNode *snapshot_current = NULL;
+
+static int num_snapshots = 0;
 static int num_snapshot_buffers = 0;
 static int num_snapshot_bytes = 0;
-#endif
+static int next_snapshot_key = 0;
 
 
 // -----------------------------------------------------------------------------
@@ -45,10 +43,8 @@ void SaveSnapshotBuffer(ListNode **snapshot_buffers, void *buffer, int size)
 
   addNodeToList(snapshot_buffers, NULL, bi);
 
-#if DEBUG_SNAPSHOTS
   num_snapshot_buffers++;
   num_snapshot_bytes += size;
-#endif
 }
 
 static void LoadSnapshotBuffer(struct SnapshotNodeInfo *bi)
@@ -70,10 +66,8 @@ static void FreeSnapshotBuffer(void *bi_raw)
 {
   struct SnapshotNodeInfo *bi = (struct SnapshotNodeInfo *)bi_raw;
 
-#if DEBUG_SNAPSHOTS
   num_snapshot_buffers--;
   num_snapshot_bytes -= bi->size;
-#endif
 
   checked_free(bi->buffer_copy);
   checked_free(bi);
@@ -94,7 +88,7 @@ static void FreeSnapshot(void *snapshot_buffers_ptr)
   FreeSnapshotBuffers(snapshot_buffers_ptr);
 }
 
-void FreeSnapshotSingle()
+void FreeSnapshotSingle(void)
 {
   FreeSnapshotBuffers(snapshot_single);
 
@@ -106,27 +100,79 @@ static void FreeSnapshotList_UpToNode(ListNode *node)
   while (snapshot_list != node)
   {
 #if DEBUG_SNAPSHOTS
-    printf("::: FreeSnapshotList_*() [%s, %d, %d]\n",
-          snapshot_list->key, num_snapshot_buffers, num_snapshot_bytes);
+    Debug("snapshot:FreeSnapshotList_UpToNode", "[%s, %d, %d]",
+         snapshot_list->key, num_snapshot_buffers, num_snapshot_bytes);
 #endif
 
     deleteNodeFromList(&snapshot_list, snapshot_list->key, FreeSnapshot);
 
-    num_snapshots_in_list--;
+    num_snapshots--;
+    next_snapshot_key = (snapshot_list ? atoi(snapshot_list->key) + 1 : 0);
   }
 }
 
-void FreeSnapshotList()
+void FreeSnapshotList(void)
 {
 #if DEBUG_SNAPSHOTS
-  printf("::: FreeSnapshotList()\n");
+  Debug("snapshot:FreeSnapshotList", "");
 #endif
 
   FreeSnapshotList_UpToNode(NULL);
 
+  num_snapshots = 0;
+  num_snapshot_buffers = 0;
+  num_snapshot_bytes = 0;
+  next_snapshot_key = 0;
+
   snapshot_current = NULL;
 }
 
+static void ReduceSnapshotList(void)
+{
+#if DEBUG_SNAPSHOTS
+  int num_snapshots_last = num_snapshots;
+#endif
+
+  // maximum number of snapshots exceeded -- thin out list of snapshots
+  ListNode *node = snapshot_list;
+  int num_snapshots_to_skip = num_snapshots / 10;
+
+  // do not remove the newest snapshots from the list
+  while (node && num_snapshots_to_skip--)
+    node = node->next;
+
+  // remove every second snapshot from the remaining list
+  while (node)
+  {
+    // never delete the first list node (snapshot at game start)
+    if (node->next == NULL)
+      break;
+
+    // in alternation, delete one node from the list ...
+    deleteNodeFromList(&node, node->key, FreeSnapshot);
+    num_snapshots--;
+
+    // ... and keep one node (which always exists here)
+    node = node->next;
+  }
+
+#if DEBUG_SNAPSHOTS
+  Debug("snapshot:ReduceSnapshotList",
+       "(Reducing number of snapshots from %d to %d.)",
+       num_snapshots_last, num_snapshots);
+
+#if 0
+  node = snapshot_list;
+  while (node)
+  {
+    Debug("snapshot:ReduceSnapshotList", "key: %s", node->key);
+
+    node = node->next;
+  }
+#endif
+#endif
+}
+
 void SaveSnapshotSingle(ListNode *snapshot_buffers)
 {
   if (snapshot_single)
@@ -140,20 +186,26 @@ void SaveSnapshotToList(ListNode *snapshot_buffers)
   if (snapshot_current != snapshot_list)
     FreeSnapshotList_UpToNode(snapshot_current);
 
-  addNodeToList(&snapshot_list, i_to_a(num_snapshots_in_list),
+#if DEBUG_SNAPSHOTS
+  Debug("snapshot:SaveSnapshotToList",
+       "[%d] [%d snapshots, %d buffers, %d bytes]",
+       next_snapshot_key, num_snapshots,
+       num_snapshot_buffers, num_snapshot_bytes);
+#endif
+
+  addNodeToList(&snapshot_list, i_to_a(next_snapshot_key),
                snapshot_buffers);
 
   snapshot_current = snapshot_list;
 
-  num_snapshots_in_list++;
+  num_snapshots++;
+  next_snapshot_key++;
 
-#if DEBUG_SNAPSHOTS
-  printf("::: SaveSnapshotToList() [%s, %d, %d]\n",
-        snapshot_current->key, num_snapshot_buffers, num_snapshot_bytes);
-#endif
+  if (num_snapshot_bytes > setup.engine_snapshot_memory)
+    ReduceSnapshotList();
 }
 
-boolean LoadSnapshotSingle()
+boolean LoadSnapshotSingle(void)
 {
   if (snapshot_single)
   {
@@ -175,7 +227,7 @@ boolean LoadSnapshotFromList_Older(int steps)
     LoadSnapshotBuffers(snapshot_current->content);
 
 #if DEBUG_SNAPSHOTS
-    printf("::: LoadSnapshotFromList_Older() [%s]\n", snapshot_current->key);
+    Debug("snapshot:LoadSnapshotFromList_Older", "[%s]", snapshot_current->key);
 #endif
 
     return TRUE;
@@ -194,7 +246,7 @@ boolean LoadSnapshotFromList_Newer(int steps)
     LoadSnapshotBuffers(snapshot_current->content);
 
 #if DEBUG_SNAPSHOTS
-    printf("::: LoadSnapshotFromList_Newer() [%s]\n", snapshot_current->key);
+    Debug("snapshot:LoadSnapshotFromList_Newer", "[%s]", snapshot_current->key);
 #endif
 
     return TRUE;
@@ -203,7 +255,7 @@ boolean LoadSnapshotFromList_Newer(int steps)
   return FALSE;
 }
 
-boolean CheckSnapshotList()
+boolean CheckSnapshotList(void)
 {
   return (snapshot_list ? TRUE : FALSE);
 }