summaryrefslogtreecommitdiff
path: root/arena.c
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2015-11-13 19:15:37 -0800
committerMichael Pavone <pavone@retrodev.com>2015-11-13 19:15:37 -0800
commit802454482c2843234a19a06f6acce360e0be3d60 (patch)
tree5b64111a903c93c75789390121965c055da45dd9 /arena.c
parent3834192b16663bb4bf5098df5b7a053e9c9dd086 (diff)
It is now possible to switch back and forth between the menu ROM and the game
Diffstat (limited to 'arena.c')
-rw-r--r--arena.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/arena.c b/arena.c
new file mode 100644
index 0000000..6bc50e0
--- /dev/null
+++ b/arena.c
@@ -0,0 +1,81 @@
+/*
+ Copyright 2015 Michael Pavone
+ This file is part of BlastEm.
+ BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
+*/
+#include <stdlib.h>
+#include <stdint.h>
+#include "arena.h"
+
+struct arena {
+ void **used_blocks;
+ void **free_blocks;
+
+ size_t used_count;
+ size_t used_storage;
+ size_t free_count;
+ size_t free_storage;
+};
+
+static arena *current_arena;
+
+arena *get_current_arena()
+{
+ if (!current_arena) {
+ current_arena = calloc(1, sizeof(arena));
+ }
+ return current_arena;
+}
+
+arena *set_current_arena(arena *a)
+{
+ arena *tmp = current_arena;
+ current_arena = a;
+ return tmp;
+}
+
+arena *start_new_arena()
+{
+ arena *tmp = current_arena;
+ current_arena = NULL;
+ return tmp;
+}
+
+void track_block(void *block)
+{
+ arena *cur = get_current_arena();
+ if (cur->used_count == cur->used_storage) {
+ cur->used_storage *= 2;
+ cur->used_blocks = realloc(cur->used_blocks, cur->used_storage * sizeof(void *));
+ }
+ cur->used_blocks[cur->used_count++] = block;
+}
+
+void mark_all_free()
+{
+ arena *cur = get_current_arena();
+ if (!cur->free_blocks) {
+ cur->free_blocks = cur->used_blocks;
+ cur->free_storage = cur->used_storage;
+ cur->free_count = cur->used_count;
+ cur->used_count = cur->used_storage = 0;
+ cur->used_blocks = NULL;
+ } else {
+ if (cur->free_storage < cur->used_count + cur->free_count) {
+ cur->free_storage = cur->used_count + cur->free_count;
+ cur->free_blocks = realloc(cur->free_blocks, cur->free_storage * sizeof(void*));
+ }
+ for (; cur->used_count > 0; cur->used_count--)
+ {
+ cur->free_blocks[cur->free_count++] = cur->used_blocks[cur->used_count-1];
+ }
+ }
+}
+
+void *try_alloc_arena()
+{
+ if (!current_arena || !current_arena->free_count) {
+ return NULL;
+ }
+ return current_arena->free_blocks[--current_arena->free_count];
+}