diff --git a/GL/lighting.c b/GL/lighting.c index 249a389..e40f105 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -1,4 +1,6 @@ #include +#include + #include #include "private.h" diff --git a/GL/matrix.c b/GL/matrix.c index e200e7e..2b78f63 100644 --- a/GL/matrix.c +++ b/GL/matrix.c @@ -1,3 +1,5 @@ +#include + #include #include "../include/gl.h" diff --git a/Makefile b/Makefile index f862122..8075e7a 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ TARGET = libGLdc.a OBJS = GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o -OBJS += GL/matrix.o GL/fog.o GL/error.o +OBJS += GL/matrix.o GL/fog.o GL/error.o containers/stack.o containers/named_array.o containers/aligned_vector.o SUBDIRS = diff --git a/containers/aligned_vector.c b/containers/aligned_vector.c new file mode 100644 index 0000000..b6410c4 --- /dev/null +++ b/containers/aligned_vector.c @@ -0,0 +1,107 @@ +#include +#include +#include + +#ifndef __APPLE__ +#include +#else +/* Linux + Kos define this, OSX does not, so just use malloc there */ +#define memalign(x, size) malloc((size)) +#endif + +#include "aligned_vector.h" + +#define ALIGNED_VECTOR_INITIAL_CAPACITY 256u + +void aligned_vector_init(AlignedVector* vector, unsigned int element_size) { + vector->size = vector->capacity = 0; + vector->element_size = element_size; + vector->data = NULL; + + /* Reserve some initial capacity */ + aligned_vector_reserve(vector, ALIGNED_VECTOR_INITIAL_CAPACITY); +} + +void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) { + if(element_count <= vector->capacity) { + return; + } + + unsigned int original_byte_size = vector->size * vector->element_size; + unsigned int new_byte_size = element_count * vector->element_size; + unsigned char* original_data = vector->data; + vector->data = (unsigned char*) memalign(0x20, new_byte_size); + + if(original_data) { + memcpy(vector->data, original_data, original_byte_size); + free(original_data); + } + + vector->capacity = element_count; +} + +void aligned_vector_push_back(AlignedVector* vector, const void* objs, unsigned int count) { + /* Resize enough room */ + + unsigned int initial_size = vector->size; + aligned_vector_resize(vector, vector->size + count); + + unsigned char* dest = vector->data + (vector->element_size * initial_size); + + /* Copy the objects in */ + memcpy(dest, objs, vector->element_size * count); +} + +void aligned_vector_resize(AlignedVector* vector, const unsigned int element_count) { + /* Don't change memory when resizing downwards, just change the size */ + if(element_count <= vector->size) { + vector->size = element_count; + return; + } + + if(vector->capacity < element_count) { + /* Reserve more than we need so that a subsequent push_back doesn't trigger yet another + * resize */ + aligned_vector_reserve(vector, (int) ceil(((float)element_count) * 1.5f)); + } + + vector->size = element_count; +} + +void* aligned_vector_at(AlignedVector* vector, const unsigned int index) { + return &vector->data[index * vector->element_size]; +} + +void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count) { + const unsigned int current = vector->size; + aligned_vector_resize(vector, vector->size + additional_count); + return aligned_vector_at(vector, current); +} + +void aligned_vector_clear(AlignedVector* vector) { + vector->size = 0; +} + +void aligned_vector_shrink_to_fit(AlignedVector* vector) { + if(vector->size == 0) { + free(vector->data); + vector->data = NULL; + vector->capacity = 0; + } else { + unsigned int new_byte_size = vector->size * vector->element_size; + unsigned char* original_data = vector->data; + vector->data = (unsigned char*) memalign(0x20, new_byte_size); + + if(original_data) { + memcpy(vector->data, original_data, new_byte_size); + free(original_data); + } + + vector->capacity = vector->size; + } +} + +void aligned_vector_cleanup(AlignedVector* vector) { + aligned_vector_clear(vector); + aligned_vector_shrink_to_fit(vector); +} diff --git a/containers/aligned_vector.h b/containers/aligned_vector.h index a160408..130d9be 100644 --- a/containers/aligned_vector.h +++ b/containers/aligned_vector.h @@ -1,20 +1,6 @@ #ifndef ALIGNED_VECTOR_H #define ALIGNED_VECTOR_H -#include -#include -#include - -#ifndef __APPLE__ -#include -#else -/* Linux + Kos define this, OSX does not, so just use malloc there */ -#define memalign(x, size) malloc((size)) -#endif - - -#define ALIGNED_VECTOR_INITIAL_CAPACITY 256u - typedef struct { unsigned int size; unsigned int capacity; @@ -22,101 +8,14 @@ typedef struct { unsigned int element_size; } AlignedVector; - -inline void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count); -inline void aligned_vector_resize(AlignedVector* vector, const unsigned int element_count); - -inline void aligned_vector_init(AlignedVector* vector, unsigned int element_size) { - vector->size = vector->capacity = 0; - vector->element_size = element_size; - vector->data = NULL; - - /* Reserve some initial capacity */ - aligned_vector_reserve(vector, ALIGNED_VECTOR_INITIAL_CAPACITY); -} - -inline void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) { - if(element_count <= vector->capacity) { - return; - } - - unsigned int original_byte_size = vector->size * vector->element_size; - unsigned int new_byte_size = element_count * vector->element_size; - unsigned char* original_data = vector->data; - vector->data = (unsigned char*) memalign(0x20, new_byte_size); - - if(original_data) { - memcpy(vector->data, original_data, original_byte_size); - free(original_data); - } - - vector->capacity = element_count; -} - -inline void aligned_vector_push_back(AlignedVector* vector, const void* objs, unsigned int count) { - /* Resize enough room */ - - unsigned int initial_size = vector->size; - aligned_vector_resize(vector, vector->size + count); - - unsigned char* dest = vector->data + (vector->element_size * initial_size); - - /* Copy the objects in */ - memcpy(dest, objs, vector->element_size * count); -} - -inline void aligned_vector_resize(AlignedVector* vector, const unsigned int element_count) { - /* Don't change memory when resizing downwards, just change the size */ - if(element_count <= vector->size) { - vector->size = element_count; - return; - } - - if(vector->capacity < element_count) { - /* Reserve more than we need so that a subsequent push_back doesn't trigger yet another - * resize */ - aligned_vector_reserve(vector, (int) ceil(((float)element_count) * 1.5f)); - } - - vector->size = element_count; -} - -inline void* aligned_vector_at(AlignedVector* vector, const unsigned int index) { - return &vector->data[index * vector->element_size]; -} - -inline void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count) { - const unsigned int current = vector->size; - aligned_vector_resize(vector, vector->size + additional_count); - return aligned_vector_at(vector, current); -} - -inline void aligned_vector_clear(AlignedVector* vector) { - vector->size = 0; -} - -inline void aligned_vector_shrink_to_fit(AlignedVector* vector) { - if(vector->size == 0) { - free(vector->data); - vector->data = NULL; - vector->capacity = 0; - } else { - unsigned int new_byte_size = vector->size * vector->element_size; - unsigned char* original_data = vector->data; - vector->data = (unsigned char*) memalign(0x20, new_byte_size); - - if(original_data) { - memcpy(vector->data, original_data, new_byte_size); - free(original_data); - } - - vector->capacity = vector->size; - } -} - -inline void aligned_vector_cleanup(AlignedVector* vector) { - aligned_vector_clear(vector); - aligned_vector_shrink_to_fit(vector); -} +void aligned_vector_init(AlignedVector* vector, unsigned int element_size); +void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count); +void aligned_vector_push_back(AlignedVector* vector, const void* objs, unsigned int count); +void aligned_vector_resize(AlignedVector* vector, const unsigned int element_count); +void* aligned_vector_at(AlignedVector* vector, const unsigned int index); +void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count); +void aligned_vector_clear(AlignedVector* vector); +void aligned_vector_shrink_to_fit(AlignedVector* vector); +void aligned_vector_cleanup(AlignedVector* vector); #endif // ALIGNED_VECTOR_H diff --git a/containers/named_array.c b/containers/named_array.c new file mode 100644 index 0000000..e9029e6 --- /dev/null +++ b/containers/named_array.c @@ -0,0 +1,89 @@ +#include +#include +#include + +#ifndef __APPLE__ +#include +#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 + memset(array->used_markers, 0, sizeof(array->marker_count)); +} + +char named_array_used(NamedArray* array, unsigned int id) { + 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) { + unsigned int id = (i * 8) + j + 1; + if(!named_array_used(array, id)) { + array->used_markers[i] |= (unsigned char) 1 << j; + *new_id = id; + unsigned char* ptr = &array->elements[(id - 1) * array->element_size]; + memset(ptr, 0, array->element_size); + return ptr; + } + } + } + + return NULL; +} + +void named_array_release(NamedArray* array, unsigned int new_id) { + 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(id == 0) { + return NULL; + } + + if(!named_array_used(array, id)) { + return NULL; + } + + return &array->elements[(id - 1) * array->element_size]; +} + +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; +} + diff --git a/containers/named_array.h b/containers/named_array.h index 8989cea..f72dfd2 100644 --- a/containers/named_array.h +++ b/containers/named_array.h @@ -1,10 +1,6 @@ #ifndef NAMED_ARRAY_H #define NAMED_ARRAY_H -#include -#include -#include - typedef struct { unsigned int element_size; unsigned int max_element_count; @@ -13,82 +9,11 @@ typedef struct { unsigned char marker_count; } NamedArray; - -inline 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 - memset(array->used_markers, 0, sizeof(array->marker_count)); -} - -inline char named_array_used(NamedArray* array, unsigned int id) { - id--; - - unsigned int i = id / 8; - unsigned int j = id % 8; - - unsigned char v = array->used_markers[i] & (unsigned char) (1 << j); - return !!(v); -} - -inline 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) { - unsigned int id = (i * 8) + j + 1; - if(!named_array_used(array, id)) { - array->used_markers[i] |= (unsigned char) 1 << j; - *new_id = id; - unsigned char* ptr = &array->elements[(id - 1) * array->element_size]; - memset(ptr, 0, array->element_size); - return ptr; - } - } - } - - return NULL; -} - -inline void named_array_release(NamedArray* array, unsigned int new_id) { - new_id--; - - unsigned int i = new_id / 8; - unsigned int j = new_id % 8; - - array->used_markers[i] &= (unsigned char) ~(1 << j); -} - -inline void* named_array_get(NamedArray* array, unsigned int id) { - if(id == 0) { - return NULL; - } - - if(!named_array_used(array, id)) { - return NULL; - } - - return &array->elements[(id - 1) * array->element_size]; -} - -inline 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; -} - +void named_array_init(NamedArray* array, unsigned int element_size, unsigned int max_elements); +char named_array_used(NamedArray* array, unsigned int id); +void* named_array_alloc(NamedArray* array, unsigned int* new_id); +void named_array_release(NamedArray* array, unsigned int new_id); +void* named_array_get(NamedArray* array, unsigned int id); +void named_array_cleanup(NamedArray* array); #endif // NAMED_ARRAY_H diff --git a/containers/stack.c b/containers/stack.c new file mode 100644 index 0000000..ba82b22 --- /dev/null +++ b/containers/stack.c @@ -0,0 +1,45 @@ +#include + +#ifndef __APPLE__ +#include +#else +/* Linux + Kos define this, OSX does not, so just use malloc there */ +#define memalign(x, size) malloc((size)) +#endif + +#include "stack.h" + +void init_stack(Stack* stack, unsigned int element_size, unsigned int capacity) { + stack->size = 0; + stack->capacity = capacity; + stack->element_size = element_size; + stack->data = (unsigned char*) memalign(0x20, element_size * capacity); +} + +void* stack_top(Stack* stack) { + return &stack->data[(stack->size - 1) * stack->element_size]; +} + +void* stack_replace(Stack* stack, const void* element) { + memcpy(stack->data + ((stack->size - 1) * stack->element_size), element, stack->element_size); + return stack_top(stack); +} + +void* stack_push(Stack* stack, const void* element) { + if(stack->size + 1 == stack->capacity) { + return NULL; + } + + memcpy(stack->data + (stack->size * stack->element_size), element, stack->element_size); + stack->size++; + + return stack_top(stack); +} + +void stack_pop(Stack* stack) { + if(stack->size == 0) { + return; + } + + stack->size--; +} diff --git a/containers/stack.h b/containers/stack.h index ebb9dec..12945f6 100644 --- a/containers/stack.h +++ b/containers/stack.h @@ -1,16 +1,6 @@ #ifndef STACK_H #define STACK_H -#include - -#ifndef __APPLE__ -#include -#else -/* Linux + Kos define this, OSX does not, so just use malloc there */ -#define memalign(x, size) malloc((size)) -#endif - - typedef struct { unsigned char* data; unsigned int capacity; @@ -18,40 +8,10 @@ typedef struct { unsigned int element_size; } Stack; -void init_stack(Stack* stack, unsigned int element_size, unsigned int capacity) { - stack->size = 0; - stack->capacity = capacity; - stack->element_size = element_size; - stack->data = (unsigned char*) memalign(0x20, element_size * capacity); -} - -void* stack_top(Stack* stack) { - return &stack->data[(stack->size - 1) * stack->element_size]; -} - -void* stack_replace(Stack* stack, const void* element) { - memcpy(stack->data + ((stack->size - 1) * stack->element_size), element, stack->element_size); - return stack_top(stack); -} - -void* stack_push(Stack* stack, const void* element) { - if(stack->size + 1 == stack->capacity) { - return NULL; - } - - memcpy(stack->data + (stack->size * stack->element_size), element, stack->element_size); - stack->size++; - - return stack_top(stack); -} - -void stack_pop(Stack* stack) { - if(stack->size == 0) { - return; - } - - stack->size--; -} - +void init_stack(Stack* stack, unsigned int element_size, unsigned int capacity); +void* stack_top(Stack* stack); +void* stack_replace(Stack* stack, const void* element); +void* stack_push(Stack* stack, const void* element); +void stack_pop(Stack* stack); #endif // STACK_H