view arena.c @ 915:9e882eca717e

Initial support for relative mouse mode and skeleton of support for capture mode. Avoid mouse position overflow in absolute mode. Allow absolute mode to be set by ROM DB.
author Michael Pavone <pavone@retrodev.com>
date Tue, 15 Dec 2015 20:01:50 -0800
parents 9f149f0e98b7
children c7c573f0229e
line wrap: on
line source

/*
 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];
}