added setting engine snapshot mode to setup screen and file
[rocksndiamonds.git] / src / libgame / snapshot.c
1 // ============================================================================
2 // Artsoft Retro-Game Library
3 // ----------------------------------------------------------------------------
4 // (c) 1995-2014 by Artsoft Entertainment
5 //                  Holger Schemel
6 //                  info@artsoft.org
7 //                  http://www.artsoft.org/
8 // ----------------------------------------------------------------------------
9 // snapshot.c
10 // ============================================================================
11
12 #include "snapshot.h"
13
14
15 static ListNode *snapshot_single = NULL;
16 static ListNode *snapshot_list = NULL;
17 static ListNode *snapshot_current = NULL;
18
19 static int num_snapshots_in_list = 0;
20
21 #ifdef DEBUG
22 #define DEBUG_SNAPSHOTS                 0
23 #endif
24
25 #if DEBUG_SNAPSHOTS
26 static int num_snapshot_buffers = 0;
27 static int num_snapshot_bytes = 0;
28 #endif
29
30
31 // -----------------------------------------------------------------------------
32 // functions for handling buffers for a single snapshot
33 // -----------------------------------------------------------------------------
34
35 void SaveSnapshotBuffer(ListNode **snapshot_buffers, void *buffer, int size)
36 {
37   struct SnapshotNodeInfo *bi =
38     checked_calloc(sizeof(struct SnapshotNodeInfo));
39
40   bi->buffer_orig = buffer;
41   bi->buffer_copy = checked_malloc(size);
42   bi->size = size;
43
44   memcpy(bi->buffer_copy, buffer, size);
45
46   addNodeToList(snapshot_buffers, NULL, bi);
47
48 #if DEBUG_SNAPSHOTS
49   num_snapshot_buffers++;
50   num_snapshot_bytes += size;
51 #endif
52 }
53
54 static void LoadSnapshotBuffer(struct SnapshotNodeInfo *bi)
55 {
56   memcpy(bi->buffer_orig, bi->buffer_copy, bi->size);
57 }
58
59 void LoadSnapshotBuffers(ListNode *snapshot_buffers)
60 {
61   while (snapshot_buffers != NULL)
62   {
63     LoadSnapshotBuffer((struct SnapshotNodeInfo *)snapshot_buffers->content);
64
65     snapshot_buffers = snapshot_buffers->next;
66   }
67 }
68
69 static void FreeSnapshotBuffer(void *bi_raw)
70 {
71   struct SnapshotNodeInfo *bi = (struct SnapshotNodeInfo *)bi_raw;
72
73 #if DEBUG_SNAPSHOTS
74   num_snapshot_buffers--;
75   num_snapshot_bytes -= bi->size;
76 #endif
77
78   checked_free(bi->buffer_copy);
79   checked_free(bi);
80 }
81
82 void FreeSnapshotBuffers(ListNode *snapshot_buffers)
83 {
84   while (snapshot_buffers != NULL)
85     deleteNodeFromList(&snapshot_buffers, NULL, FreeSnapshotBuffer);
86 }
87
88 // -----------------------------------------------------------------------------
89 // functions for handling single shapshot or list of snapshots
90 // -----------------------------------------------------------------------------
91
92 static void FreeSnapshot(void *snapshot_buffers_ptr)
93 {
94   FreeSnapshotBuffers(snapshot_buffers_ptr);
95 }
96
97 void FreeSnapshotSingle()
98 {
99   FreeSnapshotBuffers(snapshot_single);
100
101   snapshot_single = NULL;
102 }
103
104 static void FreeSnapshotList_UpToNode(ListNode *node)
105 {
106   while (snapshot_list != node)
107   {
108 #if DEBUG_SNAPSHOTS
109     printf("::: FreeSnapshotList_*() [%s, %d, %d]\n",
110            snapshot_list->key, num_snapshot_buffers, num_snapshot_bytes);
111 #endif
112
113     deleteNodeFromList(&snapshot_list, snapshot_list->key, FreeSnapshot);
114
115     num_snapshots_in_list--;
116   }
117 }
118
119 void FreeSnapshotList()
120 {
121 #if DEBUG_SNAPSHOTS
122   printf("::: FreeSnapshotList()\n");
123 #endif
124
125   FreeSnapshotList_UpToNode(NULL);
126
127   snapshot_current = NULL;
128 }
129
130 void SaveSnapshotSingle(ListNode *snapshot_buffers)
131 {
132   if (snapshot_single)
133     FreeSnapshotSingle();
134
135   snapshot_single = snapshot_buffers;
136 }
137
138 void SaveSnapshotToList(ListNode *snapshot_buffers)
139 {
140   if (snapshot_current != snapshot_list)
141     FreeSnapshotList_UpToNode(snapshot_current);
142
143   addNodeToList(&snapshot_list, i_to_a(num_snapshots_in_list),
144                 snapshot_buffers);
145
146   snapshot_current = snapshot_list;
147
148   num_snapshots_in_list++;
149
150 #if DEBUG_SNAPSHOTS
151   printf("::: SaveSnapshotToList() [%s, %d, %d]\n",
152          snapshot_current->key, num_snapshot_buffers, num_snapshot_bytes);
153 #endif
154 }
155
156 boolean LoadSnapshotSingle()
157 {
158   if (snapshot_single)
159   {
160     LoadSnapshotBuffers(snapshot_single);
161
162     return TRUE;
163   }
164
165   return FALSE;
166 }
167
168 boolean LoadSnapshotFromList_Older(int steps)
169 {
170   if (snapshot_current && snapshot_current->next)
171   {
172     while (snapshot_current->next && steps--)
173       snapshot_current = snapshot_current->next;
174
175     LoadSnapshotBuffers(snapshot_current->content);
176
177 #if DEBUG_SNAPSHOTS
178     printf("::: LoadSnapshotFromList_Older() [%s]\n", snapshot_current->key);
179 #endif
180
181     return TRUE;
182   }
183
184   return FALSE;
185 }
186
187 boolean LoadSnapshotFromList_Newer(int steps)
188 {
189   if (snapshot_current && snapshot_current->prev)
190   {
191     while (snapshot_current->prev && steps--)
192       snapshot_current = snapshot_current->prev;
193
194     LoadSnapshotBuffers(snapshot_current->content);
195
196 #if DEBUG_SNAPSHOTS
197     printf("::: LoadSnapshotFromList_Newer() [%s]\n", snapshot_current->key);
198 #endif
199
200     return TRUE;
201   }
202
203   return FALSE;
204 }
205
206 boolean CheckSnapshotList()
207 {
208   return (snapshot_list ? TRUE : FALSE);
209 }