Fix the containers to compile on C89 and C99

This commit is contained in:
Luke Benstead 2018-05-26 19:17:42 +01:00
parent 2f014f55b6
commit c363a37e30
9 changed files with 266 additions and 237 deletions

View File

@ -1,4 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <dc/vec3f.h> #include <dc/vec3f.h>
#include "private.h" #include "private.h"

View File

@ -1,3 +1,5 @@
#include <string.h>
#include <dc/matrix.h> #include <dc/matrix.h>
#include "../include/gl.h" #include "../include/gl.h"

View File

@ -7,7 +7,7 @@
TARGET = libGLdc.a 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/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 = SUBDIRS =

107
containers/aligned_vector.c Normal file
View File

@ -0,0 +1,107 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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 "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);
}

View File

@ -1,20 +1,6 @@
#ifndef ALIGNED_VECTOR_H #ifndef ALIGNED_VECTOR_H
#define ALIGNED_VECTOR_H #define ALIGNED_VECTOR_H
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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
#define ALIGNED_VECTOR_INITIAL_CAPACITY 256u
typedef struct { typedef struct {
unsigned int size; unsigned int size;
unsigned int capacity; unsigned int capacity;
@ -22,101 +8,14 @@ typedef struct {
unsigned int element_size; unsigned int element_size;
} AlignedVector; } AlignedVector;
void aligned_vector_init(AlignedVector* vector, unsigned int element_size);
inline void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count); void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count);
inline void aligned_vector_resize(AlignedVector* vector, const 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);
inline void aligned_vector_init(AlignedVector* vector, unsigned int element_size) { void* aligned_vector_at(AlignedVector* vector, const unsigned int index);
vector->size = vector->capacity = 0; void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count);
vector->element_size = element_size; void aligned_vector_clear(AlignedVector* vector);
vector->data = NULL; void aligned_vector_shrink_to_fit(AlignedVector* vector);
void aligned_vector_cleanup(AlignedVector* vector);
/* 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);
}
#endif // ALIGNED_VECTOR_H #endif // ALIGNED_VECTOR_H

89
containers/named_array.c Normal file
View File

@ -0,0 +1,89 @@
#include <stdlib.h>
#include <math.h>
#include <string.h>
#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
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;
}

View File

@ -1,10 +1,6 @@
#ifndef NAMED_ARRAY_H #ifndef NAMED_ARRAY_H
#define NAMED_ARRAY_H #define NAMED_ARRAY_H
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef struct { typedef struct {
unsigned int element_size; unsigned int element_size;
unsigned int max_element_count; unsigned int max_element_count;
@ -13,82 +9,11 @@ typedef struct {
unsigned char marker_count; unsigned char marker_count;
} NamedArray; } NamedArray;
void named_array_init(NamedArray* array, unsigned int element_size, unsigned int max_elements);
inline void named_array_init(NamedArray* array, unsigned int element_size, unsigned int max_elements) { char named_array_used(NamedArray* array, unsigned int id);
array->element_size = element_size; void* named_array_alloc(NamedArray* array, unsigned int* new_id);
array->max_element_count = max_elements; void named_array_release(NamedArray* array, unsigned int new_id);
void* named_array_get(NamedArray* array, unsigned int id);
float c = (float) max_elements / 8.0f; void named_array_cleanup(NamedArray* array);
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;
}
#endif // NAMED_ARRAY_H #endif // NAMED_ARRAY_H

45
containers/stack.c Normal file
View File

@ -0,0 +1,45 @@
#include <string.h>
#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 "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--;
}

View File

@ -1,16 +1,6 @@
#ifndef STACK_H #ifndef STACK_H
#define STACK_H #define STACK_H
#include <string.h>
#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
typedef struct { typedef struct {
unsigned char* data; unsigned char* data;
unsigned int capacity; unsigned int capacity;
@ -18,40 +8,10 @@ typedef struct {
unsigned int element_size; unsigned int element_size;
} Stack; } Stack;
void init_stack(Stack* stack, unsigned int element_size, unsigned int capacity) { void init_stack(Stack* stack, unsigned int element_size, unsigned int capacity);
stack->size = 0; void* stack_top(Stack* stack);
stack->capacity = capacity; void* stack_replace(Stack* stack, const void* element);
stack->element_size = element_size; void* stack_push(Stack* stack, const void* element);
stack->data = (unsigned char*) memalign(0x20, element_size * capacity); void stack_pop(Stack* stack);
}
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--;
}
#endif // STACK_H #endif // STACK_H