1 // ============================================================================
2 // Artsoft Retro-Game Library
3 // ----------------------------------------------------------------------------
4 // (c) 1995-2014 by Artsoft Entertainment
7 // http://www.artsoft.org/
8 // ----------------------------------------------------------------------------
10 // ============================================================================
16 #define DEBUG_SNAPSHOTS 0
20 #define MAX_SNAPSHOT_BYTES (50 * 1024 * 1024)
22 #define MAX_SNAPSHOT_BYTES (500 * 1024 * 1024)
25 static ListNode *snapshot_single = NULL;
26 static ListNode *snapshot_list = NULL;
27 static ListNode *snapshot_current = NULL;
29 static int num_snapshots = 0;
30 static int num_snapshot_buffers = 0;
31 static int num_snapshot_bytes = 0;
32 static int next_snapshot_key = 0;
35 // -----------------------------------------------------------------------------
36 // functions for handling buffers for a single snapshot
37 // -----------------------------------------------------------------------------
39 void SaveSnapshotBuffer(ListNode **snapshot_buffers, void *buffer, int size)
41 struct SnapshotNodeInfo *bi =
42 checked_calloc(sizeof(struct SnapshotNodeInfo));
44 bi->buffer_orig = buffer;
45 bi->buffer_copy = checked_malloc(size);
48 memcpy(bi->buffer_copy, buffer, size);
50 addNodeToList(snapshot_buffers, NULL, bi);
52 num_snapshot_buffers++;
53 num_snapshot_bytes += size;
56 static void LoadSnapshotBuffer(struct SnapshotNodeInfo *bi)
58 memcpy(bi->buffer_orig, bi->buffer_copy, bi->size);
61 void LoadSnapshotBuffers(ListNode *snapshot_buffers)
63 while (snapshot_buffers != NULL)
65 LoadSnapshotBuffer((struct SnapshotNodeInfo *)snapshot_buffers->content);
67 snapshot_buffers = snapshot_buffers->next;
71 static void FreeSnapshotBuffer(void *bi_raw)
73 struct SnapshotNodeInfo *bi = (struct SnapshotNodeInfo *)bi_raw;
75 num_snapshot_buffers--;
76 num_snapshot_bytes -= bi->size;
78 checked_free(bi->buffer_copy);
82 void FreeSnapshotBuffers(ListNode *snapshot_buffers)
84 while (snapshot_buffers != NULL)
85 deleteNodeFromList(&snapshot_buffers, NULL, FreeSnapshotBuffer);
88 // -----------------------------------------------------------------------------
89 // functions for handling single shapshot or list of snapshots
90 // -----------------------------------------------------------------------------
92 static void FreeSnapshot(void *snapshot_buffers_ptr)
94 FreeSnapshotBuffers(snapshot_buffers_ptr);
97 void FreeSnapshotSingle()
99 FreeSnapshotBuffers(snapshot_single);
101 snapshot_single = NULL;
104 static void FreeSnapshotList_UpToNode(ListNode *node)
106 while (snapshot_list != node)
109 printf("::: FreeSnapshotList_*() [%s, %d, %d]\n",
110 snapshot_list->key, num_snapshot_buffers, num_snapshot_bytes);
113 deleteNodeFromList(&snapshot_list, snapshot_list->key, FreeSnapshot);
116 next_snapshot_key = (snapshot_list ? atoi(snapshot_list->key) + 1 : 0);
120 void FreeSnapshotList()
123 printf("::: FreeSnapshotList()\n");
126 FreeSnapshotList_UpToNode(NULL);
129 num_snapshot_buffers = 0;
130 num_snapshot_bytes = 0;
131 next_snapshot_key = 0;
133 snapshot_current = NULL;
136 void ReduceSnapshotList()
139 printf("::: (Reducing number of snapshots from %d ",
143 // maximum number of snapshots exceeded -- thin out list of snapshots
144 ListNode *node = snapshot_list;
145 int num_snapshots_to_skip = num_snapshots / 10;
147 // do not remove the newest snapshots from the list
148 while (node && num_snapshots_to_skip--)
151 // remove every second snapshot from the remaining list
154 // never delete the first list node (snapshot at game start)
155 if (node->next == NULL)
158 // in alternation, delete one node from the list ...
159 deleteNodeFromList(&node, node->key, FreeSnapshot);
162 // ... and keep one node (which always exists here)
167 printf("to %d.)\n", num_snapshots);
170 node = snapshot_list;
173 printf("::: key: %s\n", node->key);
180 void SaveSnapshotSingle(ListNode *snapshot_buffers)
183 FreeSnapshotSingle();
185 snapshot_single = snapshot_buffers;
188 void SaveSnapshotToList(ListNode *snapshot_buffers)
190 if (snapshot_current != snapshot_list)
191 FreeSnapshotList_UpToNode(snapshot_current);
194 printf("::: SaveSnapshotToList() [%d] [%d snapshots, %d buffers, %d bytes]\n",
195 next_snapshot_key, num_snapshots,
196 num_snapshot_buffers, num_snapshot_bytes);
199 addNodeToList(&snapshot_list, i_to_a(next_snapshot_key),
202 snapshot_current = snapshot_list;
207 if (num_snapshot_bytes > MAX_SNAPSHOT_BYTES)
208 ReduceSnapshotList();
211 boolean LoadSnapshotSingle()
215 LoadSnapshotBuffers(snapshot_single);
223 boolean LoadSnapshotFromList_Older(int steps)
225 if (snapshot_current && snapshot_current->next)
227 while (snapshot_current->next && steps--)
228 snapshot_current = snapshot_current->next;
230 LoadSnapshotBuffers(snapshot_current->content);
233 printf("::: LoadSnapshotFromList_Older() [%s]\n", snapshot_current->key);
242 boolean LoadSnapshotFromList_Newer(int steps)
244 if (snapshot_current && snapshot_current->prev)
246 while (snapshot_current->prev && steps--)
247 snapshot_current = snapshot_current->prev;
249 LoadSnapshotBuffers(snapshot_current->content);
252 printf("::: LoadSnapshotFromList_Newer() [%s]\n", snapshot_current->key);
261 boolean CheckSnapshotList()
263 return (snapshot_list ? TRUE : FALSE);