X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Flibgame%2Fsnapshot.c;h=221b9b6117b82d39973d46e694de69c14732181f;hp=1262ee88b2abda4f66173503e70240c2d0f42674;hb=115ce6f2da1914d68b0fe0e5f9082973190dacdd;hpb=4b722be68436ced0b7bb3eff61ed14d6c66df949 diff --git a/src/libgame/snapshot.c b/src/libgame/snapshot.c index 1262ee88..221b9b61 100644 --- a/src/libgame/snapshot.c +++ b/src/libgame/snapshot.c @@ -12,16 +12,18 @@ #include "snapshot.h" +#ifdef DEBUG +#define DEBUG_SNAPSHOTS 0 +#endif + 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 +static int num_snapshots = 0; +static int num_snapshot_buffers = 0; +static int num_snapshot_bytes = 0; +static int next_snapshot_key = 0; // ----------------------------------------------------------------------------- @@ -40,6 +42,9 @@ void SaveSnapshotBuffer(ListNode **snapshot_buffers, void *buffer, int size) memcpy(bi->buffer_copy, buffer, size); addNodeToList(snapshot_buffers, NULL, bi); + + num_snapshot_buffers++; + num_snapshot_bytes += size; } static void LoadSnapshotBuffer(struct SnapshotNodeInfo *bi) @@ -57,45 +62,115 @@ void LoadSnapshotBuffers(ListNode *snapshot_buffers) } } +static void FreeSnapshotBuffer(void *bi_raw) +{ + struct SnapshotNodeInfo *bi = (struct SnapshotNodeInfo *)bi_raw; + + num_snapshot_buffers--; + num_snapshot_bytes -= bi->size; + + checked_free(bi->buffer_copy); + checked_free(bi); +} + void FreeSnapshotBuffers(ListNode *snapshot_buffers) { while (snapshot_buffers != NULL) - deleteNodeFromList(&snapshot_buffers, snapshot_buffers->key, checked_free); + deleteNodeFromList(&snapshot_buffers, NULL, FreeSnapshotBuffer); } // ----------------------------------------------------------------------------- -// functions for handling one of several snapshots +// functions for handling single shapshot or list of snapshots // ----------------------------------------------------------------------------- -static void FreeSnapshotExt(void *snapshot_buffers_ptr) +static void FreeSnapshot(void *snapshot_buffers_ptr) { FreeSnapshotBuffers(snapshot_buffers_ptr); } -void FreeSnapshotSingle() +void FreeSnapshotSingle(void) { FreeSnapshotBuffers(snapshot_single); snapshot_single = NULL; } -void FreeSnapshotList_UpToNode(ListNode *node) +static void FreeSnapshotList_UpToNode(ListNode *node) { while (snapshot_list != node) { - deleteNodeFromList(&snapshot_list, snapshot_list->key, FreeSnapshotExt); +#if DEBUG_SNAPSHOTS + printf("::: FreeSnapshotList_*() [%s, %d, %d]\n", + 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"); +#endif + FreeSnapshotList_UpToNode(NULL); + num_snapshots = 0; + num_snapshot_buffers = 0; + num_snapshot_bytes = 0; + next_snapshot_key = 0; + snapshot_current = NULL; } +void ReduceSnapshotList(void) +{ +#if DEBUG_SNAPSHOTS + printf("::: (Reducing number of snapshots from %d ", + 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 + printf("to %d.)\n", num_snapshots); + +#if 0 + node = snapshot_list; + while (node) + { + printf("::: key: %s\n", node->key); + node = node->next; + } +#endif +#endif +} + void SaveSnapshotSingle(ListNode *snapshot_buffers) { if (snapshot_single) @@ -109,19 +184,25 @@ 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 + printf("::: SaveSnapshotToList() [%d] [%d snapshots, %d buffers, %d bytes]\n", + 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]\n", snapshot_current->key); -#endif + if (num_snapshot_bytes > setup.engine_snapshot_memory) + ReduceSnapshotList(); } -boolean LoadSnapshotSingle() +boolean LoadSnapshotSingle(void) { if (snapshot_single) { @@ -135,7 +216,7 @@ boolean LoadSnapshotSingle() boolean LoadSnapshotFromList_Older(int steps) { - if (snapshot_current->next) + if (snapshot_current && snapshot_current->next) { while (snapshot_current->next && steps--) snapshot_current = snapshot_current->next; @@ -154,7 +235,7 @@ boolean LoadSnapshotFromList_Older(int steps) boolean LoadSnapshotFromList_Newer(int steps) { - if (snapshot_current->prev) + if (snapshot_current && snapshot_current->prev) { while (snapshot_current->prev && steps--) snapshot_current = snapshot_current->prev; @@ -170,3 +251,8 @@ boolean LoadSnapshotFromList_Newer(int steps) return FALSE; } + +boolean CheckSnapshotList(void) +{ + return (snapshot_list ? TRUE : FALSE); +}