2018-05-26 18:17:42 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <string.h>
|
2019-02-27 20:45:53 +00:00
|
|
|
#include <assert.h>
|
2018-05-26 18:17:42 +00:00
|
|
|
|
|
|
|
#ifndef __APPLE__
|
|
|
|
#include <malloc.h>
|
|
|
|
#else
|
|
|
|
/* Linux + Kos define this, OSX does not, so just use malloc there */
|
|
|
|
#define memalign(x, size) malloc((size))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "named_array.h"
|
|
|
|
|
|
|
|
void named_array_init(NamedArray* array, unsigned int element_size, unsigned int max_elements) {
|
|
|
|
array->element_size = element_size;
|
|
|
|
array->max_element_count = max_elements;
|
|
|
|
|
|
|
|
float c = (float) max_elements / 8.0f;
|
|
|
|
array->marker_count = (unsigned char) ceil(c);
|
|
|
|
|
|
|
|
#ifdef _arch_dreamcast
|
|
|
|
// Use 32-bit aligned memory on the Dreamcast
|
|
|
|
array->elements = (unsigned char*) memalign(0x20, element_size * max_elements);
|
|
|
|
array->used_markers = (unsigned char*) memalign(0x20, array->marker_count);
|
|
|
|
#else
|
|
|
|
array->elements = (unsigned char*) malloc(element_size * max_elements);
|
|
|
|
array->used_markers = (unsigned char*) malloc(array->marker_count);
|
|
|
|
#endif
|
2018-08-21 14:50:27 +00:00
|
|
|
memset(array->used_markers, 0, sizeof(unsigned char) * array->marker_count);
|
2018-05-26 18:17:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char named_array_used(NamedArray* array, unsigned int id) {
|
|
|
|
unsigned int i = id / 8;
|
|
|
|
unsigned int j = id % 8;
|
|
|
|
|
|
|
|
unsigned char v = array->used_markers[i] & (unsigned char) (1 << j);
|
|
|
|
return !!(v);
|
|
|
|
}
|
|
|
|
|
|
|
|
void* named_array_alloc(NamedArray* array, unsigned int* new_id) {
|
|
|
|
unsigned int i = 0, j = 0;
|
|
|
|
for(i = 0; i < array->marker_count; ++i) {
|
|
|
|
for(j = 0; j < 8; ++j) {
|
2019-02-28 18:33:37 +00:00
|
|
|
unsigned int id = (i * 8) + j;
|
2018-05-26 18:17:42 +00:00
|
|
|
if(!named_array_used(array, id)) {
|
|
|
|
array->used_markers[i] |= (unsigned char) 1 << j;
|
|
|
|
*new_id = id;
|
2019-02-28 18:33:37 +00:00
|
|
|
unsigned char* ptr = &array->elements[id * array->element_size];
|
2018-05-26 18:17:42 +00:00
|
|
|
memset(ptr, 0, array->element_size);
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-02-27 20:45:53 +00:00
|
|
|
void* named_array_reserve(NamedArray* array, unsigned int id) {
|
|
|
|
if(!named_array_used(array, id)) {
|
2019-02-28 18:33:37 +00:00
|
|
|
unsigned int j = (id % 8);
|
2019-02-28 08:34:32 +00:00
|
|
|
unsigned int i = id / 8;
|
2019-02-27 20:45:53 +00:00
|
|
|
|
|
|
|
assert(!named_array_used(array, id));
|
|
|
|
array->used_markers[i] |= (unsigned char) 1 << j;
|
|
|
|
assert(named_array_used(array, id));
|
|
|
|
|
2019-02-28 18:33:37 +00:00
|
|
|
unsigned char* ptr = &array->elements[id * array->element_size];
|
2019-02-27 20:45:53 +00:00
|
|
|
memset(ptr, 0, array->element_size);
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return named_array_get(array, id);
|
|
|
|
}
|
|
|
|
|
2018-05-26 18:17:42 +00:00
|
|
|
void named_array_release(NamedArray* array, unsigned int new_id) {
|
|
|
|
unsigned int i = new_id / 8;
|
|
|
|
unsigned int j = new_id % 8;
|
|
|
|
|
|
|
|
array->used_markers[i] &= (unsigned char) ~(1 << j);
|
|
|
|
}
|
|
|
|
|
|
|
|
void* named_array_get(NamedArray* array, unsigned int id) {
|
|
|
|
if(!named_array_used(array, id)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-02-28 18:33:37 +00:00
|
|
|
return &array->elements[id * array->element_size];
|
2018-05-26 18:17:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void named_array_cleanup(NamedArray* array) {
|
|
|
|
free(array->elements);
|
|
|
|
free(array->used_markers);
|
|
|
|
array->elements = NULL;
|
|
|
|
array->used_markers = NULL;
|
|
|
|
array->element_size = array->max_element_count = 0;
|
|
|
|
array->marker_count = 0;
|
|
|
|
}
|
|
|
|
|