mirror of
https://github.com/zeldaret/af.git
synced 2026-09-28 14:50:04 -04:00
d66a21685f
* git subrepo clone git@github.com:ethteck/splat.git tools/splat subrepo: subdir: "tools/splat" merged: "4fec014" upstream: origin: "git@github.com:ethteck/splat.git" branch: "master" commit: "4fec014" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * gitignore * decompress_baserom.py * Initial yaml * run flib * more yaml stuff * Builds an uncompressed ROM * setup ido download * git subrepo clone git@github.com:simonlindholm/asm-differ.git tools/asm-differ subrepo: subdir: "tools/asm-differ" merged: "ae40866" upstream: origin: "git@github.com:simonlindholm/asm-differ.git" branch: "main" commit: "ae40866" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo clone git@github.com:simonlindholm/asm-processor.git tools/asm-processor subrepo: subdir: "tools/asm-processor" merged: "bbd86ea" upstream: origin: "git@github.com:simonlindholm/asm-processor.git" branch: "main" commit: "bbd86ea" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo clone (merge) git@github.com:EllipticEllipsis/fado.git tools/fado subrepo: subdir: "tools/fado" merged: "8d896ee" upstream: origin: "git@github.com:EllipticEllipsis/fado.git" branch: "master" commit: "8d896ee" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * setup ido in makefile * data and rodata * add automatic file splits * bootstrap most symbol_addrs * git subrepo clone --branch=irix git@github.com:hensldm/ultralib.git lib/ultralib subrepo: subdir: "lib/ultralib" merged: "0d1e095" upstream: origin: "git@github.com:hensldm/ultralib.git" branch: "irix" commit: "0d1e095" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * setup ido building * various tooling * git subrepo pull tools/asm-differ subrepo: subdir: "tools/asm-differ" merged: "857b398" upstream: origin: "git@github.com:simonlindholm/asm-differ.git" branch: "main" commit: "857b398" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * Change defines to match IDO * review * newlin * update gitignore * Windows error * D_01000000 * yeet settings.json * yeet * git subrepo clone git@github.com:decompals/ultralib.git lib/ultralib subrepo: subdir: "lib/ultralib" merged: "d03b2a3" upstream: origin: "git@github.com:decompals/ultralib.git" branch: "main" commit: "d03b2a3" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * clangformat and clangtidy * Setup a bunch of headers * bootstrap boot and code functions and variables headers * global.h * update format.py includes * -D_MIPS_SZLONG=32 * format.py: --verbose * Update tools/decompress_baserom.py Co-authored-by: Derek Hensley <hensley.derek58@gmail.com> * Add libc to global.h * review * yeet saved_regs * yeet headers * yeet _MSC_VER * more header cleanup * add readme licensing note --------- Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
330 lines
8.0 KiB
C
330 lines
8.0 KiB
C
#include "vc_vector.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define GROWTH_FACTOR 1.5
|
|
#define DEFAULT_COUNT_OF_ELEMENTS 8
|
|
#define MINIMUM_COUNT_OF_ELEMENTS 2
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// vc_vector structure
|
|
|
|
struct vc_vector {
|
|
size_t count;
|
|
size_t element_size;
|
|
size_t reserved_size;
|
|
char* data;
|
|
vc_vector_deleter* deleter;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Auxiliary methods
|
|
|
|
bool vc_vector_realloc(vc_vector* vector, size_t new_count) {
|
|
const size_t new_size = new_count * vector->element_size;
|
|
char* new_data = (char*)realloc(vector->data, new_size);
|
|
if (!new_data) {
|
|
return false;
|
|
}
|
|
|
|
vector->reserved_size = new_size;
|
|
vector->data = new_data;
|
|
return true;
|
|
}
|
|
|
|
// [first_index, last_index)
|
|
void vc_vector_call_deleter(vc_vector* vector, size_t first_index, size_t last_index) {
|
|
for (size_t i = first_index; i < last_index; ++i) {
|
|
vector->deleter(vc_vector_at(vector, i));
|
|
}
|
|
}
|
|
|
|
void vc_vector_call_deleter_all(vc_vector* vector) {
|
|
vc_vector_call_deleter(vector, 0, vc_vector_count(vector));
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Control
|
|
|
|
vc_vector* vc_vector_create(size_t count_elements, size_t size_of_element, vc_vector_deleter* deleter) {
|
|
vc_vector* v = (vc_vector*)malloc(sizeof(vc_vector));
|
|
if (v != NULL) {
|
|
v->data = NULL;
|
|
v->count = 0;
|
|
v->element_size = size_of_element;
|
|
v->deleter = deleter;
|
|
|
|
if (count_elements < MINIMUM_COUNT_OF_ELEMENTS) {
|
|
count_elements = DEFAULT_COUNT_OF_ELEMENTS;
|
|
}
|
|
|
|
if (size_of_element < 1 ||
|
|
!vc_vector_realloc(v, count_elements)) {
|
|
free(v);
|
|
v = NULL;
|
|
}
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
vc_vector* vc_vector_create_copy(const vc_vector* vector) {
|
|
vc_vector* new_vector = vc_vector_create(vector->reserved_size / vector->count,
|
|
vector->element_size,
|
|
vector->deleter);
|
|
if (!new_vector) {
|
|
return new_vector;
|
|
}
|
|
|
|
if (memcpy(vector->data,
|
|
new_vector->data,
|
|
new_vector->element_size * vector->count) == NULL) {
|
|
vc_vector_release(new_vector);
|
|
new_vector = NULL;
|
|
return new_vector;
|
|
}
|
|
|
|
new_vector->count = vector->count;
|
|
return new_vector;
|
|
}
|
|
|
|
void vc_vector_release(vc_vector* vector) {
|
|
if (vector->deleter != NULL) {
|
|
vc_vector_call_deleter_all(vector);
|
|
}
|
|
|
|
if (vector->reserved_size != 0) {
|
|
free(vector->data);
|
|
}
|
|
|
|
free(vector);
|
|
}
|
|
|
|
bool vc_vector_is_equals(vc_vector* vector1, vc_vector* vector2) {
|
|
const size_t size_vector1 = vc_vector_size(vector1);
|
|
if (size_vector1 != vc_vector_size(vector2)) {
|
|
return false;
|
|
}
|
|
|
|
return memcmp(vector1->data, vector2->data, size_vector1) == 0;
|
|
}
|
|
|
|
float vc_vector_get_growth_factor(void) {
|
|
return GROWTH_FACTOR;
|
|
}
|
|
|
|
size_t vc_vector_get_default_count_of_elements(void) {
|
|
return DEFAULT_COUNT_OF_ELEMENTS;
|
|
}
|
|
|
|
size_t vc_vector_struct_size(void) {
|
|
return sizeof(vc_vector);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Element access
|
|
|
|
void* vc_vector_at(vc_vector* vector, size_t index) {
|
|
return vector->data + index * vector->element_size;
|
|
}
|
|
|
|
void* vc_vector_front(vc_vector* vector) {
|
|
return vector->data;
|
|
}
|
|
|
|
void* vc_vector_back(vc_vector* vector) {
|
|
return vector->data + (vector->count - 1) * vector->element_size;
|
|
}
|
|
|
|
void* vc_vector_data(vc_vector* vector) {
|
|
return vector->data;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Iterators
|
|
|
|
void* vc_vector_begin(vc_vector* vector) {
|
|
return vector->data;
|
|
}
|
|
|
|
void* vc_vector_end(vc_vector* vector) {
|
|
return vector->data + vector->element_size * vector->count;
|
|
}
|
|
|
|
void* vc_vector_next(vc_vector* vector, void* i) {
|
|
return (char *)i + vector->element_size;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Capacity
|
|
|
|
bool vc_vector_empty(vc_vector* vector) {
|
|
return vector->count == 0;
|
|
}
|
|
|
|
size_t vc_vector_count(const vc_vector* vector) {
|
|
return vector->count;
|
|
}
|
|
|
|
size_t vc_vector_size(const vc_vector* vector) {
|
|
return vector->count * vector->element_size;
|
|
}
|
|
|
|
size_t vc_vector_max_count(const vc_vector* vector) {
|
|
return vector->reserved_size / vector->element_size;
|
|
}
|
|
|
|
size_t vc_vector_max_size(const vc_vector* vector) {
|
|
return vector->reserved_size;
|
|
}
|
|
|
|
bool vc_vector_reserve_count(vc_vector* vector, size_t new_count) {
|
|
if (new_count < vector->count) {
|
|
return false;
|
|
}
|
|
|
|
size_t new_size = vector->element_size * new_count;
|
|
if (new_size == vector->reserved_size) {
|
|
return true;
|
|
}
|
|
|
|
return vc_vector_realloc(vector, new_count);
|
|
}
|
|
|
|
bool vc_vector_reserve_size(vc_vector* vector, size_t new_size) {
|
|
return vc_vector_reserve_count(vector, new_size / vector->element_size);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Modifiers
|
|
|
|
void vc_vector_clear(vc_vector* vector) {
|
|
if (vector->deleter != NULL) {
|
|
vc_vector_call_deleter_all(vector);
|
|
}
|
|
|
|
vector->count = 0;
|
|
}
|
|
|
|
bool vc_vector_insert(vc_vector* vector, size_t index, const void* value) {
|
|
if (vc_vector_max_count(vector) < vector->count + 1) {
|
|
if (!vc_vector_realloc(vector, vc_vector_max_count(vector) * GROWTH_FACTOR)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!memmove(vc_vector_at(vector, index + 1),
|
|
vc_vector_at(vector, index),
|
|
vector->element_size * (vector->count - index))) {
|
|
|
|
return false;
|
|
}
|
|
|
|
if (memcpy(vc_vector_at(vector, index),
|
|
value,
|
|
vector->element_size) == NULL) {
|
|
return false;
|
|
}
|
|
|
|
++vector->count;
|
|
return true;
|
|
}
|
|
|
|
bool vc_vector_erase(vc_vector* vector, size_t index) {
|
|
if (vector->deleter != NULL) {
|
|
vector->deleter(vc_vector_at(vector, index));
|
|
}
|
|
|
|
if (!memmove(vc_vector_at(vector, index),
|
|
vc_vector_at(vector, index + 1),
|
|
vector->element_size * (vector->count - index))) {
|
|
return false;
|
|
}
|
|
|
|
vector->count--;
|
|
return true;
|
|
}
|
|
|
|
bool vc_vector_erase_range(vc_vector* vector, size_t first_index, size_t last_index) {
|
|
if (vector->deleter != NULL) {
|
|
vc_vector_call_deleter(vector, first_index, last_index);
|
|
}
|
|
|
|
if (!memmove(vc_vector_at(vector, first_index),
|
|
vc_vector_at(vector, last_index),
|
|
vector->element_size * (vector->count - last_index))) {
|
|
return false;
|
|
}
|
|
|
|
vector->count -= last_index - first_index;
|
|
return true;
|
|
}
|
|
|
|
bool vc_vector_append(vc_vector* vector, const void* values, size_t count) {
|
|
const size_t count_new = count + vc_vector_count(vector);
|
|
|
|
if (vc_vector_max_count(vector) < count_new) {
|
|
size_t max_count_to_reserved = vc_vector_max_count(vector) * GROWTH_FACTOR;
|
|
while (count_new > max_count_to_reserved) {
|
|
max_count_to_reserved *= GROWTH_FACTOR;
|
|
}
|
|
|
|
if (!vc_vector_realloc(vector, max_count_to_reserved)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (memcpy(vector->data + vector->count * vector->element_size,
|
|
values,
|
|
vector->element_size * count) == NULL) {
|
|
return false;
|
|
}
|
|
|
|
vector->count = count_new;
|
|
return true;
|
|
}
|
|
|
|
bool vc_vector_push_back(vc_vector* vector, const void* value) {
|
|
if (!vc_vector_append(vector, value, 1)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool vc_vector_pop_back(vc_vector* vector) {
|
|
if (vector->deleter != NULL) {
|
|
vector->deleter(vc_vector_back(vector));
|
|
}
|
|
|
|
vector->count--;
|
|
return true;
|
|
}
|
|
|
|
bool vc_vector_replace(vc_vector* vector, size_t index, const void* value) {
|
|
if (vector->deleter != NULL) {
|
|
vector->deleter(vc_vector_at(vector, index));
|
|
}
|
|
|
|
return memcpy(vc_vector_at(vector, index),
|
|
value,
|
|
vector->element_size) != NULL;
|
|
}
|
|
|
|
bool vc_vector_replace_multiple(vc_vector* vector, size_t index, const void* values, size_t count) {
|
|
if (vector->deleter != NULL) {
|
|
vc_vector_call_deleter(vector, index, index + count);
|
|
}
|
|
|
|
return memcpy(vc_vector_at(vector, index),
|
|
values,
|
|
vector->element_size * count) != NULL;
|
|
}
|