use the same allocator everywhere behind pxl8 calls
This commit is contained in:
parent
f18652dc97
commit
fe747969a5
45 changed files with 687 additions and 627 deletions
3
pxl8.sh
3
pxl8.sh
|
|
@ -407,7 +407,8 @@ case "$COMMAND" in
|
||||||
src/sfx/pxl8_sfx.c
|
src/sfx/pxl8_sfx.c
|
||||||
src/script/pxl8_repl.c
|
src/script/pxl8_repl.c
|
||||||
src/script/pxl8_script.c
|
src/script/pxl8_script.c
|
||||||
src/hal/pxl8_sdl3.c
|
src/hal/pxl8_hal_sdl3.c
|
||||||
|
src/hal/pxl8_mem_sdl3.c
|
||||||
src/world/pxl8_bsp.c
|
src/world/pxl8_bsp.c
|
||||||
src/world/pxl8_gen.c
|
src/world/pxl8_gen.c
|
||||||
src/world/pxl8_world.c
|
src/world/pxl8_world.c
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "pxl8_io.h"
|
#include "pxl8_io.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
static pxl8_result parse_ase_header(pxl8_stream* stream, pxl8_ase_header* header) {
|
static pxl8_result parse_ase_header(pxl8_stream* stream, pxl8_ase_header* header) {
|
||||||
header->file_size = pxl8_read_u32(stream);
|
header->file_size = pxl8_read_u32(stream);
|
||||||
|
|
@ -58,7 +59,7 @@ static pxl8_result parse_old_palette_chunk(pxl8_stream* stream, pxl8_ase_palette
|
||||||
palette->entry_count = total_colors;
|
palette->entry_count = total_colors;
|
||||||
palette->first_color = 0;
|
palette->first_color = 0;
|
||||||
palette->last_color = total_colors - 1;
|
palette->last_color = total_colors - 1;
|
||||||
palette->colors = (u32*)malloc(total_colors * sizeof(u32));
|
palette->colors = (u32*)pxl8_malloc(total_colors * sizeof(u32));
|
||||||
if (!palette->colors) {
|
if (!palette->colors) {
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
@ -97,7 +98,7 @@ static pxl8_result parse_layer_chunk(pxl8_stream* stream, pxl8_ase_layer* layer)
|
||||||
|
|
||||||
u16 name_len = pxl8_read_u16(stream);
|
u16 name_len = pxl8_read_u16(stream);
|
||||||
if (name_len > 0) {
|
if (name_len > 0) {
|
||||||
layer->name = (char*)malloc(name_len + 1);
|
layer->name = (char*)pxl8_malloc(name_len + 1);
|
||||||
if (!layer->name) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!layer->name) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
pxl8_read_bytes(stream, layer->name, name_len);
|
pxl8_read_bytes(stream, layer->name, name_len);
|
||||||
layer->name[name_len] = '\0';
|
layer->name[name_len] = '\0';
|
||||||
|
|
@ -120,7 +121,7 @@ static pxl8_result parse_palette_chunk(pxl8_stream* stream, pxl8_ase_palette* pa
|
||||||
return PXL8_ERROR_ASE_MALFORMED_CHUNK;
|
return PXL8_ERROR_ASE_MALFORMED_CHUNK;
|
||||||
}
|
}
|
||||||
|
|
||||||
palette->colors = (u32*)malloc(color_count * sizeof(u32));
|
palette->colors = (u32*)pxl8_malloc(color_count * sizeof(u32));
|
||||||
if (!palette->colors) {
|
if (!palette->colors) {
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
@ -154,7 +155,7 @@ static pxl8_result parse_user_data_chunk(pxl8_stream* stream, pxl8_ase_user_data
|
||||||
if (user_data->has_text) {
|
if (user_data->has_text) {
|
||||||
u16 text_len = pxl8_read_u16(stream);
|
u16 text_len = pxl8_read_u16(stream);
|
||||||
if (text_len > 0) {
|
if (text_len > 0) {
|
||||||
user_data->text = (char*)malloc(text_len + 1);
|
user_data->text = (char*)pxl8_malloc(text_len + 1);
|
||||||
if (!user_data->text) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!user_data->text) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
pxl8_read_bytes(stream, user_data->text, text_len);
|
pxl8_read_bytes(stream, user_data->text, text_len);
|
||||||
user_data->text[text_len] = '\0';
|
user_data->text[text_len] = '\0';
|
||||||
|
|
@ -174,14 +175,14 @@ static pxl8_result parse_user_data_chunk(pxl8_stream* stream, pxl8_ase_user_data
|
||||||
u32 num_properties = pxl8_read_u32(stream);
|
u32 num_properties = pxl8_read_u32(stream);
|
||||||
|
|
||||||
if (num_properties > 0) {
|
if (num_properties > 0) {
|
||||||
user_data->properties = (pxl8_ase_property*)calloc(num_properties, sizeof(pxl8_ase_property));
|
user_data->properties = (pxl8_ase_property*)pxl8_calloc(num_properties, sizeof(pxl8_ase_property));
|
||||||
if (!user_data->properties) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!user_data->properties) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
user_data->property_count = num_properties;
|
user_data->property_count = num_properties;
|
||||||
|
|
||||||
for (u32 i = 0; i < num_properties; i++) {
|
for (u32 i = 0; i < num_properties; i++) {
|
||||||
u16 name_len = pxl8_read_u16(stream);
|
u16 name_len = pxl8_read_u16(stream);
|
||||||
if (name_len > 0) {
|
if (name_len > 0) {
|
||||||
user_data->properties[i].name = (char*)malloc(name_len + 1);
|
user_data->properties[i].name = (char*)pxl8_malloc(name_len + 1);
|
||||||
if (!user_data->properties[i].name) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!user_data->properties[i].name) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
pxl8_read_bytes(stream, user_data->properties[i].name, name_len);
|
pxl8_read_bytes(stream, user_data->properties[i].name, name_len);
|
||||||
user_data->properties[i].name[name_len] = '\0';
|
user_data->properties[i].name[name_len] = '\0';
|
||||||
|
|
@ -207,7 +208,7 @@ static pxl8_result parse_user_data_chunk(pxl8_stream* stream, pxl8_ase_user_data
|
||||||
case 8: {
|
case 8: {
|
||||||
u16 str_len = pxl8_read_u16(stream);
|
u16 str_len = pxl8_read_u16(stream);
|
||||||
if (str_len > 0) {
|
if (str_len > 0) {
|
||||||
user_data->properties[i].string_val = (char*)malloc(str_len + 1);
|
user_data->properties[i].string_val = (char*)pxl8_malloc(str_len + 1);
|
||||||
if (!user_data->properties[i].string_val) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!user_data->properties[i].string_val) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
pxl8_read_bytes(stream, user_data->properties[i].string_val, str_len);
|
pxl8_read_bytes(stream, user_data->properties[i].string_val, str_len);
|
||||||
user_data->properties[i].string_val[str_len] = '\0';
|
user_data->properties[i].string_val[str_len] = '\0';
|
||||||
|
|
@ -236,7 +237,7 @@ static pxl8_result parse_tileset_chunk(pxl8_stream* stream, pxl8_ase_tileset* ti
|
||||||
|
|
||||||
u16 name_len = pxl8_read_u16(stream);
|
u16 name_len = pxl8_read_u16(stream);
|
||||||
if (name_len > 0) {
|
if (name_len > 0) {
|
||||||
tileset->name = (char*)malloc(name_len + 1);
|
tileset->name = (char*)pxl8_malloc(name_len + 1);
|
||||||
if (!tileset->name) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!tileset->name) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
pxl8_read_bytes(stream, tileset->name, name_len);
|
pxl8_read_bytes(stream, tileset->name, name_len);
|
||||||
tileset->name[name_len] = '\0';
|
tileset->name[name_len] = '\0';
|
||||||
|
|
@ -249,7 +250,7 @@ static pxl8_result parse_tileset_chunk(pxl8_stream* stream, pxl8_ase_tileset* ti
|
||||||
if (tileset->flags & 2) {
|
if (tileset->flags & 2) {
|
||||||
u32 compressed_size = pxl8_read_u32(stream);
|
u32 compressed_size = pxl8_read_u32(stream);
|
||||||
tileset->pixels_size = tileset->tile_width * tileset->tile_height * tileset->tile_count;
|
tileset->pixels_size = tileset->tile_width * tileset->tile_height * tileset->tile_count;
|
||||||
tileset->pixels = (u8*)malloc(tileset->pixels_size);
|
tileset->pixels = (u8*)pxl8_malloc(tileset->pixels_size);
|
||||||
if (!tileset->pixels) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!tileset->pixels) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
const u8* compressed_data = pxl8_read_ptr(stream, compressed_size);
|
const u8* compressed_data = pxl8_read_ptr(stream, compressed_size);
|
||||||
|
|
@ -257,13 +258,13 @@ static pxl8_result parse_tileset_chunk(pxl8_stream* stream, pxl8_ase_tileset* ti
|
||||||
i32 result = mz_uncompress(tileset->pixels, &dest_len, compressed_data, compressed_size);
|
i32 result = mz_uncompress(tileset->pixels, &dest_len, compressed_data, compressed_size);
|
||||||
if (result != MZ_OK) {
|
if (result != MZ_OK) {
|
||||||
pxl8_error("Failed to decompress tileset data: miniz error %d", result);
|
pxl8_error("Failed to decompress tileset data: miniz error %d", result);
|
||||||
free(tileset->pixels);
|
pxl8_free(tileset->pixels);
|
||||||
tileset->pixels = NULL;
|
tileset->pixels = NULL;
|
||||||
return PXL8_ERROR_ASE_MALFORMED_CHUNK;
|
return PXL8_ERROR_ASE_MALFORMED_CHUNK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tileset->tile_user_data = (pxl8_ase_user_data*)calloc(tileset->tile_count, sizeof(pxl8_ase_user_data));
|
tileset->tile_user_data = (pxl8_ase_user_data*)pxl8_calloc(tileset->tile_count, sizeof(pxl8_ase_user_data));
|
||||||
if (!tileset->tile_user_data) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!tileset->tile_user_data) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
return PXL8_OK;
|
return PXL8_OK;
|
||||||
|
|
@ -288,7 +289,7 @@ static pxl8_result parse_cel_chunk(pxl8_stream* stream, u32 chunk_size, pxl8_ase
|
||||||
u32 pixels_size = cel->image.width * cel->image.height;
|
u32 pixels_size = cel->image.width * cel->image.height;
|
||||||
u32 compressed_size = chunk_size - 20;
|
u32 compressed_size = chunk_size - 20;
|
||||||
|
|
||||||
cel->image.pixels = (u8*)malloc(pixels_size);
|
cel->image.pixels = (u8*)pxl8_malloc(pixels_size);
|
||||||
if (!cel->image.pixels) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!cel->image.pixels) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
const u8* compressed_data = pxl8_read_ptr(stream, compressed_size);
|
const u8* compressed_data = pxl8_read_ptr(stream, compressed_size);
|
||||||
|
|
@ -296,7 +297,7 @@ static pxl8_result parse_cel_chunk(pxl8_stream* stream, u32 chunk_size, pxl8_ase
|
||||||
i32 result = mz_uncompress(cel->image.pixels, &dest_len, compressed_data, compressed_size);
|
i32 result = mz_uncompress(cel->image.pixels, &dest_len, compressed_data, compressed_size);
|
||||||
if (result != MZ_OK) {
|
if (result != MZ_OK) {
|
||||||
pxl8_error("Failed to decompress cel data: miniz error %d", result);
|
pxl8_error("Failed to decompress cel data: miniz error %d", result);
|
||||||
free(cel->image.pixels);
|
pxl8_free(cel->image.pixels);
|
||||||
cel->image.pixels = NULL;
|
cel->image.pixels = NULL;
|
||||||
return PXL8_ERROR_ASE_MALFORMED_CHUNK;
|
return PXL8_ERROR_ASE_MALFORMED_CHUNK;
|
||||||
}
|
}
|
||||||
|
|
@ -321,7 +322,7 @@ static pxl8_result parse_cel_chunk(pxl8_stream* stream, u32 chunk_size, pxl8_ase
|
||||||
u32 uncompressed_size = tile_count * bytes_per_tile;
|
u32 uncompressed_size = tile_count * bytes_per_tile;
|
||||||
u32 compressed_size = chunk_size - 36;
|
u32 compressed_size = chunk_size - 36;
|
||||||
|
|
||||||
u8* temp_buffer = (u8*)malloc(uncompressed_size);
|
u8* temp_buffer = (u8*)pxl8_malloc(uncompressed_size);
|
||||||
if (!temp_buffer) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!temp_buffer) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
const u8* compressed_data = pxl8_read_ptr(stream, compressed_size);
|
const u8* compressed_data = pxl8_read_ptr(stream, compressed_size);
|
||||||
|
|
@ -329,13 +330,13 @@ static pxl8_result parse_cel_chunk(pxl8_stream* stream, u32 chunk_size, pxl8_ase
|
||||||
i32 result = mz_uncompress(temp_buffer, &dest_len, compressed_data, compressed_size);
|
i32 result = mz_uncompress(temp_buffer, &dest_len, compressed_data, compressed_size);
|
||||||
if (result != MZ_OK) {
|
if (result != MZ_OK) {
|
||||||
pxl8_error("Failed to decompress tilemap data: miniz error %d", result);
|
pxl8_error("Failed to decompress tilemap data: miniz error %d", result);
|
||||||
free(temp_buffer);
|
pxl8_free(temp_buffer);
|
||||||
return PXL8_ERROR_ASE_MALFORMED_CHUNK;
|
return PXL8_ERROR_ASE_MALFORMED_CHUNK;
|
||||||
}
|
}
|
||||||
|
|
||||||
cel->tilemap.tiles = (u32*)calloc(tile_count, sizeof(u32));
|
cel->tilemap.tiles = (u32*)pxl8_calloc(tile_count, sizeof(u32));
|
||||||
if (!cel->tilemap.tiles) {
|
if (!cel->tilemap.tiles) {
|
||||||
free(temp_buffer);
|
pxl8_free(temp_buffer);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -353,7 +354,7 @@ static pxl8_result parse_cel_chunk(pxl8_stream* stream, u32 chunk_size, pxl8_ase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(temp_buffer);
|
pxl8_free(temp_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PXL8_OK;
|
return PXL8_OK;
|
||||||
|
|
@ -367,7 +368,7 @@ pxl8_result pxl8_ase_load(const char* filepath, pxl8_ase_file* ase_file) {
|
||||||
memset(ase_file, 0, sizeof(pxl8_ase_file));
|
memset(ase_file, 0, sizeof(pxl8_ase_file));
|
||||||
|
|
||||||
u8* file_data;
|
u8* file_data;
|
||||||
size_t file_size;
|
usize file_size;
|
||||||
pxl8_result result = pxl8_io_read_binary_file(filepath, &file_data, &file_size);
|
pxl8_result result = pxl8_io_read_binary_file(filepath, &file_data, &file_size);
|
||||||
if (result != PXL8_OK) {
|
if (result != PXL8_OK) {
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -387,7 +388,7 @@ pxl8_result pxl8_ase_load(const char* filepath, pxl8_ase_file* ase_file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ase_file->frame_count = ase_file->header.frames;
|
ase_file->frame_count = ase_file->header.frames;
|
||||||
ase_file->frames = (pxl8_ase_frame*)calloc(ase_file->frame_count, sizeof(pxl8_ase_frame));
|
ase_file->frames = (pxl8_ase_frame*)pxl8_calloc(ase_file->frame_count, sizeof(pxl8_ase_frame));
|
||||||
if (!ase_file->frames) {
|
if (!ase_file->frames) {
|
||||||
pxl8_io_free_binary_data(file_data);
|
pxl8_io_free_binary_data(file_data);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
@ -425,7 +426,7 @@ pxl8_result pxl8_ase_load(const char* filepath, pxl8_ase_file* ase_file) {
|
||||||
frame->duration = frame_header.duration;
|
frame->duration = frame_header.duration;
|
||||||
|
|
||||||
u32 pixel_count = frame->width * frame->height;
|
u32 pixel_count = frame->width * frame->height;
|
||||||
frame->pixels = (u8*)calloc(pixel_count, sizeof(u8));
|
frame->pixels = (u8*)pxl8_calloc(pixel_count, sizeof(u8));
|
||||||
if (!frame->pixels) {
|
if (!frame->pixels) {
|
||||||
result = PXL8_ERROR_OUT_OF_MEMORY;
|
result = PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
break;
|
break;
|
||||||
|
|
@ -457,7 +458,7 @@ pxl8_result pxl8_ase_load(const char* filepath, pxl8_ase_file* ase_file) {
|
||||||
|
|
||||||
case PXL8_ASE_CHUNK_LAYER: {
|
case PXL8_ASE_CHUNK_LAYER: {
|
||||||
pxl8_ase_layer* new_layers =
|
pxl8_ase_layer* new_layers =
|
||||||
(pxl8_ase_layer*)realloc(ase_file->layers,
|
(pxl8_ase_layer*)pxl8_realloc(ase_file->layers,
|
||||||
(ase_file->layer_count + 1) * sizeof(pxl8_ase_layer));
|
(ase_file->layer_count + 1) * sizeof(pxl8_ase_layer));
|
||||||
if (!new_layers) {
|
if (!new_layers) {
|
||||||
result = PXL8_ERROR_OUT_OF_MEMORY;
|
result = PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
@ -476,7 +477,7 @@ pxl8_result pxl8_ase_load(const char* filepath, pxl8_ase_file* ase_file) {
|
||||||
pxl8_ase_cel cel = {0};
|
pxl8_ase_cel cel = {0};
|
||||||
result = parse_cel_chunk(&stream, chunk_header.chunk_size - 6, &cel);
|
result = parse_cel_chunk(&stream, chunk_header.chunk_size - 6, &cel);
|
||||||
if (result == PXL8_OK) {
|
if (result == PXL8_OK) {
|
||||||
pxl8_ase_cel* new_cels = (pxl8_ase_cel*)realloc(frame->cels, (frame->cel_count + 1) * sizeof(pxl8_ase_cel));
|
pxl8_ase_cel* new_cels = (pxl8_ase_cel*)pxl8_realloc(frame->cels, (frame->cel_count + 1) * sizeof(pxl8_ase_cel));
|
||||||
if (!new_cels) {
|
if (!new_cels) {
|
||||||
result = PXL8_ERROR_OUT_OF_MEMORY;
|
result = PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
break;
|
break;
|
||||||
|
|
@ -515,14 +516,14 @@ pxl8_result pxl8_ase_load(const char* filepath, pxl8_ase_file* ase_file) {
|
||||||
|
|
||||||
case PXL8_ASE_CHUNK_PALETTE:
|
case PXL8_ASE_CHUNK_PALETTE:
|
||||||
if (ase_file->palette.colors) {
|
if (ase_file->palette.colors) {
|
||||||
free(ase_file->palette.colors);
|
pxl8_free(ase_file->palette.colors);
|
||||||
ase_file->palette.colors = NULL;
|
ase_file->palette.colors = NULL;
|
||||||
}
|
}
|
||||||
result = parse_palette_chunk(&stream, &ase_file->palette);
|
result = parse_palette_chunk(&stream, &ase_file->palette);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PXL8_ASE_CHUNK_TILESET: {
|
case PXL8_ASE_CHUNK_TILESET: {
|
||||||
pxl8_ase_tileset* new_tilesets = (pxl8_ase_tileset*)realloc(ase_file->tilesets,
|
pxl8_ase_tileset* new_tilesets = (pxl8_ase_tileset*)pxl8_realloc(ase_file->tilesets,
|
||||||
(ase_file->tileset_count + 1) * sizeof(pxl8_ase_tileset));
|
(ase_file->tileset_count + 1) * sizeof(pxl8_ase_tileset));
|
||||||
if (!new_tilesets) {
|
if (!new_tilesets) {
|
||||||
result = PXL8_ERROR_OUT_OF_MEMORY;
|
result = PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
@ -579,57 +580,57 @@ void pxl8_ase_destroy(pxl8_ase_file* ase_file) {
|
||||||
|
|
||||||
if (ase_file->frames) {
|
if (ase_file->frames) {
|
||||||
for (u32 i = 0; i < ase_file->frame_count; i++) {
|
for (u32 i = 0; i < ase_file->frame_count; i++) {
|
||||||
if (ase_file->frames[i].pixels) free(ase_file->frames[i].pixels);
|
if (ase_file->frames[i].pixels) pxl8_free(ase_file->frames[i].pixels);
|
||||||
if (ase_file->frames[i].cels) {
|
if (ase_file->frames[i].cels) {
|
||||||
for (u32 j = 0; j < ase_file->frames[i].cel_count; j++) {
|
for (u32 j = 0; j < ase_file->frames[i].cel_count; j++) {
|
||||||
pxl8_ase_cel* cel = &ase_file->frames[i].cels[j];
|
pxl8_ase_cel* cel = &ase_file->frames[i].cels[j];
|
||||||
if (cel->cel_type == 2 && cel->image.pixels) {
|
if (cel->cel_type == 2 && cel->image.pixels) {
|
||||||
free(cel->image.pixels);
|
pxl8_free(cel->image.pixels);
|
||||||
} else if (cel->cel_type == 3 && cel->tilemap.tiles) {
|
} else if (cel->cel_type == 3 && cel->tilemap.tiles) {
|
||||||
free(cel->tilemap.tiles);
|
pxl8_free(cel->tilemap.tiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(ase_file->frames[i].cels);
|
pxl8_free(ase_file->frames[i].cels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(ase_file->frames);
|
pxl8_free(ase_file->frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ase_file->palette.colors) {
|
if (ase_file->palette.colors) {
|
||||||
free(ase_file->palette.colors);
|
pxl8_free(ase_file->palette.colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ase_file->layers) {
|
if (ase_file->layers) {
|
||||||
for (u32 i = 0; i < ase_file->layer_count; i++) {
|
for (u32 i = 0; i < ase_file->layer_count; i++) {
|
||||||
if (ase_file->layers[i].name) {
|
if (ase_file->layers[i].name) {
|
||||||
free(ase_file->layers[i].name);
|
pxl8_free(ase_file->layers[i].name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(ase_file->layers);
|
pxl8_free(ase_file->layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ase_file->tilesets) {
|
if (ase_file->tilesets) {
|
||||||
for (u32 i = 0; i < ase_file->tileset_count; i++) {
|
for (u32 i = 0; i < ase_file->tileset_count; i++) {
|
||||||
if (ase_file->tilesets[i].name) free(ase_file->tilesets[i].name);
|
if (ase_file->tilesets[i].name) pxl8_free(ase_file->tilesets[i].name);
|
||||||
if (ase_file->tilesets[i].pixels) free(ase_file->tilesets[i].pixels);
|
if (ase_file->tilesets[i].pixels) pxl8_free(ase_file->tilesets[i].pixels);
|
||||||
if (ase_file->tilesets[i].tile_user_data) {
|
if (ase_file->tilesets[i].tile_user_data) {
|
||||||
for (u32 j = 0; j < ase_file->tilesets[i].tile_count; j++) {
|
for (u32 j = 0; j < ase_file->tilesets[i].tile_count; j++) {
|
||||||
pxl8_ase_user_data* ud = &ase_file->tilesets[i].tile_user_data[j];
|
pxl8_ase_user_data* ud = &ase_file->tilesets[i].tile_user_data[j];
|
||||||
if (ud->text) free(ud->text);
|
if (ud->text) pxl8_free(ud->text);
|
||||||
if (ud->properties) {
|
if (ud->properties) {
|
||||||
for (u32 k = 0; k < ud->property_count; k++) {
|
for (u32 k = 0; k < ud->property_count; k++) {
|
||||||
if (ud->properties[k].name) free(ud->properties[k].name);
|
if (ud->properties[k].name) pxl8_free(ud->properties[k].name);
|
||||||
if (ud->properties[k].type == 8 && ud->properties[k].string_val) {
|
if (ud->properties[k].type == 8 && ud->properties[k].string_val) {
|
||||||
free(ud->properties[k].string_val);
|
pxl8_free(ud->properties[k].string_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(ud->properties);
|
pxl8_free(ud->properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(ase_file->tilesets[i].tile_user_data);
|
pxl8_free(ase_file->tilesets[i].tile_user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(ase_file->tilesets);
|
pxl8_free(ase_file->tilesets);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(ase_file, 0, sizeof(pxl8_ase_file));
|
memset(ase_file, 0, sizeof(pxl8_ase_file));
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#define PXL8_CART_MAGIC 0x43585850
|
#define PXL8_CART_MAGIC 0x43585850
|
||||||
#define PXL8_CART_VERSION 1
|
#define PXL8_CART_VERSION 1
|
||||||
|
|
@ -62,7 +63,7 @@ static bool is_directory(const char* path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_pxc_file(const char* path) {
|
static bool is_pxc_file(const char* path) {
|
||||||
size_t len = strlen(path);
|
usize len = strlen(path);
|
||||||
return len > 4 && strcmp(path + len - 4, ".pxc") == 0;
|
return len > 4 && strcmp(path + len - 4, ".pxc") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,7 +98,7 @@ static void collect_files_recursive(const char* dir_path, const char* prefix,
|
||||||
} else {
|
} else {
|
||||||
if (*count >= *capacity) {
|
if (*count >= *capacity) {
|
||||||
*capacity = (*capacity == 0) ? 64 : (*capacity * 2);
|
*capacity = (*capacity == 0) ? 64 : (*capacity * 2);
|
||||||
*paths = realloc(*paths, *capacity * sizeof(char*));
|
*paths = pxl8_realloc(*paths, *capacity * sizeof(char*));
|
||||||
}
|
}
|
||||||
(*paths)[(*count)++] = strdup(rel_path);
|
(*paths)[(*count)++] = strdup(rel_path);
|
||||||
}
|
}
|
||||||
|
|
@ -123,13 +124,13 @@ static pxl8_result load_packed_cart(pxl8_cart* cart, const u8* data, u32 size) {
|
||||||
if (header->magic != PXL8_CART_MAGIC) return PXL8_ERROR_INVALID_FORMAT;
|
if (header->magic != PXL8_CART_MAGIC) return PXL8_ERROR_INVALID_FORMAT;
|
||||||
if (header->version > PXL8_CART_VERSION) return PXL8_ERROR_INVALID_FORMAT;
|
if (header->version > PXL8_CART_VERSION) return PXL8_ERROR_INVALID_FORMAT;
|
||||||
|
|
||||||
cart->data = malloc(size);
|
cart->data = pxl8_malloc(size);
|
||||||
if (!cart->data) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!cart->data) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
memcpy(cart->data, data, size);
|
memcpy(cart->data, data, size);
|
||||||
cart->data_size = size;
|
cart->data_size = size;
|
||||||
|
|
||||||
cart->file_count = header->file_count;
|
cart->file_count = header->file_count;
|
||||||
cart->files = calloc(cart->file_count, sizeof(pxl8_cart_file));
|
cart->files = pxl8_calloc(cart->file_count, sizeof(pxl8_cart_file));
|
||||||
if (!cart->files) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!cart->files) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
const u8* toc = cart->data + sizeof(pxl8_cart_header);
|
const u8* toc = cart->data + sizeof(pxl8_cart_header);
|
||||||
|
|
@ -137,7 +138,7 @@ static pxl8_result load_packed_cart(pxl8_cart* cart, const u8* data, u32 size) {
|
||||||
const pxl8_cart_entry* entry = (const pxl8_cart_entry*)toc;
|
const pxl8_cart_entry* entry = (const pxl8_cart_entry*)toc;
|
||||||
toc += sizeof(pxl8_cart_entry);
|
toc += sizeof(pxl8_cart_entry);
|
||||||
|
|
||||||
cart->files[i].path = malloc(entry->path_len + 1);
|
cart->files[i].path = pxl8_malloc(entry->path_len + 1);
|
||||||
memcpy(cart->files[i].path, toc, entry->path_len);
|
memcpy(cart->files[i].path, toc, entry->path_len);
|
||||||
cart->files[i].path[entry->path_len] = '\0';
|
cart->files[i].path[entry->path_len] = '\0';
|
||||||
toc += entry->path_len;
|
toc += entry->path_len;
|
||||||
|
|
@ -151,7 +152,7 @@ static pxl8_result load_packed_cart(pxl8_cart* cart, const u8* data, u32 size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_cart* pxl8_cart_create(void) {
|
pxl8_cart* pxl8_cart_create(void) {
|
||||||
pxl8_cart* cart = calloc(1, sizeof(pxl8_cart));
|
pxl8_cart* cart = pxl8_calloc(1, sizeof(pxl8_cart));
|
||||||
if (cart) {
|
if (cart) {
|
||||||
cart->resolution = PXL8_RESOLUTION_640x360;
|
cart->resolution = PXL8_RESOLUTION_640x360;
|
||||||
cart->window_size = (pxl8_size){1280, 720};
|
cart->window_size = (pxl8_size){1280, 720};
|
||||||
|
|
@ -167,7 +168,7 @@ pxl8_cart* pxl8_get_cart(void) {
|
||||||
void pxl8_cart_destroy(pxl8_cart* cart) {
|
void pxl8_cart_destroy(pxl8_cart* cart) {
|
||||||
if (!cart) return;
|
if (!cart) return;
|
||||||
pxl8_cart_unload(cart);
|
pxl8_cart_unload(cart);
|
||||||
free(cart);
|
pxl8_free(cart);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_cart_load(pxl8_cart* cart, const char* path) {
|
pxl8_result pxl8_cart_load(pxl8_cart* cart, const char* path) {
|
||||||
|
|
@ -202,16 +203,16 @@ pxl8_result pxl8_cart_load(pxl8_cart* cart, const char* path) {
|
||||||
u32 size = (u32)ftell(file);
|
u32 size = (u32)ftell(file);
|
||||||
fseek(file, 0, SEEK_SET);
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
u8* data = malloc(size);
|
u8* data = pxl8_malloc(size);
|
||||||
if (!data || fread(data, 1, size, file) != size) {
|
if (!data || fread(data, 1, size, file) != size) {
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
pxl8_result result = load_packed_cart(cart, data, size);
|
pxl8_result result = load_packed_cart(cart, data, size);
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
|
|
||||||
if (result == PXL8_OK) {
|
if (result == PXL8_OK) {
|
||||||
pxl8_info("Loaded cart");
|
pxl8_info("Loaded cart");
|
||||||
|
|
@ -242,16 +243,16 @@ pxl8_result pxl8_cart_load_embedded(pxl8_cart* cart, const char* exe_path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(file, trailer.cart_offset, SEEK_SET);
|
fseek(file, trailer.cart_offset, SEEK_SET);
|
||||||
u8* data = malloc(trailer.cart_size);
|
u8* data = pxl8_malloc(trailer.cart_size);
|
||||||
if (!data || fread(data, 1, trailer.cart_size, file) != trailer.cart_size) {
|
if (!data || fread(data, 1, trailer.cart_size, file) != trailer.cart_size) {
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
pxl8_result result = load_packed_cart(cart, data, trailer.cart_size);
|
pxl8_result result = load_packed_cart(cart, data, trailer.cart_size);
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
|
|
||||||
if (result == PXL8_OK) {
|
if (result == PXL8_OK) {
|
||||||
pxl8_info("Loaded embedded cart");
|
pxl8_info("Loaded embedded cart");
|
||||||
|
|
@ -265,7 +266,7 @@ void pxl8_cart_unload(pxl8_cart* cart) {
|
||||||
if (cart->title) {
|
if (cart->title) {
|
||||||
pxl8_info("Unloaded cart: %s", cart->title);
|
pxl8_info("Unloaded cart: %s", cart->title);
|
||||||
pxl8_cart_unmount(cart);
|
pxl8_cart_unmount(cart);
|
||||||
free(cart->title);
|
pxl8_free(cart->title);
|
||||||
cart->title = NULL;
|
cart->title = NULL;
|
||||||
} else if (cart->base_path || cart->data) {
|
} else if (cart->base_path || cart->data) {
|
||||||
pxl8_info("Unloaded cart");
|
pxl8_info("Unloaded cart");
|
||||||
|
|
@ -274,18 +275,18 @@ void pxl8_cart_unload(pxl8_cart* cart) {
|
||||||
|
|
||||||
if (cart->files) {
|
if (cart->files) {
|
||||||
for (u32 i = 0; i < cart->file_count; i++) {
|
for (u32 i = 0; i < cart->file_count; i++) {
|
||||||
free(cart->files[i].path);
|
pxl8_free(cart->files[i].path);
|
||||||
}
|
}
|
||||||
free(cart->files);
|
pxl8_free(cart->files);
|
||||||
cart->files = NULL;
|
cart->files = NULL;
|
||||||
}
|
}
|
||||||
cart->file_count = 0;
|
cart->file_count = 0;
|
||||||
|
|
||||||
free(cart->data);
|
pxl8_free(cart->data);
|
||||||
cart->data = NULL;
|
cart->data = NULL;
|
||||||
cart->data_size = 0;
|
cart->data_size = 0;
|
||||||
|
|
||||||
free(cart->base_path);
|
pxl8_free(cart->base_path);
|
||||||
cart->base_path = NULL;
|
cart->base_path = NULL;
|
||||||
cart->is_folder = false;
|
cart->is_folder = false;
|
||||||
}
|
}
|
||||||
|
|
@ -302,7 +303,7 @@ pxl8_result pxl8_cart_mount(pxl8_cart* cart) {
|
||||||
pxl8_original_cwd = getcwd(NULL, 0);
|
pxl8_original_cwd = getcwd(NULL, 0);
|
||||||
if (chdir(cart->base_path) != 0) {
|
if (chdir(cart->base_path) != 0) {
|
||||||
pxl8_error("Failed to change to cart directory: %s", cart->base_path);
|
pxl8_error("Failed to change to cart directory: %s", cart->base_path);
|
||||||
free(pxl8_original_cwd);
|
pxl8_free(pxl8_original_cwd);
|
||||||
pxl8_original_cwd = NULL;
|
pxl8_original_cwd = NULL;
|
||||||
return PXL8_ERROR_FILE_NOT_FOUND;
|
return PXL8_ERROR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
@ -323,7 +324,7 @@ void pxl8_cart_unmount(pxl8_cart* cart) {
|
||||||
|
|
||||||
if (pxl8_original_cwd) {
|
if (pxl8_original_cwd) {
|
||||||
chdir(pxl8_original_cwd);
|
chdir(pxl8_original_cwd);
|
||||||
free(pxl8_original_cwd);
|
pxl8_free(pxl8_original_cwd);
|
||||||
pxl8_original_cwd = NULL;
|
pxl8_original_cwd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -343,7 +344,7 @@ const char* pxl8_cart_get_title(const pxl8_cart* cart) {
|
||||||
|
|
||||||
void pxl8_cart_set_title(pxl8_cart* cart, const char* title) {
|
void pxl8_cart_set_title(pxl8_cart* cart, const char* title) {
|
||||||
if (!cart || !title) return;
|
if (!cart || !title) return;
|
||||||
free(cart->title);
|
pxl8_free(cart->title);
|
||||||
cart->title = strdup(title);
|
cart->title = strdup(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -399,16 +400,16 @@ bool pxl8_cart_file_exists(const pxl8_cart* cart, const char* path) {
|
||||||
return find_file(cart, path) != NULL;
|
return find_file(cart, path) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pxl8_cart_resolve_path(const pxl8_cart* cart, const char* relative_path, char* out_path, size_t out_size) {
|
bool pxl8_cart_resolve_path(const pxl8_cart* cart, const char* relative_path, char* out_path, usize out_size) {
|
||||||
if (!cart || !relative_path || !out_path || out_size == 0) return false;
|
if (!cart || !relative_path || !out_path || out_size == 0) return false;
|
||||||
|
|
||||||
if (cart->is_folder && cart->base_path) {
|
if (cart->is_folder && cart->base_path) {
|
||||||
i32 written = snprintf(out_path, out_size, "%s/%s", cart->base_path, relative_path);
|
i32 written = snprintf(out_path, out_size, "%s/%s", cart->base_path, relative_path);
|
||||||
return written >= 0 && (size_t)written < out_size;
|
return written >= 0 && (usize)written < out_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 written = snprintf(out_path, out_size, "%s", relative_path);
|
i32 written = snprintf(out_path, out_size, "%s", relative_path);
|
||||||
return written >= 0 && (size_t)written < out_size;
|
return written >= 0 && (usize)written < out_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_cart_read_file(const pxl8_cart* cart, const char* path, u8** data_out, u32* size_out) {
|
pxl8_result pxl8_cart_read_file(const pxl8_cart* cart, const char* path, u8** data_out, u32* size_out) {
|
||||||
|
|
@ -427,9 +428,9 @@ pxl8_result pxl8_cart_read_file(const pxl8_cart* cart, const char* path, u8** da
|
||||||
*size_out = (u32)ftell(file);
|
*size_out = (u32)ftell(file);
|
||||||
fseek(file, 0, SEEK_SET);
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
*data_out = malloc(*size_out);
|
*data_out = pxl8_malloc(*size_out);
|
||||||
if (!*data_out || fread(*data_out, 1, *size_out, file) != *size_out) {
|
if (!*data_out || fread(*data_out, 1, *size_out, file) != *size_out) {
|
||||||
free(*data_out);
|
pxl8_free(*data_out);
|
||||||
*data_out = NULL;
|
*data_out = NULL;
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||||
|
|
@ -442,7 +443,7 @@ pxl8_result pxl8_cart_read_file(const pxl8_cart* cart, const char* path, u8** da
|
||||||
if (!cf) return PXL8_ERROR_FILE_NOT_FOUND;
|
if (!cf) return PXL8_ERROR_FILE_NOT_FOUND;
|
||||||
|
|
||||||
*size_out = cf->size;
|
*size_out = cf->size;
|
||||||
*data_out = malloc(cf->size);
|
*data_out = pxl8_malloc(cf->size);
|
||||||
if (!*data_out) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!*data_out) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
memcpy(*data_out, cart->data + cf->offset, cf->size);
|
memcpy(*data_out, cart->data + cf->offset, cf->size);
|
||||||
|
|
@ -450,7 +451,7 @@ pxl8_result pxl8_cart_read_file(const pxl8_cart* cart, const char* path, u8** da
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_cart_free_file(u8* data) {
|
void pxl8_cart_free_file(u8* data) {
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_cart_pack(const char* folder_path, const char* output_path) {
|
pxl8_result pxl8_cart_pack(const char* folder_path, const char* output_path) {
|
||||||
|
|
@ -483,7 +484,7 @@ pxl8_result pxl8_cart_pack(const char* folder_path, const char* output_path) {
|
||||||
u32 data_offset = sizeof(pxl8_cart_header) + toc_size;
|
u32 data_offset = sizeof(pxl8_cart_header) + toc_size;
|
||||||
u32 total_size = data_offset;
|
u32 total_size = data_offset;
|
||||||
|
|
||||||
u32* file_sizes = malloc(count * sizeof(u32));
|
u32* file_sizes = pxl8_malloc(count * sizeof(u32));
|
||||||
for (u32 i = 0; i < count; i++) {
|
for (u32 i = 0; i < count; i++) {
|
||||||
char full_path[1024];
|
char full_path[1024];
|
||||||
snprintf(full_path, sizeof(full_path), "%s/%s", folder_path, paths[i]);
|
snprintf(full_path, sizeof(full_path), "%s/%s", folder_path, paths[i]);
|
||||||
|
|
@ -496,11 +497,11 @@ pxl8_result pxl8_cart_pack(const char* folder_path, const char* output_path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* buffer = calloc(1, total_size);
|
u8* buffer = pxl8_calloc(1, total_size);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
free(file_sizes);
|
pxl8_free(file_sizes);
|
||||||
for (u32 i = 0; i < count; i++) free(paths[i]);
|
for (u32 i = 0; i < count; i++) pxl8_free(paths[i]);
|
||||||
free(paths);
|
pxl8_free(paths);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -536,20 +537,20 @@ pxl8_result pxl8_cart_pack(const char* folder_path, const char* output_path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
file_offset += file_sizes[i];
|
file_offset += file_sizes[i];
|
||||||
free(paths[i]);
|
pxl8_free(paths[i]);
|
||||||
}
|
}
|
||||||
free(paths);
|
pxl8_free(paths);
|
||||||
free(file_sizes);
|
pxl8_free(file_sizes);
|
||||||
|
|
||||||
FILE* out = fopen(output_path, "wb");
|
FILE* out = fopen(output_path, "wb");
|
||||||
if (!out) {
|
if (!out) {
|
||||||
free(buffer);
|
pxl8_free(buffer);
|
||||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(buffer, 1, total_size, out);
|
fwrite(buffer, 1, total_size, out);
|
||||||
fclose(out);
|
fclose(out);
|
||||||
free(buffer);
|
pxl8_free(buffer);
|
||||||
|
|
||||||
pxl8_info("Cart packed: %u files, %u bytes", count, total_size);
|
pxl8_info("Cart packed: %u files, %u bytes", count, total_size);
|
||||||
return PXL8_OK;
|
return PXL8_OK;
|
||||||
|
|
@ -573,7 +574,7 @@ pxl8_result pxl8_cart_bundle(const char* input_path, const char* output_path, co
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
cart_size = (u32)ftell(f);
|
cart_size = (u32)ftell(f);
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
cart_data = malloc(cart_size);
|
cart_data = pxl8_malloc(cart_size);
|
||||||
fread(cart_data, 1, cart_size, f);
|
fread(cart_data, 1, cart_size, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
unlink(temp_pxc);
|
unlink(temp_pxc);
|
||||||
|
|
@ -584,7 +585,7 @@ pxl8_result pxl8_cart_bundle(const char* input_path, const char* output_path, co
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
cart_size = (u32)ftell(f);
|
cart_size = (u32)ftell(f);
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
cart_data = malloc(cart_size);
|
cart_data = pxl8_malloc(cart_size);
|
||||||
fread(cart_data, 1, cart_size, f);
|
fread(cart_data, 1, cart_size, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free_cart = true;
|
free_cart = true;
|
||||||
|
|
@ -594,30 +595,30 @@ pxl8_result pxl8_cart_bundle(const char* input_path, const char* output_path, co
|
||||||
|
|
||||||
FILE* exe = fopen(exe_path, "rb");
|
FILE* exe = fopen(exe_path, "rb");
|
||||||
if (!exe) {
|
if (!exe) {
|
||||||
if (free_cart) free(cart_data);
|
if (free_cart) pxl8_free(cart_data);
|
||||||
return PXL8_ERROR_FILE_NOT_FOUND;
|
return PXL8_ERROR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
fseek(exe, 0, SEEK_END);
|
fseek(exe, 0, SEEK_END);
|
||||||
u32 exe_size = (u32)ftell(exe);
|
u32 exe_size = (u32)ftell(exe);
|
||||||
fseek(exe, 0, SEEK_SET);
|
fseek(exe, 0, SEEK_SET);
|
||||||
|
|
||||||
u8* exe_data = malloc(exe_size);
|
u8* exe_data = pxl8_malloc(exe_size);
|
||||||
fread(exe_data, 1, exe_size, exe);
|
fread(exe_data, 1, exe_size, exe);
|
||||||
fclose(exe);
|
fclose(exe);
|
||||||
|
|
||||||
FILE* out = fopen(output_path, "wb");
|
FILE* out = fopen(output_path, "wb");
|
||||||
if (!out) {
|
if (!out) {
|
||||||
free(exe_data);
|
pxl8_free(exe_data);
|
||||||
if (free_cart) free(cart_data);
|
if (free_cart) pxl8_free(cart_data);
|
||||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(exe_data, 1, exe_size, out);
|
fwrite(exe_data, 1, exe_size, out);
|
||||||
free(exe_data);
|
pxl8_free(exe_data);
|
||||||
|
|
||||||
u32 cart_offset = exe_size;
|
u32 cart_offset = exe_size;
|
||||||
fwrite(cart_data, 1, cart_size, out);
|
fwrite(cart_data, 1, cart_size, out);
|
||||||
if (free_cart) free(cart_data);
|
if (free_cart) pxl8_free(cart_data);
|
||||||
|
|
||||||
pxl8_cart_trailer trailer = {
|
pxl8_cart_trailer trailer = {
|
||||||
.magic = PXL8_CART_TRAILER_MAGIC,
|
.magic = PXL8_CART_TRAILER_MAGIC,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ bool pxl8_cart_is_packed(const pxl8_cart* cart);
|
||||||
bool pxl8_cart_has_embedded(const char* exe_path);
|
bool pxl8_cart_has_embedded(const char* exe_path);
|
||||||
|
|
||||||
bool pxl8_cart_file_exists(const pxl8_cart* cart, const char* path);
|
bool pxl8_cart_file_exists(const pxl8_cart* cart, const char* path);
|
||||||
bool pxl8_cart_resolve_path(const pxl8_cart* cart, const char* relative_path, char* out_path, size_t out_size);
|
bool pxl8_cart_resolve_path(const pxl8_cart* cart, const char* relative_path, char* out_path, usize out_size);
|
||||||
pxl8_result pxl8_cart_read_file(const pxl8_cart* cart, const char* path, u8** data_out, u32* size_out);
|
pxl8_result pxl8_cart_read_file(const pxl8_cart* cart, const char* path, u8** data_out, u32* size_out);
|
||||||
void pxl8_cart_free_file(u8* data);
|
void pxl8_cart_free_file(u8* data);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 magic;
|
u32 magic;
|
||||||
|
|
@ -40,7 +41,7 @@ static u32 pxl8_save_checksum(const u8* data, u32 size) {
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pxl8_save_get_slot_path(pxl8_save* save, u8 slot, char* path, size_t path_size) {
|
static void pxl8_save_get_slot_path(pxl8_save* save, u8 slot, char* path, usize path_size) {
|
||||||
if (slot == PXL8_SAVE_HOTRELOAD_SLOT) {
|
if (slot == PXL8_SAVE_HOTRELOAD_SLOT) {
|
||||||
snprintf(path, path_size, "%s%chotreload.sav", save->directory, PATH_SEP);
|
snprintf(path, path_size, "%s%chotreload.sav", save->directory, PATH_SEP);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -68,7 +69,7 @@ static pxl8_result pxl8_save_ensure_directory(const char* path) {
|
||||||
pxl8_save* pxl8_save_create(const char* game_name, u32 magic, u32 version) {
|
pxl8_save* pxl8_save_create(const char* game_name, u32 magic, u32 version) {
|
||||||
if (!game_name) return NULL;
|
if (!game_name) return NULL;
|
||||||
|
|
||||||
pxl8_save* save = (pxl8_save*)calloc(1, sizeof(pxl8_save));
|
pxl8_save* save = (pxl8_save*)pxl8_calloc(1, sizeof(pxl8_save));
|
||||||
if (!save) return NULL;
|
if (!save) return NULL;
|
||||||
|
|
||||||
save->magic = magic;
|
save->magic = magic;
|
||||||
|
|
@ -81,7 +82,7 @@ pxl8_save* pxl8_save_create(const char* game_name, u32 magic, u32 version) {
|
||||||
snprintf(save->directory, sizeof(save->directory),
|
snprintf(save->directory, sizeof(save->directory),
|
||||||
"%s%cpxl8%c%s", base_dir, PATH_SEP, PATH_SEP, game_name);
|
"%s%cpxl8%c%s", base_dir, PATH_SEP, PATH_SEP, game_name);
|
||||||
} else {
|
} else {
|
||||||
free(save);
|
pxl8_free(save);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
@ -91,7 +92,7 @@ pxl8_save* pxl8_save_create(const char* game_name, u32 magic, u32 version) {
|
||||||
if (pw) home = pw->pw_dir;
|
if (pw) home = pw->pw_dir;
|
||||||
}
|
}
|
||||||
if (!home) {
|
if (!home) {
|
||||||
free(save);
|
pxl8_free(save);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,7 +107,7 @@ pxl8_save* pxl8_save_create(const char* game_name, u32 magic, u32 version) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pxl8_save_ensure_directory(save->directory) != PXL8_OK) {
|
if (pxl8_save_ensure_directory(save->directory) != PXL8_OK) {
|
||||||
free(save);
|
pxl8_free(save);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +117,7 @@ pxl8_save* pxl8_save_create(const char* game_name, u32 magic, u32 version) {
|
||||||
|
|
||||||
void pxl8_save_destroy(pxl8_save* save) {
|
void pxl8_save_destroy(pxl8_save* save) {
|
||||||
if (save) {
|
if (save) {
|
||||||
free(save);
|
pxl8_free(save);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,14 +200,14 @@ pxl8_result pxl8_save_read(pxl8_save* save, u8 slot, u8** data_out, u32* size_ou
|
||||||
return PXL8_ERROR_INVALID_FORMAT;
|
return PXL8_ERROR_INVALID_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* data = (u8*)malloc(header.size);
|
u8* data = (u8*)pxl8_malloc(header.size);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fread(data, 1, header.size, file) != header.size) {
|
if (fread(data, 1, header.size, file) != header.size) {
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
@ -215,7 +216,7 @@ pxl8_result pxl8_save_read(pxl8_save* save, u8 slot, u8** data_out, u32* size_ou
|
||||||
|
|
||||||
u32 checksum = pxl8_save_checksum(data, header.size);
|
u32 checksum = pxl8_save_checksum(data, header.size);
|
||||||
if (checksum != header.checksum) {
|
if (checksum != header.checksum) {
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
pxl8_error("Save file checksum mismatch");
|
pxl8_error("Save file checksum mismatch");
|
||||||
return PXL8_ERROR_INVALID_FORMAT;
|
return PXL8_ERROR_INVALID_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
@ -234,7 +235,7 @@ pxl8_result pxl8_save_read(pxl8_save* save, u8 slot, u8** data_out, u32* size_ou
|
||||||
|
|
||||||
void pxl8_save_free(u8* data) {
|
void pxl8_save_free(u8* data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "pxl8_hal.h"
|
#include "pxl8_hal.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
#include "pxl8_macros.h"
|
#include "pxl8_macros.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
#include "pxl8_repl.h"
|
#include "pxl8_repl.h"
|
||||||
#include "pxl8_replay.h"
|
#include "pxl8_replay.h"
|
||||||
#include "pxl8_script.h"
|
#include "pxl8_script.h"
|
||||||
|
|
@ -38,23 +39,23 @@ static void pxl8_audio_event_callback(u8 event_type, u8 context_id, u8 note, f32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pxl8* pxl8_create(const pxl8_hal* hal) {
|
pxl8* pxl8_create(const pxl8_hal* hal) {
|
||||||
pxl8* sys = (pxl8*)calloc(1, sizeof(pxl8));
|
pxl8* sys = (pxl8*)pxl8_calloc(1, sizeof(pxl8));
|
||||||
if (!sys) return NULL;
|
if (!sys) return NULL;
|
||||||
|
|
||||||
pxl8_log_init(&sys->log);
|
pxl8_log_init(&sys->log);
|
||||||
|
|
||||||
if (!hal) {
|
if (!hal) {
|
||||||
pxl8_error("hal cannot be null");
|
pxl8_error("hal cannot be null");
|
||||||
free(sys);
|
pxl8_free(sys);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sys->hal = hal;
|
sys->hal = hal;
|
||||||
|
|
||||||
sys->game = (pxl8_game*)calloc(1, sizeof(pxl8_game));
|
sys->game = (pxl8_game*)pxl8_calloc(1, sizeof(pxl8_game));
|
||||||
if (!sys->game) {
|
if (!sys->game) {
|
||||||
pxl8_error("failed to allocate game");
|
pxl8_error("failed to allocate game");
|
||||||
free(sys);
|
pxl8_free(sys);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,11 +65,11 @@ pxl8* pxl8_create(const pxl8_hal* hal) {
|
||||||
void pxl8_destroy(pxl8* sys) {
|
void pxl8_destroy(pxl8* sys) {
|
||||||
if (!sys) return;
|
if (!sys) return;
|
||||||
|
|
||||||
if (sys->game) free(sys->game);
|
if (sys->game) pxl8_free(sys->game);
|
||||||
if (sys->cart) pxl8_cart_destroy(sys->cart);
|
if (sys->cart) pxl8_cart_destroy(sys->cart);
|
||||||
if (sys->hal && sys->platform_data) sys->hal->destroy(sys->platform_data);
|
if (sys->hal && sys->platform_data) sys->hal->destroy(sys->platform_data);
|
||||||
|
|
||||||
free(sys);
|
pxl8_free(sys);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pxl8_print_help(void) {
|
static void pxl8_print_help(void) {
|
||||||
|
|
@ -170,7 +171,7 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
|
||||||
cart_path = ".";
|
cart_path = ".";
|
||||||
} else {
|
} else {
|
||||||
pxl8_error("no main.fnl or main.lua found in current directory");
|
pxl8_error("no main.fnl or main.lua found in current directory");
|
||||||
free(original_cwd);
|
pxl8_free(original_cwd);
|
||||||
return PXL8_ERROR_INITIALIZATION_FAILED;
|
return PXL8_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -189,7 +190,7 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
|
||||||
pxl8_error("failed to load cart%s%s", load_from_path ? ": " : "", load_from_path ? cart_path : "");
|
pxl8_error("failed to load cart%s%s", load_from_path ? ": " : "", load_from_path ? cart_path : "");
|
||||||
if (sys->cart) pxl8_cart_destroy(sys->cart);
|
if (sys->cart) pxl8_cart_destroy(sys->cart);
|
||||||
sys->cart = NULL;
|
sys->cart = NULL;
|
||||||
free(original_cwd);
|
pxl8_free(original_cwd);
|
||||||
return PXL8_ERROR_INITIALIZATION_FAILED;
|
return PXL8_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,7 +203,7 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
|
||||||
} else if (script_arg) {
|
} else if (script_arg) {
|
||||||
pxl8_strncpy(game->script_path, script_arg, sizeof(game->script_path));
|
pxl8_strncpy(game->script_path, script_arg, sizeof(game->script_path));
|
||||||
}
|
}
|
||||||
free(original_cwd);
|
pxl8_free(original_cwd);
|
||||||
|
|
||||||
const char* window_title = pxl8_cart_get_title(sys->cart);
|
const char* window_title = pxl8_cart_get_title(sys->cart);
|
||||||
if (!window_title) window_title = "pxl8";
|
if (!window_title) window_title = "pxl8";
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,35 @@
|
||||||
#include "pxl8_bytes.h"
|
#include "pxl8_bytes.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void pxl8_pack_u8(u8* buf, size_t offset, u8 val) {
|
void pxl8_pack_u8(u8* buf, usize offset, u8 val) {
|
||||||
buf[offset] = val;
|
buf[offset] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_u16_le(u8* buf, size_t offset, u16 val) {
|
void pxl8_pack_u16_le(u8* buf, usize offset, u16 val) {
|
||||||
buf[offset] = (u8)(val);
|
buf[offset] = (u8)(val);
|
||||||
buf[offset + 1] = (u8)(val >> 8);
|
buf[offset + 1] = (u8)(val >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_u16_be(u8* buf, size_t offset, u16 val) {
|
void pxl8_pack_u16_be(u8* buf, usize offset, u16 val) {
|
||||||
buf[offset] = (u8)(val >> 8);
|
buf[offset] = (u8)(val >> 8);
|
||||||
buf[offset + 1] = (u8)(val);
|
buf[offset + 1] = (u8)(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_u32_le(u8* buf, size_t offset, u32 val) {
|
void pxl8_pack_u32_le(u8* buf, usize offset, u32 val) {
|
||||||
buf[offset] = (u8)(val);
|
buf[offset] = (u8)(val);
|
||||||
buf[offset + 1] = (u8)(val >> 8);
|
buf[offset + 1] = (u8)(val >> 8);
|
||||||
buf[offset + 2] = (u8)(val >> 16);
|
buf[offset + 2] = (u8)(val >> 16);
|
||||||
buf[offset + 3] = (u8)(val >> 24);
|
buf[offset + 3] = (u8)(val >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_u32_be(u8* buf, size_t offset, u32 val) {
|
void pxl8_pack_u32_be(u8* buf, usize offset, u32 val) {
|
||||||
buf[offset] = (u8)(val >> 24);
|
buf[offset] = (u8)(val >> 24);
|
||||||
buf[offset + 1] = (u8)(val >> 16);
|
buf[offset + 1] = (u8)(val >> 16);
|
||||||
buf[offset + 2] = (u8)(val >> 8);
|
buf[offset + 2] = (u8)(val >> 8);
|
||||||
buf[offset + 3] = (u8)(val);
|
buf[offset + 3] = (u8)(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_u64_le(u8* buf, size_t offset, u64 val) {
|
void pxl8_pack_u64_le(u8* buf, usize offset, u64 val) {
|
||||||
buf[offset] = (u8)(val);
|
buf[offset] = (u8)(val);
|
||||||
buf[offset + 1] = (u8)(val >> 8);
|
buf[offset + 1] = (u8)(val >> 8);
|
||||||
buf[offset + 2] = (u8)(val >> 16);
|
buf[offset + 2] = (u8)(val >> 16);
|
||||||
|
|
@ -40,7 +40,7 @@ void pxl8_pack_u64_le(u8* buf, size_t offset, u64 val) {
|
||||||
buf[offset + 7] = (u8)(val >> 56);
|
buf[offset + 7] = (u8)(val >> 56);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_u64_be(u8* buf, size_t offset, u64 val) {
|
void pxl8_pack_u64_be(u8* buf, usize offset, u64 val) {
|
||||||
buf[offset] = (u8)(val >> 56);
|
buf[offset] = (u8)(val >> 56);
|
||||||
buf[offset + 1] = (u8)(val >> 48);
|
buf[offset + 1] = (u8)(val >> 48);
|
||||||
buf[offset + 2] = (u8)(val >> 40);
|
buf[offset + 2] = (u8)(val >> 40);
|
||||||
|
|
@ -51,85 +51,85 @@ void pxl8_pack_u64_be(u8* buf, size_t offset, u64 val) {
|
||||||
buf[offset + 7] = (u8)(val);
|
buf[offset + 7] = (u8)(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_i8(u8* buf, size_t offset, i8 val) {
|
void pxl8_pack_i8(u8* buf, usize offset, i8 val) {
|
||||||
buf[offset] = (u8)val;
|
buf[offset] = (u8)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_i16_le(u8* buf, size_t offset, i16 val) {
|
void pxl8_pack_i16_le(u8* buf, usize offset, i16 val) {
|
||||||
pxl8_pack_u16_le(buf, offset, (u16)val);
|
pxl8_pack_u16_le(buf, offset, (u16)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_i16_be(u8* buf, size_t offset, i16 val) {
|
void pxl8_pack_i16_be(u8* buf, usize offset, i16 val) {
|
||||||
pxl8_pack_u16_be(buf, offset, (u16)val);
|
pxl8_pack_u16_be(buf, offset, (u16)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_i32_le(u8* buf, size_t offset, i32 val) {
|
void pxl8_pack_i32_le(u8* buf, usize offset, i32 val) {
|
||||||
pxl8_pack_u32_le(buf, offset, (u32)val);
|
pxl8_pack_u32_le(buf, offset, (u32)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_i32_be(u8* buf, size_t offset, i32 val) {
|
void pxl8_pack_i32_be(u8* buf, usize offset, i32 val) {
|
||||||
pxl8_pack_u32_be(buf, offset, (u32)val);
|
pxl8_pack_u32_be(buf, offset, (u32)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_i64_le(u8* buf, size_t offset, i64 val) {
|
void pxl8_pack_i64_le(u8* buf, usize offset, i64 val) {
|
||||||
pxl8_pack_u64_le(buf, offset, (u64)val);
|
pxl8_pack_u64_le(buf, offset, (u64)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_i64_be(u8* buf, size_t offset, i64 val) {
|
void pxl8_pack_i64_be(u8* buf, usize offset, i64 val) {
|
||||||
pxl8_pack_u64_be(buf, offset, (u64)val);
|
pxl8_pack_u64_be(buf, offset, (u64)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_f32_le(u8* buf, size_t offset, f32 val) {
|
void pxl8_pack_f32_le(u8* buf, usize offset, f32 val) {
|
||||||
u32 bits;
|
u32 bits;
|
||||||
memcpy(&bits, &val, sizeof(bits));
|
memcpy(&bits, &val, sizeof(bits));
|
||||||
pxl8_pack_u32_le(buf, offset, bits);
|
pxl8_pack_u32_le(buf, offset, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_f32_be(u8* buf, size_t offset, f32 val) {
|
void pxl8_pack_f32_be(u8* buf, usize offset, f32 val) {
|
||||||
u32 bits;
|
u32 bits;
|
||||||
memcpy(&bits, &val, sizeof(bits));
|
memcpy(&bits, &val, sizeof(bits));
|
||||||
pxl8_pack_u32_be(buf, offset, bits);
|
pxl8_pack_u32_be(buf, offset, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_f64_le(u8* buf, size_t offset, f64 val) {
|
void pxl8_pack_f64_le(u8* buf, usize offset, f64 val) {
|
||||||
u64 bits;
|
u64 bits;
|
||||||
memcpy(&bits, &val, sizeof(bits));
|
memcpy(&bits, &val, sizeof(bits));
|
||||||
pxl8_pack_u64_le(buf, offset, bits);
|
pxl8_pack_u64_le(buf, offset, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_pack_f64_be(u8* buf, size_t offset, f64 val) {
|
void pxl8_pack_f64_be(u8* buf, usize offset, f64 val) {
|
||||||
u64 bits;
|
u64 bits;
|
||||||
memcpy(&bits, &val, sizeof(bits));
|
memcpy(&bits, &val, sizeof(bits));
|
||||||
pxl8_pack_u64_be(buf, offset, bits);
|
pxl8_pack_u64_be(buf, offset, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 pxl8_unpack_u8(const u8* buf, size_t offset) {
|
u8 pxl8_unpack_u8(const u8* buf, usize offset) {
|
||||||
return buf[offset];
|
return buf[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 pxl8_unpack_u16_le(const u8* buf, size_t offset) {
|
u16 pxl8_unpack_u16_le(const u8* buf, usize offset) {
|
||||||
return (u16)buf[offset] | ((u16)buf[offset + 1] << 8);
|
return (u16)buf[offset] | ((u16)buf[offset + 1] << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 pxl8_unpack_u16_be(const u8* buf, size_t offset) {
|
u16 pxl8_unpack_u16_be(const u8* buf, usize offset) {
|
||||||
return ((u16)buf[offset] << 8) | (u16)buf[offset + 1];
|
return ((u16)buf[offset] << 8) | (u16)buf[offset + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 pxl8_unpack_u32_le(const u8* buf, size_t offset) {
|
u32 pxl8_unpack_u32_le(const u8* buf, usize offset) {
|
||||||
return (u32)buf[offset] |
|
return (u32)buf[offset] |
|
||||||
((u32)buf[offset + 1] << 8) |
|
((u32)buf[offset + 1] << 8) |
|
||||||
((u32)buf[offset + 2] << 16) |
|
((u32)buf[offset + 2] << 16) |
|
||||||
((u32)buf[offset + 3] << 24);
|
((u32)buf[offset + 3] << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 pxl8_unpack_u32_be(const u8* buf, size_t offset) {
|
u32 pxl8_unpack_u32_be(const u8* buf, usize offset) {
|
||||||
return ((u32)buf[offset] << 24) |
|
return ((u32)buf[offset] << 24) |
|
||||||
((u32)buf[offset + 1] << 16) |
|
((u32)buf[offset + 1] << 16) |
|
||||||
((u32)buf[offset + 2] << 8) |
|
((u32)buf[offset + 2] << 8) |
|
||||||
(u32)buf[offset + 3];
|
(u32)buf[offset + 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 pxl8_unpack_u64_le(const u8* buf, size_t offset) {
|
u64 pxl8_unpack_u64_le(const u8* buf, usize offset) {
|
||||||
return (u64)buf[offset] |
|
return (u64)buf[offset] |
|
||||||
((u64)buf[offset + 1] << 8) |
|
((u64)buf[offset + 1] << 8) |
|
||||||
((u64)buf[offset + 2] << 16) |
|
((u64)buf[offset + 2] << 16) |
|
||||||
|
|
@ -140,7 +140,7 @@ u64 pxl8_unpack_u64_le(const u8* buf, size_t offset) {
|
||||||
((u64)buf[offset + 7] << 56);
|
((u64)buf[offset + 7] << 56);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 pxl8_unpack_u64_be(const u8* buf, size_t offset) {
|
u64 pxl8_unpack_u64_be(const u8* buf, usize offset) {
|
||||||
return ((u64)buf[offset] << 56) |
|
return ((u64)buf[offset] << 56) |
|
||||||
((u64)buf[offset + 1] << 48) |
|
((u64)buf[offset + 1] << 48) |
|
||||||
((u64)buf[offset + 2] << 40) |
|
((u64)buf[offset + 2] << 40) |
|
||||||
|
|
@ -151,56 +151,56 @@ u64 pxl8_unpack_u64_be(const u8* buf, size_t offset) {
|
||||||
(u64)buf[offset + 7];
|
(u64)buf[offset + 7];
|
||||||
}
|
}
|
||||||
|
|
||||||
i8 pxl8_unpack_i8(const u8* buf, size_t offset) {
|
i8 pxl8_unpack_i8(const u8* buf, usize offset) {
|
||||||
return (i8)buf[offset];
|
return (i8)buf[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
i16 pxl8_unpack_i16_le(const u8* buf, size_t offset) {
|
i16 pxl8_unpack_i16_le(const u8* buf, usize offset) {
|
||||||
return (i16)pxl8_unpack_u16_le(buf, offset);
|
return (i16)pxl8_unpack_u16_le(buf, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
i16 pxl8_unpack_i16_be(const u8* buf, size_t offset) {
|
i16 pxl8_unpack_i16_be(const u8* buf, usize offset) {
|
||||||
return (i16)pxl8_unpack_u16_be(buf, offset);
|
return (i16)pxl8_unpack_u16_be(buf, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 pxl8_unpack_i32_le(const u8* buf, size_t offset) {
|
i32 pxl8_unpack_i32_le(const u8* buf, usize offset) {
|
||||||
return (i32)pxl8_unpack_u32_le(buf, offset);
|
return (i32)pxl8_unpack_u32_le(buf, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 pxl8_unpack_i32_be(const u8* buf, size_t offset) {
|
i32 pxl8_unpack_i32_be(const u8* buf, usize offset) {
|
||||||
return (i32)pxl8_unpack_u32_be(buf, offset);
|
return (i32)pxl8_unpack_u32_be(buf, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 pxl8_unpack_i64_le(const u8* buf, size_t offset) {
|
i64 pxl8_unpack_i64_le(const u8* buf, usize offset) {
|
||||||
return (i64)pxl8_unpack_u64_le(buf, offset);
|
return (i64)pxl8_unpack_u64_le(buf, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 pxl8_unpack_i64_be(const u8* buf, size_t offset) {
|
i64 pxl8_unpack_i64_be(const u8* buf, usize offset) {
|
||||||
return (i64)pxl8_unpack_u64_be(buf, offset);
|
return (i64)pxl8_unpack_u64_be(buf, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 pxl8_unpack_f32_le(const u8* buf, size_t offset) {
|
f32 pxl8_unpack_f32_le(const u8* buf, usize offset) {
|
||||||
u32 bits = pxl8_unpack_u32_le(buf, offset);
|
u32 bits = pxl8_unpack_u32_le(buf, offset);
|
||||||
f32 result;
|
f32 result;
|
||||||
memcpy(&result, &bits, sizeof(result));
|
memcpy(&result, &bits, sizeof(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 pxl8_unpack_f32_be(const u8* buf, size_t offset) {
|
f32 pxl8_unpack_f32_be(const u8* buf, usize offset) {
|
||||||
u32 bits = pxl8_unpack_u32_be(buf, offset);
|
u32 bits = pxl8_unpack_u32_be(buf, offset);
|
||||||
f32 result;
|
f32 result;
|
||||||
memcpy(&result, &bits, sizeof(result));
|
memcpy(&result, &bits, sizeof(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
f64 pxl8_unpack_f64_le(const u8* buf, size_t offset) {
|
f64 pxl8_unpack_f64_le(const u8* buf, usize offset) {
|
||||||
u64 bits = pxl8_unpack_u64_le(buf, offset);
|
u64 bits = pxl8_unpack_u64_le(buf, offset);
|
||||||
f64 result;
|
f64 result;
|
||||||
memcpy(&result, &bits, sizeof(result));
|
memcpy(&result, &bits, sizeof(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
f64 pxl8_unpack_f64_be(const u8* buf, size_t offset) {
|
f64 pxl8_unpack_f64_be(const u8* buf, usize offset) {
|
||||||
u64 bits = pxl8_unpack_u64_be(buf, offset);
|
u64 bits = pxl8_unpack_u64_be(buf, offset);
|
||||||
f64 result;
|
f64 result;
|
||||||
memcpy(&result, &bits, sizeof(result));
|
memcpy(&result, &bits, sizeof(result));
|
||||||
|
|
|
||||||
|
|
@ -10,43 +10,43 @@ void pxl8_bit_set(u32* val, u8 bit);
|
||||||
bool pxl8_bit_test(u32 val, u8 bit);
|
bool pxl8_bit_test(u32 val, u8 bit);
|
||||||
void pxl8_bit_toggle(u32* val, u8 bit);
|
void pxl8_bit_toggle(u32* val, u8 bit);
|
||||||
|
|
||||||
void pxl8_pack_u8(u8* buf, size_t offset, u8 val);
|
void pxl8_pack_u8(u8* buf, usize offset, u8 val);
|
||||||
void pxl8_pack_u16_be(u8* buf, size_t offset, u16 val);
|
void pxl8_pack_u16_be(u8* buf, usize offset, u16 val);
|
||||||
void pxl8_pack_u16_le(u8* buf, size_t offset, u16 val);
|
void pxl8_pack_u16_le(u8* buf, usize offset, u16 val);
|
||||||
void pxl8_pack_u32_be(u8* buf, size_t offset, u32 val);
|
void pxl8_pack_u32_be(u8* buf, usize offset, u32 val);
|
||||||
void pxl8_pack_u32_le(u8* buf, size_t offset, u32 val);
|
void pxl8_pack_u32_le(u8* buf, usize offset, u32 val);
|
||||||
void pxl8_pack_u64_be(u8* buf, size_t offset, u64 val);
|
void pxl8_pack_u64_be(u8* buf, usize offset, u64 val);
|
||||||
void pxl8_pack_u64_le(u8* buf, size_t offset, u64 val);
|
void pxl8_pack_u64_le(u8* buf, usize offset, u64 val);
|
||||||
void pxl8_pack_i8(u8* buf, size_t offset, i8 val);
|
void pxl8_pack_i8(u8* buf, usize offset, i8 val);
|
||||||
void pxl8_pack_i16_be(u8* buf, size_t offset, i16 val);
|
void pxl8_pack_i16_be(u8* buf, usize offset, i16 val);
|
||||||
void pxl8_pack_i16_le(u8* buf, size_t offset, i16 val);
|
void pxl8_pack_i16_le(u8* buf, usize offset, i16 val);
|
||||||
void pxl8_pack_i32_be(u8* buf, size_t offset, i32 val);
|
void pxl8_pack_i32_be(u8* buf, usize offset, i32 val);
|
||||||
void pxl8_pack_i32_le(u8* buf, size_t offset, i32 val);
|
void pxl8_pack_i32_le(u8* buf, usize offset, i32 val);
|
||||||
void pxl8_pack_i64_be(u8* buf, size_t offset, i64 val);
|
void pxl8_pack_i64_be(u8* buf, usize offset, i64 val);
|
||||||
void pxl8_pack_i64_le(u8* buf, size_t offset, i64 val);
|
void pxl8_pack_i64_le(u8* buf, usize offset, i64 val);
|
||||||
void pxl8_pack_f32_be(u8* buf, size_t offset, f32 val);
|
void pxl8_pack_f32_be(u8* buf, usize offset, f32 val);
|
||||||
void pxl8_pack_f32_le(u8* buf, size_t offset, f32 val);
|
void pxl8_pack_f32_le(u8* buf, usize offset, f32 val);
|
||||||
void pxl8_pack_f64_be(u8* buf, size_t offset, f64 val);
|
void pxl8_pack_f64_be(u8* buf, usize offset, f64 val);
|
||||||
void pxl8_pack_f64_le(u8* buf, size_t offset, f64 val);
|
void pxl8_pack_f64_le(u8* buf, usize offset, f64 val);
|
||||||
|
|
||||||
u8 pxl8_unpack_u8(const u8* buf, size_t offset);
|
u8 pxl8_unpack_u8(const u8* buf, usize offset);
|
||||||
u16 pxl8_unpack_u16_be(const u8* buf, size_t offset);
|
u16 pxl8_unpack_u16_be(const u8* buf, usize offset);
|
||||||
u16 pxl8_unpack_u16_le(const u8* buf, size_t offset);
|
u16 pxl8_unpack_u16_le(const u8* buf, usize offset);
|
||||||
u32 pxl8_unpack_u32_be(const u8* buf, size_t offset);
|
u32 pxl8_unpack_u32_be(const u8* buf, usize offset);
|
||||||
u32 pxl8_unpack_u32_le(const u8* buf, size_t offset);
|
u32 pxl8_unpack_u32_le(const u8* buf, usize offset);
|
||||||
u64 pxl8_unpack_u64_be(const u8* buf, size_t offset);
|
u64 pxl8_unpack_u64_be(const u8* buf, usize offset);
|
||||||
u64 pxl8_unpack_u64_le(const u8* buf, size_t offset);
|
u64 pxl8_unpack_u64_le(const u8* buf, usize offset);
|
||||||
i8 pxl8_unpack_i8(const u8* buf, size_t offset);
|
i8 pxl8_unpack_i8(const u8* buf, usize offset);
|
||||||
i16 pxl8_unpack_i16_be(const u8* buf, size_t offset);
|
i16 pxl8_unpack_i16_be(const u8* buf, usize offset);
|
||||||
i16 pxl8_unpack_i16_le(const u8* buf, size_t offset);
|
i16 pxl8_unpack_i16_le(const u8* buf, usize offset);
|
||||||
i32 pxl8_unpack_i32_be(const u8* buf, size_t offset);
|
i32 pxl8_unpack_i32_be(const u8* buf, usize offset);
|
||||||
i32 pxl8_unpack_i32_le(const u8* buf, size_t offset);
|
i32 pxl8_unpack_i32_le(const u8* buf, usize offset);
|
||||||
i64 pxl8_unpack_i64_be(const u8* buf, size_t offset);
|
i64 pxl8_unpack_i64_be(const u8* buf, usize offset);
|
||||||
i64 pxl8_unpack_i64_le(const u8* buf, size_t offset);
|
i64 pxl8_unpack_i64_le(const u8* buf, usize offset);
|
||||||
f32 pxl8_unpack_f32_be(const u8* buf, size_t offset);
|
f32 pxl8_unpack_f32_be(const u8* buf, usize offset);
|
||||||
f32 pxl8_unpack_f32_le(const u8* buf, size_t offset);
|
f32 pxl8_unpack_f32_le(const u8* buf, usize offset);
|
||||||
f64 pxl8_unpack_f64_be(const u8* buf, size_t offset);
|
f64 pxl8_unpack_f64_be(const u8* buf, usize offset);
|
||||||
f64 pxl8_unpack_f64_le(const u8* buf, size_t offset);
|
f64 pxl8_unpack_f64_le(const u8* buf, usize offset);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const u8* bytes;
|
const u8* bytes;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "pxl8_io.h"
|
#include "pxl8_io.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -10,7 +11,7 @@ static inline char pxl8_to_lower(char c) {
|
||||||
return (c >= 'A' && c <= 'Z') ? c + 32 : c;
|
return (c >= 'A' && c <= 'Z') ? c + 32 : c;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_io_read_file(const char* path, char** content, size_t* size) {
|
pxl8_result pxl8_io_read_file(const char* path, char** content, usize* size) {
|
||||||
if (!path || !content || !size) return PXL8_ERROR_NULL_POINTER;
|
if (!path || !content || !size) return PXL8_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
pxl8_cart* cart = pxl8_get_cart();
|
pxl8_cart* cart = pxl8_get_cart();
|
||||||
|
|
@ -19,7 +20,7 @@ pxl8_result pxl8_io_read_file(const char* path, char** content, size_t* size) {
|
||||||
u32 cart_size = 0;
|
u32 cart_size = 0;
|
||||||
pxl8_result result = pxl8_cart_read_file(cart, path, &data, &cart_size);
|
pxl8_result result = pxl8_cart_read_file(cart, path, &data, &cart_size);
|
||||||
if (result == PXL8_OK) {
|
if (result == PXL8_OK) {
|
||||||
*content = realloc(data, cart_size + 1);
|
*content = pxl8_realloc(data, cart_size + 1);
|
||||||
if (!*content) {
|
if (!*content) {
|
||||||
pxl8_cart_free_file(data);
|
pxl8_cart_free_file(data);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
@ -44,13 +45,13 @@ pxl8_result pxl8_io_read_file(const char* path, char** content, size_t* size) {
|
||||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*content = malloc(file_size + 1);
|
*content = pxl8_malloc(file_size + 1);
|
||||||
if (!*content) {
|
if (!*content) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bytes_read = fread(*content, 1, file_size, file);
|
usize bytes_read = fread(*content, 1, file_size, file);
|
||||||
(*content)[bytes_read] = '\0';
|
(*content)[bytes_read] = '\0';
|
||||||
*size = bytes_read;
|
*size = bytes_read;
|
||||||
|
|
||||||
|
|
@ -58,7 +59,7 @@ pxl8_result pxl8_io_read_file(const char* path, char** content, size_t* size) {
|
||||||
return PXL8_OK;
|
return PXL8_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_io_write_file(const char* path, const char* content, size_t size) {
|
pxl8_result pxl8_io_write_file(const char* path, const char* content, usize size) {
|
||||||
if (!path || !content) return PXL8_ERROR_NULL_POINTER;
|
if (!path || !content) return PXL8_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
FILE* file = fopen(path, "wb");
|
FILE* file = fopen(path, "wb");
|
||||||
|
|
@ -66,17 +67,17 @@ pxl8_result pxl8_io_write_file(const char* path, const char* content, size_t siz
|
||||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bytes_written = fwrite(content, 1, size, file);
|
usize bytes_written = fwrite(content, 1, size, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
return (bytes_written == size) ? PXL8_OK : PXL8_ERROR_SYSTEM_FAILURE;
|
return (bytes_written == size) ? PXL8_OK : PXL8_ERROR_SYSTEM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_io_read_binary_file(const char* path, u8** data, size_t* size) {
|
pxl8_result pxl8_io_read_binary_file(const char* path, u8** data, usize* size) {
|
||||||
return pxl8_io_read_file(path, (char**)data, size);
|
return pxl8_io_read_file(path, (char**)data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_io_write_binary_file(const char* path, const u8* data, size_t size) {
|
pxl8_result pxl8_io_write_binary_file(const char* path, const u8* data, usize size) {
|
||||||
return pxl8_io_write_file(path, (const char*)data, size);
|
return pxl8_io_write_file(path, (const char*)data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,13 +113,13 @@ pxl8_result pxl8_io_create_directory(const char* path) {
|
||||||
|
|
||||||
void pxl8_io_free_file_content(char* content) {
|
void pxl8_io_free_file_content(char* content) {
|
||||||
if (content) {
|
if (content) {
|
||||||
free(content);
|
pxl8_free(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_io_free_binary_data(u8* data) {
|
void pxl8_io_free_binary_data(u8* data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,7 +145,7 @@ static i32 pxl8_key_code(const char* key_name) {
|
||||||
};
|
};
|
||||||
|
|
||||||
char lower_name[64];
|
char lower_name[64];
|
||||||
size_t i;
|
usize i;
|
||||||
for (i = 0; i < sizeof(lower_name) - 1 && key_name[i]; i++) {
|
for (i = 0; i < sizeof(lower_name) - 1 && key_name[i]; i++) {
|
||||||
lower_name[i] = pxl8_to_lower(key_name[i]);
|
lower_name[i] = pxl8_to_lower(key_name[i]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,10 @@ bool pxl8_io_file_exists(const char* path);
|
||||||
void pxl8_io_free_binary_data(u8* data);
|
void pxl8_io_free_binary_data(u8* data);
|
||||||
void pxl8_io_free_file_content(char* content);
|
void pxl8_io_free_file_content(char* content);
|
||||||
f64 pxl8_io_get_file_modified_time(const char* path);
|
f64 pxl8_io_get_file_modified_time(const char* path);
|
||||||
pxl8_result pxl8_io_read_binary_file(const char* path, u8** data, size_t* size);
|
pxl8_result pxl8_io_read_binary_file(const char* path, u8** data, usize* size);
|
||||||
pxl8_result pxl8_io_read_file(const char* path, char** content, size_t* size);
|
pxl8_result pxl8_io_read_file(const char* path, char** content, usize* size);
|
||||||
pxl8_result pxl8_io_write_binary_file(const char* path, const u8* data, size_t size);
|
pxl8_result pxl8_io_write_binary_file(const char* path, const u8* data, usize size);
|
||||||
pxl8_result pxl8_io_write_file(const char* path, const char* content, size_t size);
|
pxl8_result pxl8_io_write_file(const char* path, const char* content, usize size);
|
||||||
|
|
||||||
bool pxl8_key_down(const pxl8_input_state* input, const char* key_name);
|
bool pxl8_key_down(const pxl8_input_state* input, const char* key_name);
|
||||||
bool pxl8_key_pressed(const pxl8_input_state* input, const char* key_name);
|
bool pxl8_key_pressed(const pxl8_input_state* input, const char* key_name);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ void pxl8_log_set_level(pxl8_log_level level) {
|
||||||
if (g_log) g_log->level = level;
|
if (g_log) g_log->level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_timestamp(char* buffer, size_t size) {
|
static void log_timestamp(char* buffer, usize size) {
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
struct tm* tm_info = localtime(&now);
|
struct tm* tm_info = localtime(&now);
|
||||||
strftime(buffer, size, "%H:%M:%S", tm_info);
|
strftime(buffer, size, "%H:%M:%S", tm_info);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "pxl8_replay.h"
|
#include "pxl8_replay.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
#include "pxl8_sys.h"
|
#include "pxl8_sys.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -42,8 +43,8 @@ struct pxl8_replay {
|
||||||
static void pxl8_replay_chunk_free(pxl8_replay_chunk* chunk) {
|
static void pxl8_replay_chunk_free(pxl8_replay_chunk* chunk) {
|
||||||
while (chunk) {
|
while (chunk) {
|
||||||
pxl8_replay_chunk* next = chunk->next;
|
pxl8_replay_chunk* next = chunk->next;
|
||||||
free(chunk->data);
|
pxl8_free(chunk->data);
|
||||||
free(chunk);
|
pxl8_free(chunk);
|
||||||
chunk = next;
|
chunk = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -52,7 +53,7 @@ static void pxl8_replay_keyframe_entry_free(pxl8_keyframe_entry* entry) {
|
||||||
while (entry) {
|
while (entry) {
|
||||||
pxl8_keyframe_entry* next = entry->next;
|
pxl8_keyframe_entry* next = entry->next;
|
||||||
pxl8_replay_chunk_free(entry->input_deltas);
|
pxl8_replay_chunk_free(entry->input_deltas);
|
||||||
free(entry);
|
pxl8_free(entry);
|
||||||
entry = next;
|
entry = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +65,7 @@ pxl8_replay* pxl8_replay_create(const char* path, u32 keyframe_interval) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_replay* r = calloc(1, sizeof(pxl8_replay));
|
pxl8_replay* r = pxl8_calloc(1, sizeof(pxl8_replay));
|
||||||
if (!r) {
|
if (!r) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -85,7 +86,7 @@ pxl8_replay* pxl8_replay_create(const char* path, u32 keyframe_interval) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_replay* pxl8_replay_create_buffer(u32 keyframe_interval, u32 max_keyframes) {
|
pxl8_replay* pxl8_replay_create_buffer(u32 keyframe_interval, u32 max_keyframes) {
|
||||||
pxl8_replay* r = calloc(1, sizeof(pxl8_replay));
|
pxl8_replay* r = pxl8_calloc(1, sizeof(pxl8_replay));
|
||||||
if (!r) return NULL;
|
if (!r) return NULL;
|
||||||
|
|
||||||
r->recording = true;
|
r->recording = true;
|
||||||
|
|
@ -125,7 +126,7 @@ pxl8_replay* pxl8_replay_open(const char* path) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_replay* r = calloc(1, sizeof(pxl8_replay));
|
pxl8_replay* r = pxl8_calloc(1, sizeof(pxl8_replay));
|
||||||
if (!r) {
|
if (!r) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -146,14 +147,14 @@ pxl8_replay* pxl8_replay_open(const char* path) {
|
||||||
if (fread(size_bytes, 3, 1, f) != 1) break;
|
if (fread(size_bytes, 3, 1, f) != 1) break;
|
||||||
u32 size = size_bytes[0] | (size_bytes[1] << 8) | (size_bytes[2] << 16);
|
u32 size = size_bytes[0] | (size_bytes[1] << 8) | (size_bytes[2] << 16);
|
||||||
|
|
||||||
u8* data = malloc(size);
|
u8* data = pxl8_malloc(size);
|
||||||
if (!data || fread(data, size, 1, f) != 1) {
|
if (!data || fread(data, size, 1, f) != 1) {
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunk_type == PXL8_REPLAY_CHUNK_KEYFRAME) {
|
if (chunk_type == PXL8_REPLAY_CHUNK_KEYFRAME) {
|
||||||
pxl8_keyframe_entry* entry = calloc(1, sizeof(pxl8_keyframe_entry));
|
pxl8_keyframe_entry* entry = pxl8_calloc(1, sizeof(pxl8_keyframe_entry));
|
||||||
if (entry && size >= sizeof(pxl8_keyframe)) {
|
if (entry && size >= sizeof(pxl8_keyframe)) {
|
||||||
memcpy(&entry->keyframe, data, sizeof(pxl8_keyframe));
|
memcpy(&entry->keyframe, data, sizeof(pxl8_keyframe));
|
||||||
entry->prev = r->current_keyframe;
|
entry->prev = r->current_keyframe;
|
||||||
|
|
@ -166,10 +167,10 @@ pxl8_replay* pxl8_replay_open(const char* path) {
|
||||||
}
|
}
|
||||||
r->keyframe_count++;
|
r->keyframe_count++;
|
||||||
}
|
}
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
} else if (chunk_type == PXL8_REPLAY_CHUNK_INPUT) {
|
} else if (chunk_type == PXL8_REPLAY_CHUNK_INPUT) {
|
||||||
if (r->current_keyframe) {
|
if (r->current_keyframe) {
|
||||||
pxl8_replay_chunk* chunk = calloc(1, sizeof(pxl8_replay_chunk));
|
pxl8_replay_chunk* chunk = pxl8_calloc(1, sizeof(pxl8_replay_chunk));
|
||||||
if (chunk) {
|
if (chunk) {
|
||||||
chunk->type = chunk_type;
|
chunk->type = chunk_type;
|
||||||
chunk->size = size;
|
chunk->size = size;
|
||||||
|
|
@ -185,9 +186,9 @@ pxl8_replay* pxl8_replay_open(const char* path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
} else if (chunk_type == PXL8_REPLAY_CHUNK_AUDIO_EVENT) {
|
} else if (chunk_type == PXL8_REPLAY_CHUNK_AUDIO_EVENT) {
|
||||||
pxl8_replay_chunk* chunk = calloc(1, sizeof(pxl8_replay_chunk));
|
pxl8_replay_chunk* chunk = pxl8_calloc(1, sizeof(pxl8_replay_chunk));
|
||||||
if (chunk) {
|
if (chunk) {
|
||||||
chunk->type = chunk_type;
|
chunk->type = chunk_type;
|
||||||
chunk->size = size;
|
chunk->size = size;
|
||||||
|
|
@ -202,9 +203,9 @@ pxl8_replay* pxl8_replay_open(const char* path) {
|
||||||
r->audio_events_tail = chunk;
|
r->audio_events_tail = chunk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
} else {
|
} else {
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,7 +232,7 @@ void pxl8_replay_destroy(pxl8_replay* r) {
|
||||||
pxl8_replay_chunk_free(r->pending_inputs);
|
pxl8_replay_chunk_free(r->pending_inputs);
|
||||||
pxl8_replay_chunk_free(r->audio_events);
|
pxl8_replay_chunk_free(r->audio_events);
|
||||||
|
|
||||||
free(r);
|
pxl8_free(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pxl8_replay_is_recording(pxl8_replay* r) {
|
bool pxl8_replay_is_recording(pxl8_replay* r) {
|
||||||
|
|
@ -262,14 +263,14 @@ static void write_chunk(FILE* f, u8 type, const void* data, u32 size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_chunk_to_buffer(pxl8_replay* r, u8 type, const void* data, u32 size) {
|
static void add_chunk_to_buffer(pxl8_replay* r, u8 type, const void* data, u32 size) {
|
||||||
pxl8_replay_chunk* chunk = calloc(1, sizeof(pxl8_replay_chunk));
|
pxl8_replay_chunk* chunk = pxl8_calloc(1, sizeof(pxl8_replay_chunk));
|
||||||
if (!chunk) return;
|
if (!chunk) return;
|
||||||
|
|
||||||
chunk->type = type;
|
chunk->type = type;
|
||||||
chunk->size = size;
|
chunk->size = size;
|
||||||
chunk->data = malloc(size);
|
chunk->data = pxl8_malloc(size);
|
||||||
if (!chunk->data) {
|
if (!chunk->data) {
|
||||||
free(chunk);
|
pxl8_free(chunk);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(chunk->data, data, size);
|
memcpy(chunk->data, data, size);
|
||||||
|
|
@ -327,7 +328,7 @@ void pxl8_replay_write_keyframe(pxl8_replay* r, u32 frame, f32 time, pxl8_rng* r
|
||||||
write_chunk(r->file, PXL8_REPLAY_CHUNK_KEYFRAME, &kf, sizeof(kf));
|
write_chunk(r->file, PXL8_REPLAY_CHUNK_KEYFRAME, &kf, sizeof(kf));
|
||||||
fflush(r->file);
|
fflush(r->file);
|
||||||
} else {
|
} else {
|
||||||
pxl8_keyframe_entry* entry = calloc(1, sizeof(pxl8_keyframe_entry));
|
pxl8_keyframe_entry* entry = pxl8_calloc(1, sizeof(pxl8_keyframe_entry));
|
||||||
if (!entry) return;
|
if (!entry) return;
|
||||||
|
|
||||||
entry->keyframe = kf;
|
entry->keyframe = kf;
|
||||||
|
|
@ -342,7 +343,7 @@ void pxl8_replay_write_keyframe(pxl8_replay* r, u32 frame, f32 time, pxl8_rng* r
|
||||||
r->keyframes->prev = NULL;
|
r->keyframes->prev = NULL;
|
||||||
}
|
}
|
||||||
pxl8_replay_chunk_free(oldest->input_deltas);
|
pxl8_replay_chunk_free(oldest->input_deltas);
|
||||||
free(oldest);
|
pxl8_free(oldest);
|
||||||
r->keyframe_count--;
|
r->keyframe_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -446,14 +447,14 @@ void pxl8_replay_write_audio_event(pxl8_replay* r, u32 frame, u8 event_type, u8
|
||||||
if (r->file) {
|
if (r->file) {
|
||||||
write_chunk(r->file, PXL8_REPLAY_CHUNK_AUDIO_EVENT, &evt, sizeof(evt));
|
write_chunk(r->file, PXL8_REPLAY_CHUNK_AUDIO_EVENT, &evt, sizeof(evt));
|
||||||
} else {
|
} else {
|
||||||
pxl8_replay_chunk* chunk = calloc(1, sizeof(pxl8_replay_chunk));
|
pxl8_replay_chunk* chunk = pxl8_calloc(1, sizeof(pxl8_replay_chunk));
|
||||||
if (!chunk) return;
|
if (!chunk) return;
|
||||||
|
|
||||||
chunk->type = PXL8_REPLAY_CHUNK_AUDIO_EVENT;
|
chunk->type = PXL8_REPLAY_CHUNK_AUDIO_EVENT;
|
||||||
chunk->size = sizeof(evt);
|
chunk->size = sizeof(evt);
|
||||||
chunk->data = malloc(sizeof(evt));
|
chunk->data = pxl8_malloc(sizeof(evt));
|
||||||
if (!chunk->data) {
|
if (!chunk->data) {
|
||||||
free(chunk);
|
pxl8_free(chunk);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(chunk->data, &evt, sizeof(evt));
|
memcpy(chunk->data, &evt, sizeof(evt));
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@ typedef uint16_t u16;
|
||||||
typedef uint32_t u32;
|
typedef uint32_t u32;
|
||||||
typedef uint64_t u64;
|
typedef uint64_t u64;
|
||||||
|
|
||||||
|
typedef size_t usize;
|
||||||
|
typedef ptrdiff_t isize;
|
||||||
|
|
||||||
#if defined(__SIZEOF_INT128__)
|
#if defined(__SIZEOF_INT128__)
|
||||||
typedef __int128_t i128;
|
typedef __int128_t i128;
|
||||||
typedef __uint128_t u128;
|
typedef __uint128_t u128;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "pxl8_3d_camera.h"
|
#include "pxl8_3d_camera.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -28,7 +29,7 @@ struct pxl8_3d_camera {
|
||||||
};
|
};
|
||||||
|
|
||||||
pxl8_3d_camera* pxl8_3d_camera_create(void) {
|
pxl8_3d_camera* pxl8_3d_camera_create(void) {
|
||||||
pxl8_3d_camera* cam = calloc(1, sizeof(pxl8_3d_camera));
|
pxl8_3d_camera* cam = pxl8_calloc(1, sizeof(pxl8_3d_camera));
|
||||||
if (!cam) return NULL;
|
if (!cam) return NULL;
|
||||||
|
|
||||||
cam->position = (pxl8_vec3){0, 0, 0};
|
cam->position = (pxl8_vec3){0, 0, 0};
|
||||||
|
|
@ -46,7 +47,7 @@ pxl8_3d_camera* pxl8_3d_camera_create(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_3d_camera_destroy(pxl8_3d_camera* cam) {
|
void pxl8_3d_camera_destroy(pxl8_3d_camera* cam) {
|
||||||
free(cam);
|
pxl8_free(cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_3d_camera_lookat(pxl8_3d_camera* cam, pxl8_vec3 eye, pxl8_vec3 target, pxl8_vec3 up) {
|
void pxl8_3d_camera_lookat(pxl8_3d_camera* cam, pxl8_vec3 eye, pxl8_vec3 target, pxl8_vec3 up) {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "pxl8_atlas.h"
|
#include "pxl8_atlas.h"
|
||||||
#include "pxl8_gfx.h"
|
#include "pxl8_gfx.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#define PXL8_ANIM_MAX_STATES 32
|
#define PXL8_ANIM_MAX_STATES 32
|
||||||
|
|
||||||
|
|
@ -36,36 +37,36 @@ pxl8_anim* pxl8_anim_create(const u32* frame_ids, const u16* frame_durations, u1
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_anim* anim = (pxl8_anim*)calloc(1, sizeof(pxl8_anim));
|
pxl8_anim* anim = (pxl8_anim*)pxl8_calloc(1, sizeof(pxl8_anim));
|
||||||
if (!anim) {
|
if (!anim) {
|
||||||
pxl8_error("Failed to allocate animation");
|
pxl8_error("Failed to allocate animation");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
anim->frame_ids = (u32*)malloc(frame_count * sizeof(u32));
|
anim->frame_ids = (u32*)pxl8_malloc(frame_count * sizeof(u32));
|
||||||
if (!anim->frame_ids) {
|
if (!anim->frame_ids) {
|
||||||
pxl8_error("Failed to allocate frame IDs");
|
pxl8_error("Failed to allocate frame IDs");
|
||||||
free(anim);
|
pxl8_free(anim);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(anim->frame_ids, frame_ids, frame_count * sizeof(u32));
|
memcpy(anim->frame_ids, frame_ids, frame_count * sizeof(u32));
|
||||||
|
|
||||||
if (frame_durations) {
|
if (frame_durations) {
|
||||||
anim->frame_durations = (u16*)malloc(frame_count * sizeof(u16));
|
anim->frame_durations = (u16*)pxl8_malloc(frame_count * sizeof(u16));
|
||||||
if (!anim->frame_durations) {
|
if (!anim->frame_durations) {
|
||||||
pxl8_error("Failed to allocate frame durations");
|
pxl8_error("Failed to allocate frame durations");
|
||||||
free(anim->frame_ids);
|
pxl8_free(anim->frame_ids);
|
||||||
free(anim);
|
pxl8_free(anim);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(anim->frame_durations, frame_durations, frame_count * sizeof(u16));
|
memcpy(anim->frame_durations, frame_durations, frame_count * sizeof(u16));
|
||||||
} else {
|
} else {
|
||||||
anim->frame_durations = (u16*)calloc(frame_count, sizeof(u16));
|
anim->frame_durations = (u16*)pxl8_calloc(frame_count, sizeof(u16));
|
||||||
if (!anim->frame_durations) {
|
if (!anim->frame_durations) {
|
||||||
pxl8_error("Failed to allocate frame durations");
|
pxl8_error("Failed to allocate frame durations");
|
||||||
free(anim->frame_ids);
|
pxl8_free(anim->frame_ids);
|
||||||
free(anim);
|
pxl8_free(anim);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (u16 i = 0; i < frame_count; i++) {
|
for (u16 i = 0; i < frame_count; i++) {
|
||||||
|
|
@ -107,12 +108,12 @@ pxl8_anim* pxl8_anim_create_from_ase(pxl8_gfx* gfx, const char* path) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32* frame_ids = (u32*)malloc(ase_file.frame_count * sizeof(u32));
|
u32* frame_ids = (u32*)pxl8_malloc(ase_file.frame_count * sizeof(u32));
|
||||||
u16* frame_durations = (u16*)malloc(ase_file.frame_count * sizeof(u16));
|
u16* frame_durations = (u16*)pxl8_malloc(ase_file.frame_count * sizeof(u16));
|
||||||
if (!frame_ids || !frame_durations) {
|
if (!frame_ids || !frame_durations) {
|
||||||
pxl8_error("Failed to allocate frame arrays");
|
pxl8_error("Failed to allocate frame arrays");
|
||||||
free(frame_ids);
|
pxl8_free(frame_ids);
|
||||||
free(frame_durations);
|
pxl8_free(frame_durations);
|
||||||
pxl8_ase_destroy(&ase_file);
|
pxl8_ase_destroy(&ase_file);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -122,8 +123,8 @@ pxl8_anim* pxl8_anim_create_from_ase(pxl8_gfx* gfx, const char* path) {
|
||||||
result = pxl8_gfx_create_texture(gfx, frame->pixels, frame->width, frame->height);
|
result = pxl8_gfx_create_texture(gfx, frame->pixels, frame->width, frame->height);
|
||||||
if (result != PXL8_OK) {
|
if (result != PXL8_OK) {
|
||||||
pxl8_error("Failed to create texture for frame %u", i);
|
pxl8_error("Failed to create texture for frame %u", i);
|
||||||
free(frame_ids);
|
pxl8_free(frame_ids);
|
||||||
free(frame_durations);
|
pxl8_free(frame_durations);
|
||||||
pxl8_ase_destroy(&ase_file);
|
pxl8_ase_destroy(&ase_file);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -133,8 +134,8 @@ pxl8_anim* pxl8_anim_create_from_ase(pxl8_gfx* gfx, const char* path) {
|
||||||
|
|
||||||
pxl8_anim* anim = pxl8_anim_create(frame_ids, frame_durations, ase_file.frame_count);
|
pxl8_anim* anim = pxl8_anim_create(frame_ids, frame_durations, ase_file.frame_count);
|
||||||
|
|
||||||
free(frame_ids);
|
pxl8_free(frame_ids);
|
||||||
free(frame_durations);
|
pxl8_free(frame_durations);
|
||||||
pxl8_ase_destroy(&ase_file);
|
pxl8_ase_destroy(&ase_file);
|
||||||
|
|
||||||
return anim;
|
return anim;
|
||||||
|
|
@ -145,15 +146,15 @@ void pxl8_anim_destroy(pxl8_anim* anim) {
|
||||||
|
|
||||||
if (anim->state_machine) {
|
if (anim->state_machine) {
|
||||||
for (u16 i = 0; i < anim->state_machine->state_count; i++) {
|
for (u16 i = 0; i < anim->state_machine->state_count; i++) {
|
||||||
free(anim->state_machine->states[i].name);
|
pxl8_free(anim->state_machine->states[i].name);
|
||||||
pxl8_anim_destroy(anim->state_machine->states[i].anim);
|
pxl8_anim_destroy(anim->state_machine->states[i].anim);
|
||||||
}
|
}
|
||||||
free(anim->state_machine);
|
pxl8_free(anim->state_machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(anim->frame_ids);
|
pxl8_free(anim->frame_ids);
|
||||||
free(anim->frame_durations);
|
pxl8_free(anim->frame_durations);
|
||||||
free(anim);
|
pxl8_free(anim);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_anim_add_state(pxl8_anim* anim, const char* name, pxl8_anim* state_anim) {
|
pxl8_result pxl8_anim_add_state(pxl8_anim* anim, const char* name, pxl8_anim* state_anim) {
|
||||||
|
|
@ -162,7 +163,7 @@ pxl8_result pxl8_anim_add_state(pxl8_anim* anim, const char* name, pxl8_anim* st
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!anim->state_machine) {
|
if (!anim->state_machine) {
|
||||||
anim->state_machine = (pxl8_anim_state_machine*)calloc(1, sizeof(pxl8_anim_state_machine));
|
anim->state_machine = (pxl8_anim_state_machine*)pxl8_calloc(1, sizeof(pxl8_anim_state_machine));
|
||||||
if (!anim->state_machine) {
|
if (!anim->state_machine) {
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "pxl8_color.h"
|
#include "pxl8_color.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
typedef struct pxl8_skyline_fit {
|
typedef struct pxl8_skyline_fit {
|
||||||
bool found;
|
bool found;
|
||||||
|
|
@ -105,7 +106,7 @@ static bool pxl8_skyline_add_rect(pxl8_skyline* skyline, pxl8_point pos, u32 w,
|
||||||
|
|
||||||
if (skyline->count - nodes_to_remove + 1 > skyline->capacity) {
|
if (skyline->count - nodes_to_remove + 1 > skyline->capacity) {
|
||||||
u32 new_capacity = (skyline->count - nodes_to_remove + 1) * 2;
|
u32 new_capacity = (skyline->count - nodes_to_remove + 1) * 2;
|
||||||
pxl8_skyline_node* new_nodes = (pxl8_skyline_node*)realloc(
|
pxl8_skyline_node* new_nodes = (pxl8_skyline_node*)pxl8_realloc(
|
||||||
skyline->nodes,
|
skyline->nodes,
|
||||||
new_capacity * sizeof(pxl8_skyline_node)
|
new_capacity * sizeof(pxl8_skyline_node)
|
||||||
);
|
);
|
||||||
|
|
@ -144,44 +145,44 @@ static void pxl8_skyline_compact(pxl8_skyline* skyline) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_atlas* pxl8_atlas_create(u32 width, u32 height, pxl8_pixel_mode pixel_mode) {
|
pxl8_atlas* pxl8_atlas_create(u32 width, u32 height, pxl8_pixel_mode pixel_mode) {
|
||||||
pxl8_atlas* atlas = (pxl8_atlas*)calloc(1, sizeof(pxl8_atlas));
|
pxl8_atlas* atlas = (pxl8_atlas*)pxl8_calloc(1, sizeof(pxl8_atlas));
|
||||||
if (!atlas) return NULL;
|
if (!atlas) return NULL;
|
||||||
|
|
||||||
atlas->height = height;
|
atlas->height = height;
|
||||||
atlas->width = width;
|
atlas->width = width;
|
||||||
|
|
||||||
i32 bytes_per_pixel = pxl8_bytes_per_pixel(pixel_mode);
|
i32 bytes_per_pixel = pxl8_bytes_per_pixel(pixel_mode);
|
||||||
atlas->pixels = (u8*)calloc(width * height, bytes_per_pixel);
|
atlas->pixels = (u8*)pxl8_calloc(width * height, bytes_per_pixel);
|
||||||
if (!atlas->pixels) {
|
if (!atlas->pixels) {
|
||||||
free(atlas);
|
pxl8_free(atlas);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
atlas->entry_capacity = PXL8_DEFAULT_ATLAS_ENTRY_CAPACITY;
|
atlas->entry_capacity = PXL8_DEFAULT_ATLAS_ENTRY_CAPACITY;
|
||||||
atlas->entries = (pxl8_atlas_entry*)calloc(atlas->entry_capacity, sizeof(pxl8_atlas_entry));
|
atlas->entries = (pxl8_atlas_entry*)pxl8_calloc(atlas->entry_capacity, sizeof(pxl8_atlas_entry));
|
||||||
if (!atlas->entries) {
|
if (!atlas->entries) {
|
||||||
free(atlas->pixels);
|
pxl8_free(atlas->pixels);
|
||||||
free(atlas);
|
pxl8_free(atlas);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
atlas->free_capacity = 16;
|
atlas->free_capacity = 16;
|
||||||
atlas->free_list = (u32*)calloc(atlas->free_capacity, sizeof(u32));
|
atlas->free_list = (u32*)pxl8_calloc(atlas->free_capacity, sizeof(u32));
|
||||||
if (!atlas->free_list) {
|
if (!atlas->free_list) {
|
||||||
free(atlas->entries);
|
pxl8_free(atlas->entries);
|
||||||
free(atlas->pixels);
|
pxl8_free(atlas->pixels);
|
||||||
free(atlas);
|
pxl8_free(atlas);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
atlas->skyline.capacity = 16;
|
atlas->skyline.capacity = 16;
|
||||||
atlas->skyline.nodes =
|
atlas->skyline.nodes =
|
||||||
(pxl8_skyline_node*)calloc(atlas->skyline.capacity, sizeof(pxl8_skyline_node));
|
(pxl8_skyline_node*)pxl8_calloc(atlas->skyline.capacity, sizeof(pxl8_skyline_node));
|
||||||
if (!atlas->skyline.nodes) {
|
if (!atlas->skyline.nodes) {
|
||||||
free(atlas->free_list);
|
pxl8_free(atlas->free_list);
|
||||||
free(atlas->entries);
|
pxl8_free(atlas->entries);
|
||||||
free(atlas->pixels);
|
pxl8_free(atlas->pixels);
|
||||||
free(atlas);
|
pxl8_free(atlas);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,12 +195,12 @@ pxl8_atlas* pxl8_atlas_create(u32 width, u32 height, pxl8_pixel_mode pixel_mode)
|
||||||
void pxl8_atlas_destroy(pxl8_atlas* atlas) {
|
void pxl8_atlas_destroy(pxl8_atlas* atlas) {
|
||||||
if (!atlas) return;
|
if (!atlas) return;
|
||||||
|
|
||||||
free(atlas->entries);
|
pxl8_free(atlas->entries);
|
||||||
free(atlas->free_list);
|
pxl8_free(atlas->free_list);
|
||||||
free(atlas->pixels);
|
pxl8_free(atlas->pixels);
|
||||||
free(atlas->pixels_tiled);
|
pxl8_free(atlas->pixels_tiled);
|
||||||
free(atlas->skyline.nodes);
|
pxl8_free(atlas->skyline.nodes);
|
||||||
free(atlas);
|
pxl8_free(atlas);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_atlas_clear(pxl8_atlas* atlas, u32 preserve_count) {
|
void pxl8_atlas_clear(pxl8_atlas* atlas, u32 preserve_count) {
|
||||||
|
|
@ -232,13 +233,13 @@ bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_pixel_mode pixel_mode) {
|
||||||
u32 new_size = atlas->width * 2;
|
u32 new_size = atlas->width * 2;
|
||||||
u32 old_width = atlas->width;
|
u32 old_width = atlas->width;
|
||||||
|
|
||||||
u8* new_pixels = (u8*)calloc(new_size * new_size, bytes_per_pixel);
|
u8* new_pixels = (u8*)pxl8_calloc(new_size * new_size, bytes_per_pixel);
|
||||||
if (!new_pixels) return false;
|
if (!new_pixels) return false;
|
||||||
|
|
||||||
pxl8_skyline new_skyline;
|
pxl8_skyline new_skyline;
|
||||||
new_skyline.nodes = (pxl8_skyline_node*)calloc(16, sizeof(pxl8_skyline_node));
|
new_skyline.nodes = (pxl8_skyline_node*)pxl8_calloc(16, sizeof(pxl8_skyline_node));
|
||||||
if (!new_skyline.nodes) {
|
if (!new_skyline.nodes) {
|
||||||
free(new_pixels);
|
pxl8_free(new_pixels);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,8 +259,8 @@ bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_pixel_mode pixel_mode) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!fit.found) {
|
if (!fit.found) {
|
||||||
free(new_skyline.nodes);
|
pxl8_free(new_skyline.nodes);
|
||||||
free(new_pixels);
|
pxl8_free(new_pixels);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,15 +280,15 @@ bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_pixel_mode pixel_mode) {
|
||||||
atlas->entries[i].y = fit.pos.y;
|
atlas->entries[i].y = fit.pos.y;
|
||||||
|
|
||||||
if (!pxl8_skyline_add_rect(&new_skyline, fit.pos, atlas->entries[i].w, atlas->entries[i].h)) {
|
if (!pxl8_skyline_add_rect(&new_skyline, fit.pos, atlas->entries[i].w, atlas->entries[i].h)) {
|
||||||
free(new_skyline.nodes);
|
pxl8_free(new_skyline.nodes);
|
||||||
free(new_pixels);
|
pxl8_free(new_pixels);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pxl8_skyline_compact(&new_skyline);
|
pxl8_skyline_compact(&new_skyline);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(atlas->pixels);
|
pxl8_free(atlas->pixels);
|
||||||
free(atlas->skyline.nodes);
|
pxl8_free(atlas->skyline.nodes);
|
||||||
|
|
||||||
atlas->pixels = new_pixels;
|
atlas->pixels = new_pixels;
|
||||||
atlas->skyline = new_skyline;
|
atlas->skyline = new_skyline;
|
||||||
|
|
@ -326,7 +327,7 @@ u32 pxl8_atlas_add_texture(
|
||||||
} else {
|
} else {
|
||||||
if (atlas->entry_count >= atlas->entry_capacity) {
|
if (atlas->entry_count >= atlas->entry_capacity) {
|
||||||
u32 new_capacity = atlas->entry_capacity * 2;
|
u32 new_capacity = atlas->entry_capacity * 2;
|
||||||
pxl8_atlas_entry* new_entries = (pxl8_atlas_entry*)realloc(
|
pxl8_atlas_entry* new_entries = (pxl8_atlas_entry*)pxl8_realloc(
|
||||||
atlas->entries,
|
atlas->entries,
|
||||||
new_capacity * sizeof(pxl8_atlas_entry)
|
new_capacity * sizeof(pxl8_atlas_entry)
|
||||||
);
|
);
|
||||||
|
|
@ -365,7 +366,7 @@ u32 pxl8_atlas_add_texture(
|
||||||
if (new_tiled_size > atlas->tiled_capacity) {
|
if (new_tiled_size > atlas->tiled_capacity) {
|
||||||
u32 new_cap = atlas->tiled_capacity ? atlas->tiled_capacity * 2 : 4096;
|
u32 new_cap = atlas->tiled_capacity ? atlas->tiled_capacity * 2 : 4096;
|
||||||
while (new_cap < new_tiled_size) new_cap *= 2;
|
while (new_cap < new_tiled_size) new_cap *= 2;
|
||||||
u8* new_tiled = (u8*)realloc(atlas->pixels_tiled, new_cap);
|
u8* new_tiled = (u8*)pxl8_realloc(atlas->pixels_tiled, new_cap);
|
||||||
if (!new_tiled) {
|
if (!new_tiled) {
|
||||||
entry->active = false;
|
entry->active = false;
|
||||||
return UINT32_MAX;
|
return UINT32_MAX;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "pxl8_cpu.h"
|
#include "pxl8_cpu.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -173,7 +174,7 @@ static inline void clip_line_2d(i32* x0, i32* y0, i32* x1, i32* y1, i32 w, i32 h
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_cpu_backend* pxl8_cpu_create(u32 width, u32 height) {
|
pxl8_cpu_backend* pxl8_cpu_create(u32 width, u32 height) {
|
||||||
pxl8_cpu_backend* cpu = calloc(1, sizeof(pxl8_cpu_backend));
|
pxl8_cpu_backend* cpu = pxl8_calloc(1, sizeof(pxl8_cpu_backend));
|
||||||
if (!cpu) return NULL;
|
if (!cpu) return NULL;
|
||||||
|
|
||||||
pxl8_cpu_render_target_desc desc = {
|
pxl8_cpu_render_target_desc desc = {
|
||||||
|
|
@ -184,7 +185,7 @@ pxl8_cpu_backend* pxl8_cpu_create(u32 width, u32 height) {
|
||||||
};
|
};
|
||||||
pxl8_cpu_render_target* base_target = pxl8_cpu_create_render_target(&desc);
|
pxl8_cpu_render_target* base_target = pxl8_cpu_create_render_target(&desc);
|
||||||
if (!base_target) {
|
if (!base_target) {
|
||||||
free(cpu);
|
pxl8_free(cpu);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,10 +194,10 @@ pxl8_cpu_backend* pxl8_cpu_create(u32 width, u32 height) {
|
||||||
cpu->current_target = base_target;
|
cpu->current_target = base_target;
|
||||||
|
|
||||||
cpu->output_size = width * height;
|
cpu->output_size = width * height;
|
||||||
cpu->output = calloc(cpu->output_size, sizeof(u32));
|
cpu->output = pxl8_calloc(cpu->output_size, sizeof(u32));
|
||||||
if (!cpu->output) {
|
if (!cpu->output) {
|
||||||
pxl8_cpu_destroy_render_target(base_target);
|
pxl8_cpu_destroy_render_target(base_target);
|
||||||
free(cpu);
|
pxl8_free(cpu);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,8 +209,8 @@ void pxl8_cpu_destroy(pxl8_cpu_backend* cpu) {
|
||||||
for (u32 i = 0; i < cpu->target_stack_depth; i++) {
|
for (u32 i = 0; i < cpu->target_stack_depth; i++) {
|
||||||
pxl8_cpu_destroy_render_target(cpu->target_stack[i]);
|
pxl8_cpu_destroy_render_target(cpu->target_stack[i]);
|
||||||
}
|
}
|
||||||
free(cpu->output);
|
pxl8_free(cpu->output);
|
||||||
free(cpu);
|
pxl8_free(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_cpu_begin_frame(pxl8_cpu_backend* cpu, const pxl8_3d_frame* frame) {
|
void pxl8_cpu_begin_frame(pxl8_cpu_backend* cpu, const pxl8_3d_frame* frame) {
|
||||||
|
|
@ -1194,33 +1195,33 @@ u32 pxl8_cpu_get_width(const pxl8_cpu_backend* cpu) {
|
||||||
pxl8_cpu_render_target* pxl8_cpu_create_render_target(const pxl8_cpu_render_target_desc* desc) {
|
pxl8_cpu_render_target* pxl8_cpu_create_render_target(const pxl8_cpu_render_target_desc* desc) {
|
||||||
if (!desc) return NULL;
|
if (!desc) return NULL;
|
||||||
|
|
||||||
pxl8_cpu_render_target* target = calloc(1, sizeof(pxl8_cpu_render_target));
|
pxl8_cpu_render_target* target = pxl8_calloc(1, sizeof(pxl8_cpu_render_target));
|
||||||
if (!target) return NULL;
|
if (!target) return NULL;
|
||||||
|
|
||||||
u32 size = desc->width * desc->height;
|
u32 size = desc->width * desc->height;
|
||||||
target->width = desc->width;
|
target->width = desc->width;
|
||||||
target->height = desc->height;
|
target->height = desc->height;
|
||||||
target->framebuffer = calloc(size, sizeof(u8));
|
target->framebuffer = pxl8_calloc(size, sizeof(u8));
|
||||||
if (!target->framebuffer) {
|
if (!target->framebuffer) {
|
||||||
free(target);
|
pxl8_free(target);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc->with_depth) {
|
if (desc->with_depth) {
|
||||||
target->zbuffer = calloc(size, sizeof(u16));
|
target->zbuffer = pxl8_calloc(size, sizeof(u16));
|
||||||
if (!target->zbuffer) {
|
if (!target->zbuffer) {
|
||||||
free(target->framebuffer);
|
pxl8_free(target->framebuffer);
|
||||||
free(target);
|
pxl8_free(target);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc->with_lighting) {
|
if (desc->with_lighting) {
|
||||||
target->light_accum = calloc(size, sizeof(u32));
|
target->light_accum = pxl8_calloc(size, sizeof(u32));
|
||||||
if (!target->light_accum) {
|
if (!target->light_accum) {
|
||||||
free(target->zbuffer);
|
pxl8_free(target->zbuffer);
|
||||||
free(target->framebuffer);
|
pxl8_free(target->framebuffer);
|
||||||
free(target);
|
pxl8_free(target);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1230,10 +1231,10 @@ pxl8_cpu_render_target* pxl8_cpu_create_render_target(const pxl8_cpu_render_targ
|
||||||
|
|
||||||
void pxl8_cpu_destroy_render_target(pxl8_cpu_render_target* target) {
|
void pxl8_cpu_destroy_render_target(pxl8_cpu_render_target* target) {
|
||||||
if (!target) return;
|
if (!target) return;
|
||||||
free(target->light_accum);
|
pxl8_free(target->light_accum);
|
||||||
free(target->zbuffer);
|
pxl8_free(target->zbuffer);
|
||||||
free(target->framebuffer);
|
pxl8_free(target->framebuffer);
|
||||||
free(target);
|
pxl8_free(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_cpu_render_target* pxl8_cpu_get_target(pxl8_cpu_backend* cpu) {
|
pxl8_cpu_render_target* pxl8_cpu_get_target(pxl8_cpu_backend* cpu) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "pxl8_font.h"
|
#include "pxl8_font.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -15,7 +16,7 @@ pxl8_result pxl8_font_create_atlas(const pxl8_font* font, u8** atlas_data, i32*
|
||||||
*atlas_height = rows_needed * font->default_height;
|
*atlas_height = rows_needed * font->default_height;
|
||||||
|
|
||||||
i32 atlas_size = (*atlas_width) * (*atlas_height);
|
i32 atlas_size = (*atlas_width) * (*atlas_height);
|
||||||
*atlas_data = (u8*)malloc(atlas_size);
|
*atlas_data = (u8*)pxl8_malloc(atlas_size);
|
||||||
if (!*atlas_data) {
|
if (!*atlas_data) {
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
#include "pxl8_macros.h"
|
#include "pxl8_macros.h"
|
||||||
#include "pxl8_math.h"
|
#include "pxl8_math.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
#include "pxl8_sys.h"
|
#include "pxl8_sys.h"
|
||||||
#include "pxl8_types.h"
|
#include "pxl8_types.h"
|
||||||
|
|
||||||
|
|
@ -122,7 +123,7 @@ pxl8_gfx* pxl8_gfx_create(
|
||||||
pxl8_pixel_mode mode,
|
pxl8_pixel_mode mode,
|
||||||
pxl8_resolution resolution
|
pxl8_resolution resolution
|
||||||
) {
|
) {
|
||||||
pxl8_gfx* gfx = (pxl8_gfx*)calloc(1, sizeof(pxl8_gfx));
|
pxl8_gfx* gfx = (pxl8_gfx*)pxl8_calloc(1, sizeof(pxl8_gfx));
|
||||||
if (!gfx) {
|
if (!gfx) {
|
||||||
pxl8_error("Failed to allocate graphics context");
|
pxl8_error("Failed to allocate graphics context");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -138,7 +139,7 @@ pxl8_gfx* pxl8_gfx_create(
|
||||||
|
|
||||||
if (!gfx->platform_data) {
|
if (!gfx->platform_data) {
|
||||||
pxl8_error("Platform data cannot be NULL");
|
pxl8_error("Platform data cannot be NULL");
|
||||||
free(gfx);
|
pxl8_free(gfx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +158,7 @@ pxl8_gfx* pxl8_gfx_create(
|
||||||
gfx->framebuffer = pxl8_cpu_get_framebuffer(gfx->backend.cpu);
|
gfx->framebuffer = pxl8_cpu_get_framebuffer(gfx->backend.cpu);
|
||||||
|
|
||||||
if (mode != PXL8_PIXEL_HICOLOR) {
|
if (mode != PXL8_PIXEL_HICOLOR) {
|
||||||
gfx->colormap = calloc(1, sizeof(pxl8_colormap));
|
gfx->colormap = pxl8_calloc(1, sizeof(pxl8_colormap));
|
||||||
if (gfx->colormap) {
|
if (gfx->colormap) {
|
||||||
pxl8_cpu_set_colormap(gfx->backend.cpu, gfx->colormap);
|
pxl8_cpu_set_colormap(gfx->backend.cpu, gfx->colormap);
|
||||||
}
|
}
|
||||||
|
|
@ -180,12 +181,12 @@ void pxl8_gfx_destroy(pxl8_gfx* gfx) {
|
||||||
if (gfx->backend.type == PXL8_GFX_BACKEND_CPU) {
|
if (gfx->backend.type == PXL8_GFX_BACKEND_CPU) {
|
||||||
pxl8_cpu_destroy(gfx->backend.cpu);
|
pxl8_cpu_destroy(gfx->backend.cpu);
|
||||||
}
|
}
|
||||||
free(gfx->colormap);
|
pxl8_free(gfx->colormap);
|
||||||
pxl8_palette_cube_destroy(gfx->palette_cube);
|
pxl8_palette_cube_destroy(gfx->palette_cube);
|
||||||
pxl8_palette_destroy(gfx->palette);
|
pxl8_palette_destroy(gfx->palette);
|
||||||
free(gfx->sprite_cache);
|
pxl8_free(gfx->sprite_cache);
|
||||||
|
|
||||||
free(gfx);
|
pxl8_free(gfx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static pxl8_result pxl8_gfx_ensure_atlas(pxl8_gfx* gfx) {
|
static pxl8_result pxl8_gfx_ensure_atlas(pxl8_gfx* gfx) {
|
||||||
|
|
@ -226,7 +227,7 @@ pxl8_result pxl8_gfx_load_sprite(pxl8_gfx* gfx, const char* path) {
|
||||||
|
|
||||||
if (!gfx->sprite_cache) {
|
if (!gfx->sprite_cache) {
|
||||||
gfx->sprite_cache_capacity = PXL8_DEFAULT_SPRITE_CACHE_CAPACITY;
|
gfx->sprite_cache_capacity = PXL8_DEFAULT_SPRITE_CACHE_CAPACITY;
|
||||||
gfx->sprite_cache = (pxl8_sprite_cache_entry*)calloc(
|
gfx->sprite_cache = (pxl8_sprite_cache_entry*)pxl8_calloc(
|
||||||
gfx->sprite_cache_capacity, sizeof(pxl8_sprite_cache_entry)
|
gfx->sprite_cache_capacity, sizeof(pxl8_sprite_cache_entry)
|
||||||
);
|
);
|
||||||
if (!gfx->sprite_cache) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!gfx->sprite_cache) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
@ -271,7 +272,7 @@ pxl8_result pxl8_gfx_load_sprite(pxl8_gfx* gfx, const char* path) {
|
||||||
|
|
||||||
if (gfx->sprite_cache_count >= gfx->sprite_cache_capacity) {
|
if (gfx->sprite_cache_count >= gfx->sprite_cache_capacity) {
|
||||||
u32 new_capacity = gfx->sprite_cache_capacity * 2;
|
u32 new_capacity = gfx->sprite_cache_capacity * 2;
|
||||||
pxl8_sprite_cache_entry* new_cache = (pxl8_sprite_cache_entry*)realloc(
|
pxl8_sprite_cache_entry* new_cache = (pxl8_sprite_cache_entry*)pxl8_realloc(
|
||||||
gfx->sprite_cache,
|
gfx->sprite_cache,
|
||||||
new_capacity * sizeof(pxl8_sprite_cache_entry)
|
new_capacity * sizeof(pxl8_sprite_cache_entry)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "pxl8_glows.h"
|
#include "pxl8_glows.h"
|
||||||
|
|
||||||
#include "pxl8_gfx.h"
|
#include "pxl8_gfx.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
@ -11,12 +12,12 @@ struct pxl8_glows {
|
||||||
};
|
};
|
||||||
|
|
||||||
pxl8_glows* pxl8_glows_create(u32 capacity) {
|
pxl8_glows* pxl8_glows_create(u32 capacity) {
|
||||||
pxl8_glows* glows = calloc(1, sizeof(pxl8_glows));
|
pxl8_glows* glows = pxl8_calloc(1, sizeof(pxl8_glows));
|
||||||
if (!glows) return NULL;
|
if (!glows) return NULL;
|
||||||
|
|
||||||
glows->data = calloc(capacity, sizeof(pxl8_glow));
|
glows->data = pxl8_calloc(capacity, sizeof(pxl8_glow));
|
||||||
if (!glows->data) {
|
if (!glows->data) {
|
||||||
free(glows);
|
pxl8_free(glows);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,8 +29,8 @@ pxl8_glows* pxl8_glows_create(u32 capacity) {
|
||||||
|
|
||||||
void pxl8_glows_destroy(pxl8_glows* glows) {
|
void pxl8_glows_destroy(pxl8_glows* glows) {
|
||||||
if (!glows) return;
|
if (!glows) return;
|
||||||
free(glows->data);
|
pxl8_free(glows->data);
|
||||||
free(glows);
|
pxl8_free(glows);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape) {
|
void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape) {
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
#include "pxl8_lightmap.h"
|
#include "pxl8_lightmap.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
pxl8_lightmap* pxl8_lightmap_create(u32 width, u32 height, u32 scale) {
|
pxl8_lightmap* pxl8_lightmap_create(u32 width, u32 height, u32 scale) {
|
||||||
pxl8_lightmap* lm = calloc(1, sizeof(pxl8_lightmap));
|
pxl8_lightmap* lm = pxl8_calloc(1, sizeof(pxl8_lightmap));
|
||||||
if (!lm) return NULL;
|
if (!lm) return NULL;
|
||||||
|
|
||||||
lm->width = width;
|
lm->width = width;
|
||||||
lm->height = height;
|
lm->height = height;
|
||||||
lm->scale = scale;
|
lm->scale = scale;
|
||||||
lm->data = calloc(width * height * 3, sizeof(u8));
|
lm->data = pxl8_calloc(width * height * 3, sizeof(u8));
|
||||||
if (!lm->data) {
|
if (!lm->data) {
|
||||||
free(lm);
|
pxl8_free(lm);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -22,8 +23,8 @@ pxl8_lightmap* pxl8_lightmap_create(u32 width, u32 height, u32 scale) {
|
||||||
|
|
||||||
void pxl8_lightmap_destroy(pxl8_lightmap* lm) {
|
void pxl8_lightmap_destroy(pxl8_lightmap* lm) {
|
||||||
if (!lm) return;
|
if (!lm) return;
|
||||||
free(lm->data);
|
pxl8_free(lm->data);
|
||||||
free(lm);
|
pxl8_free(lm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_lightmap_clear(pxl8_lightmap* lm, u8 r, u8 g, u8 b) {
|
void pxl8_lightmap_clear(pxl8_lightmap* lm, u8 r, u8 g, u8 b) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "pxl8_lights.h"
|
#include "pxl8_lights.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
@ -11,12 +12,12 @@ struct pxl8_lights {
|
||||||
pxl8_lights* pxl8_lights_create(u32 capacity) {
|
pxl8_lights* pxl8_lights_create(u32 capacity) {
|
||||||
if (capacity > PXL8_LIGHTS_MAX) capacity = PXL8_LIGHTS_MAX;
|
if (capacity > PXL8_LIGHTS_MAX) capacity = PXL8_LIGHTS_MAX;
|
||||||
|
|
||||||
pxl8_lights* lights = calloc(1, sizeof(pxl8_lights));
|
pxl8_lights* lights = pxl8_calloc(1, sizeof(pxl8_lights));
|
||||||
if (!lights) return NULL;
|
if (!lights) return NULL;
|
||||||
|
|
||||||
lights->data = calloc(capacity, sizeof(pxl8_light));
|
lights->data = pxl8_calloc(capacity, sizeof(pxl8_light));
|
||||||
if (!lights->data) {
|
if (!lights->data) {
|
||||||
free(lights);
|
pxl8_free(lights);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,8 +29,8 @@ pxl8_lights* pxl8_lights_create(u32 capacity) {
|
||||||
|
|
||||||
void pxl8_lights_destroy(pxl8_lights* lights) {
|
void pxl8_lights_destroy(pxl8_lights* lights) {
|
||||||
if (!lights) return;
|
if (!lights) return;
|
||||||
free(lights->data);
|
pxl8_free(lights->data);
|
||||||
free(lights);
|
pxl8_free(lights);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, u8 intensity, f32 radius) {
|
void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, u8 intensity, f32 radius) {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "pxl8_mem.h"
|
||||||
#include "pxl8_mesh.h"
|
#include "pxl8_mesh.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -6,16 +7,16 @@ pxl8_mesh* pxl8_mesh_create(u32 vertex_capacity, u32 index_capacity) {
|
||||||
if (vertex_capacity > PXL8_MESH_MAX_VERTICES) vertex_capacity = PXL8_MESH_MAX_VERTICES;
|
if (vertex_capacity > PXL8_MESH_MAX_VERTICES) vertex_capacity = PXL8_MESH_MAX_VERTICES;
|
||||||
if (index_capacity > PXL8_MESH_MAX_INDICES) index_capacity = PXL8_MESH_MAX_INDICES;
|
if (index_capacity > PXL8_MESH_MAX_INDICES) index_capacity = PXL8_MESH_MAX_INDICES;
|
||||||
|
|
||||||
pxl8_mesh* mesh = calloc(1, sizeof(pxl8_mesh));
|
pxl8_mesh* mesh = pxl8_calloc(1, sizeof(pxl8_mesh));
|
||||||
if (!mesh) return NULL;
|
if (!mesh) return NULL;
|
||||||
|
|
||||||
mesh->vertices = calloc(vertex_capacity, sizeof(pxl8_vertex));
|
mesh->vertices = pxl8_calloc(vertex_capacity, sizeof(pxl8_vertex));
|
||||||
mesh->indices = calloc(index_capacity, sizeof(u16));
|
mesh->indices = pxl8_calloc(index_capacity, sizeof(u16));
|
||||||
|
|
||||||
if (!mesh->vertices || !mesh->indices) {
|
if (!mesh->vertices || !mesh->indices) {
|
||||||
free(mesh->vertices);
|
pxl8_free(mesh->vertices);
|
||||||
free(mesh->indices);
|
pxl8_free(mesh->indices);
|
||||||
free(mesh);
|
pxl8_free(mesh);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,9 +30,9 @@ pxl8_mesh* pxl8_mesh_create(u32 vertex_capacity, u32 index_capacity) {
|
||||||
|
|
||||||
void pxl8_mesh_destroy(pxl8_mesh* mesh) {
|
void pxl8_mesh_destroy(pxl8_mesh* mesh) {
|
||||||
if (!mesh) return;
|
if (!mesh) return;
|
||||||
free(mesh->vertices);
|
pxl8_free(mesh->vertices);
|
||||||
free(mesh->indices);
|
pxl8_free(mesh->indices);
|
||||||
free(mesh);
|
pxl8_free(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_mesh_clear(pxl8_mesh* mesh) {
|
void pxl8_mesh_clear(pxl8_mesh* mesh) {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "pxl8_color.h"
|
#include "pxl8_color.h"
|
||||||
#include "pxl8_colormap.h"
|
#include "pxl8_colormap.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#define PXL8_PALETTE_HASH_SIZE 512
|
#define PXL8_PALETTE_HASH_SIZE 512
|
||||||
|
|
||||||
|
|
@ -207,7 +208,7 @@ static void update_cycle_colors(pxl8_palette* pal, u8 slot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_palette* pxl8_palette_create(void) {
|
pxl8_palette* pxl8_palette_create(void) {
|
||||||
pxl8_palette* pal = calloc(1, sizeof(pxl8_palette));
|
pxl8_palette* pal = pxl8_calloc(1, sizeof(pxl8_palette));
|
||||||
if (!pal) return NULL;
|
if (!pal) return NULL;
|
||||||
|
|
||||||
pal->colors[0] = 0x00000000;
|
pal->colors[0] = 0x00000000;
|
||||||
|
|
@ -228,7 +229,7 @@ pxl8_palette* pxl8_palette_create(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_palette_destroy(pxl8_palette* pal) {
|
void pxl8_palette_destroy(pxl8_palette* pal) {
|
||||||
free(pal);
|
pxl8_free(pal);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_palette_load_ase(pxl8_palette* pal, const char* path) {
|
pxl8_result pxl8_palette_load_ase(pxl8_palette* pal, const char* path) {
|
||||||
|
|
@ -517,14 +518,14 @@ static u8 find_closest_stable(const pxl8_palette* pal, u8 r, u8 g, u8 b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_palette_cube* pxl8_palette_cube_create(const pxl8_palette* pal) {
|
pxl8_palette_cube* pxl8_palette_cube_create(const pxl8_palette* pal) {
|
||||||
pxl8_palette_cube* cube = calloc(1, sizeof(pxl8_palette_cube));
|
pxl8_palette_cube* cube = pxl8_calloc(1, sizeof(pxl8_palette_cube));
|
||||||
if (!cube) return NULL;
|
if (!cube) return NULL;
|
||||||
pxl8_palette_cube_rebuild(cube, pal);
|
pxl8_palette_cube_rebuild(cube, pal);
|
||||||
return cube;
|
return cube;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_palette_cube_destroy(pxl8_palette_cube* cube) {
|
void pxl8_palette_cube_destroy(pxl8_palette_cube* cube) {
|
||||||
free(cube);
|
pxl8_free(cube);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_palette_cube_rebuild(pxl8_palette_cube* cube, const pxl8_palette* pal) {
|
void pxl8_palette_cube_rebuild(pxl8_palette_cube* cube, const pxl8_palette* pal) {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "pxl8_gfx.h"
|
#include "pxl8_gfx.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
#include "pxl8_gfx2d.h"
|
#include "pxl8_gfx2d.h"
|
||||||
#include "pxl8_palette.h"
|
#include "pxl8_palette.h"
|
||||||
#include "pxl8_rng.h"
|
#include "pxl8_rng.h"
|
||||||
|
|
@ -37,12 +38,12 @@ struct pxl8_particles {
|
||||||
};
|
};
|
||||||
|
|
||||||
pxl8_particles* pxl8_particles_create(u32 max_count, pxl8_rng* rng) {
|
pxl8_particles* pxl8_particles_create(u32 max_count, pxl8_rng* rng) {
|
||||||
pxl8_particles* ps = calloc(1, sizeof(pxl8_particles));
|
pxl8_particles* ps = pxl8_calloc(1, sizeof(pxl8_particles));
|
||||||
if (!ps) return NULL;
|
if (!ps) return NULL;
|
||||||
|
|
||||||
ps->particles = calloc(max_count, sizeof(pxl8_particle));
|
ps->particles = pxl8_calloc(max_count, sizeof(pxl8_particle));
|
||||||
if (!ps->particles) {
|
if (!ps->particles) {
|
||||||
free(ps);
|
pxl8_free(ps);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,8 +62,8 @@ pxl8_particles* pxl8_particles_create(u32 max_count, pxl8_rng* rng) {
|
||||||
|
|
||||||
void pxl8_particles_destroy(pxl8_particles* ps) {
|
void pxl8_particles_destroy(pxl8_particles* ps) {
|
||||||
if (!ps) return;
|
if (!ps) return;
|
||||||
free(ps->particles);
|
pxl8_free(ps->particles);
|
||||||
free(ps);
|
pxl8_free(ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_particles_clear(pxl8_particles* ps) {
|
void pxl8_particles_clear(pxl8_particles* ps) {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "pxl8_ase.h"
|
#include "pxl8_ase.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
#include "pxl8_macros.h"
|
#include "pxl8_macros.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
#include "pxl8_tilesheet.h"
|
#include "pxl8_tilesheet.h"
|
||||||
|
|
||||||
struct pxl8_tilesheet {
|
struct pxl8_tilesheet {
|
||||||
|
|
@ -58,7 +59,7 @@ static pxl8_tile_chunk* pxl8_get_or_create_chunk(pxl8_tilemap_layer* layer, u32
|
||||||
if (idx >= layer->chunks_wide * layer->chunks_high) return NULL;
|
if (idx >= layer->chunks_wide * layer->chunks_high) return NULL;
|
||||||
|
|
||||||
if (!layer->chunks[idx]) {
|
if (!layer->chunks[idx]) {
|
||||||
layer->chunks[idx] = calloc(1, sizeof(pxl8_tile_chunk));
|
layer->chunks[idx] = pxl8_calloc(1, sizeof(pxl8_tile_chunk));
|
||||||
if (!layer->chunks[idx]) return NULL;
|
if (!layer->chunks[idx]) return NULL;
|
||||||
|
|
||||||
layer->chunks[idx]->chunk_x = chunk_x;
|
layer->chunks[idx]->chunk_x = chunk_x;
|
||||||
|
|
@ -75,7 +76,7 @@ pxl8_tilemap* pxl8_tilemap_create(u32 width, u32 height, u32 tile_size) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_tilemap* tilemap = calloc(1, sizeof(pxl8_tilemap));
|
pxl8_tilemap* tilemap = pxl8_calloc(1, sizeof(pxl8_tilemap));
|
||||||
if (!tilemap) return NULL;
|
if (!tilemap) return NULL;
|
||||||
|
|
||||||
tilemap->width = width;
|
tilemap->width = width;
|
||||||
|
|
@ -85,7 +86,7 @@ pxl8_tilemap* pxl8_tilemap_create(u32 width, u32 height, u32 tile_size) {
|
||||||
|
|
||||||
tilemap->tilesheet = pxl8_tilesheet_create(tilemap->tile_size);
|
tilemap->tilesheet = pxl8_tilesheet_create(tilemap->tile_size);
|
||||||
if (!tilemap->tilesheet) {
|
if (!tilemap->tilesheet) {
|
||||||
free(tilemap);
|
pxl8_free(tilemap);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,13 +104,13 @@ pxl8_tilemap* pxl8_tilemap_create(u32 width, u32 height, u32 tile_size) {
|
||||||
layer->visible = (i == 0);
|
layer->visible = (i == 0);
|
||||||
layer->opacity = 255;
|
layer->opacity = 255;
|
||||||
|
|
||||||
layer->chunks = calloc(layer->chunk_count, sizeof(pxl8_tile_chunk*));
|
layer->chunks = pxl8_calloc(layer->chunk_count, sizeof(pxl8_tile_chunk*));
|
||||||
if (!layer->chunks) {
|
if (!layer->chunks) {
|
||||||
for (u32 j = 0; j < i; j++) {
|
for (u32 j = 0; j < i; j++) {
|
||||||
free(tilemap->layers[j].chunks);
|
pxl8_free(tilemap->layers[j].chunks);
|
||||||
}
|
}
|
||||||
if (tilemap->tilesheet) pxl8_tilesheet_destroy(tilemap->tilesheet);
|
if (tilemap->tilesheet) pxl8_tilesheet_destroy(tilemap->tilesheet);
|
||||||
free(tilemap);
|
pxl8_free(tilemap);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -125,17 +126,17 @@ void pxl8_tilemap_destroy(pxl8_tilemap* tilemap) {
|
||||||
if (layer->chunks) {
|
if (layer->chunks) {
|
||||||
for (u32 j = 0; j < layer->chunk_count; j++) {
|
for (u32 j = 0; j < layer->chunk_count; j++) {
|
||||||
if (layer->chunks[j]) {
|
if (layer->chunks[j]) {
|
||||||
free(layer->chunks[j]);
|
pxl8_free(layer->chunks[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(layer->chunks);
|
pxl8_free(layer->chunks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tilemap->tilesheet) pxl8_tilesheet_unref(tilemap->tilesheet);
|
if (tilemap->tilesheet) pxl8_tilesheet_unref(tilemap->tilesheet);
|
||||||
if (tilemap->tile_user_data) free(tilemap->tile_user_data);
|
if (tilemap->tile_user_data) pxl8_free(tilemap->tile_user_data);
|
||||||
|
|
||||||
free(tilemap);
|
pxl8_free(tilemap);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 pxl8_tilemap_get_width(const pxl8_tilemap* tilemap) {
|
u32 pxl8_tilemap_get_width(const pxl8_tilemap* tilemap) {
|
||||||
|
|
@ -155,7 +156,7 @@ void pxl8_tilemap_set_tile_user_data(pxl8_tilemap* tilemap, u16 tile_id, void* u
|
||||||
|
|
||||||
if (tile_id >= tilemap->tile_user_data_capacity) {
|
if (tile_id >= tilemap->tile_user_data_capacity) {
|
||||||
u32 new_capacity = tile_id + 64;
|
u32 new_capacity = tile_id + 64;
|
||||||
void** new_data = realloc(tilemap->tile_user_data, new_capacity * sizeof(void*));
|
void** new_data = pxl8_realloc(tilemap->tile_user_data, new_capacity * sizeof(void*));
|
||||||
if (!new_data) return;
|
if (!new_data) return;
|
||||||
|
|
||||||
for (u32 i = tilemap->tile_user_data_capacity; i < new_capacity; i++) {
|
for (u32 i = tilemap->tile_user_data_capacity; i < new_capacity; i++) {
|
||||||
|
|
@ -478,7 +479,7 @@ void pxl8_tilemap_compress(pxl8_tilemap* tilemap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_tiles) {
|
if (!has_tiles) {
|
||||||
free(chunk);
|
pxl8_free(chunk);
|
||||||
layer->chunks[j] = NULL;
|
layer->chunks[j] = NULL;
|
||||||
layer->allocated_chunks--;
|
layer->allocated_chunks--;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -535,8 +536,8 @@ pxl8_result pxl8_tilemap_load_ase(pxl8_tilemap* tilemap, const char* filepath, u
|
||||||
u32 tilesheet_width = tiles_per_row * tilemap->tile_size;
|
u32 tilesheet_width = tiles_per_row * tilemap->tile_size;
|
||||||
u32 tilesheet_height = tilesheet_rows * tilemap->tile_size;
|
u32 tilesheet_height = tilesheet_rows * tilemap->tile_size;
|
||||||
|
|
||||||
if (tilemap->tilesheet->data) free(tilemap->tilesheet->data);
|
if (tilemap->tilesheet->data) pxl8_free(tilemap->tilesheet->data);
|
||||||
tilemap->tilesheet->data = calloc(tilesheet_width * tilesheet_height, 1);
|
tilemap->tilesheet->data = pxl8_calloc(tilesheet_width * tilesheet_height, 1);
|
||||||
if (!tilemap->tilesheet->data) {
|
if (!tilemap->tilesheet->data) {
|
||||||
pxl8_ase_destroy(&ase_file);
|
pxl8_ase_destroy(&ase_file);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
@ -548,8 +549,8 @@ pxl8_result pxl8_tilemap_load_ase(pxl8_tilemap* tilemap, const char* filepath, u
|
||||||
tilemap->tilesheet->total_tiles = tileset->tile_count;
|
tilemap->tilesheet->total_tiles = tileset->tile_count;
|
||||||
tilemap->tilesheet->pixel_mode = PXL8_PIXEL_INDEXED;
|
tilemap->tilesheet->pixel_mode = PXL8_PIXEL_INDEXED;
|
||||||
|
|
||||||
if (tilemap->tilesheet->tile_valid) free(tilemap->tilesheet->tile_valid);
|
if (tilemap->tilesheet->tile_valid) pxl8_free(tilemap->tilesheet->tile_valid);
|
||||||
tilemap->tilesheet->tile_valid = calloc(tileset->tile_count + 1, sizeof(bool));
|
tilemap->tilesheet->tile_valid = pxl8_calloc(tileset->tile_count + 1, sizeof(bool));
|
||||||
|
|
||||||
for (u32 i = 0; i < tileset->tile_count; i++) {
|
for (u32 i = 0; i < tileset->tile_count; i++) {
|
||||||
u32 sheet_row = i / tiles_per_row;
|
u32 sheet_row = i / tiles_per_row;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "pxl8_color.h"
|
#include "pxl8_color.h"
|
||||||
#include "pxl8_gfx.h"
|
#include "pxl8_gfx.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
#include "pxl8_tilemap.h"
|
#include "pxl8_tilemap.h"
|
||||||
|
|
||||||
struct pxl8_tilesheet {
|
struct pxl8_tilesheet {
|
||||||
|
|
@ -32,7 +33,7 @@ struct pxl8_tilesheet {
|
||||||
};
|
};
|
||||||
|
|
||||||
pxl8_tilesheet* pxl8_tilesheet_create(u32 tile_size) {
|
pxl8_tilesheet* pxl8_tilesheet_create(u32 tile_size) {
|
||||||
pxl8_tilesheet* tilesheet = calloc(1, sizeof(pxl8_tilesheet));
|
pxl8_tilesheet* tilesheet = pxl8_calloc(1, sizeof(pxl8_tilesheet));
|
||||||
if (!tilesheet) return NULL;
|
if (!tilesheet) return NULL;
|
||||||
|
|
||||||
tilesheet->tile_size = tile_size;
|
tilesheet->tile_size = tile_size;
|
||||||
|
|
@ -45,37 +46,37 @@ void pxl8_tilesheet_destroy(pxl8_tilesheet* tilesheet) {
|
||||||
if (!tilesheet) return;
|
if (!tilesheet) return;
|
||||||
|
|
||||||
if (tilesheet->data) {
|
if (tilesheet->data) {
|
||||||
free(tilesheet->data);
|
pxl8_free(tilesheet->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tilesheet->tile_valid) {
|
if (tilesheet->tile_valid) {
|
||||||
free(tilesheet->tile_valid);
|
pxl8_free(tilesheet->tile_valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tilesheet->animations) {
|
if (tilesheet->animations) {
|
||||||
for (u32 i = 0; i < tilesheet->animation_count; i++) {
|
for (u32 i = 0; i < tilesheet->animation_count; i++) {
|
||||||
if (tilesheet->animations[i].frames) {
|
if (tilesheet->animations[i].frames) {
|
||||||
free(tilesheet->animations[i].frames);
|
pxl8_free(tilesheet->animations[i].frames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(tilesheet->animations);
|
pxl8_free(tilesheet->animations);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tilesheet->properties) {
|
if (tilesheet->properties) {
|
||||||
free(tilesheet->properties);
|
pxl8_free(tilesheet->properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tilesheet->autotile_rules) {
|
if (tilesheet->autotile_rules) {
|
||||||
for (u32 i = 0; i <= tilesheet->total_tiles; i++) {
|
for (u32 i = 0; i <= tilesheet->total_tiles; i++) {
|
||||||
if (tilesheet->autotile_rules[i]) {
|
if (tilesheet->autotile_rules[i]) {
|
||||||
free(tilesheet->autotile_rules[i]);
|
pxl8_free(tilesheet->autotile_rules[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(tilesheet->autotile_rules);
|
pxl8_free(tilesheet->autotile_rules);
|
||||||
free(tilesheet->autotile_rule_counts);
|
pxl8_free(tilesheet->autotile_rule_counts);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(tilesheet);
|
pxl8_free(tilesheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath, pxl8_gfx* gfx) {
|
pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath, pxl8_gfx* gfx) {
|
||||||
|
|
@ -89,7 +90,7 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tilesheet->data) {
|
if (tilesheet->data) {
|
||||||
free(tilesheet->data);
|
pxl8_free(tilesheet->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 width = ase_file.header.width;
|
u32 width = ase_file.header.width;
|
||||||
|
|
@ -111,8 +112,8 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
|
||||||
u16 ase_depth = ase_file.header.color_depth;
|
u16 ase_depth = ase_file.header.color_depth;
|
||||||
bool gfx_hicolor = (tilesheet->pixel_mode == PXL8_PIXEL_HICOLOR);
|
bool gfx_hicolor = (tilesheet->pixel_mode == PXL8_PIXEL_HICOLOR);
|
||||||
|
|
||||||
size_t data_size = pixel_count * pxl8_bytes_per_pixel(tilesheet->pixel_mode);
|
usize data_size = pixel_count * pxl8_bytes_per_pixel(tilesheet->pixel_mode);
|
||||||
tilesheet->data = malloc(data_size);
|
tilesheet->data = pxl8_malloc(data_size);
|
||||||
if (!tilesheet->data) {
|
if (!tilesheet->data) {
|
||||||
pxl8_ase_destroy(&ase_file);
|
pxl8_ase_destroy(&ase_file);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
@ -138,9 +139,9 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
|
||||||
} else if (ase_depth == 8 && gfx_hicolor) {
|
} else if (ase_depth == 8 && gfx_hicolor) {
|
||||||
pxl8_warn("Indexed ASE with hicolor gfx - storing as indexed");
|
pxl8_warn("Indexed ASE with hicolor gfx - storing as indexed");
|
||||||
tilesheet->pixel_mode = PXL8_PIXEL_INDEXED;
|
tilesheet->pixel_mode = PXL8_PIXEL_INDEXED;
|
||||||
u8* new_data = realloc(tilesheet->data, pixel_count);
|
u8* new_data = pxl8_realloc(tilesheet->data, pixel_count);
|
||||||
if (!new_data) {
|
if (!new_data) {
|
||||||
free(tilesheet->data);
|
pxl8_free(tilesheet->data);
|
||||||
tilesheet->data = NULL;
|
tilesheet->data = NULL;
|
||||||
pxl8_ase_destroy(&ase_file);
|
pxl8_ase_destroy(&ase_file);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
@ -149,16 +150,16 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
|
||||||
memcpy(tilesheet->data, src, pixel_count);
|
memcpy(tilesheet->data, src, pixel_count);
|
||||||
} else {
|
} else {
|
||||||
pxl8_error("Unsupported ASE color depth %d for gfx mode", ase_depth);
|
pxl8_error("Unsupported ASE color depth %d for gfx mode", ase_depth);
|
||||||
free(tilesheet->data);
|
pxl8_free(tilesheet->data);
|
||||||
tilesheet->data = NULL;
|
tilesheet->data = NULL;
|
||||||
pxl8_ase_destroy(&ase_file);
|
pxl8_ase_destroy(&ase_file);
|
||||||
return PXL8_ERROR_INVALID_ARGUMENT;
|
return PXL8_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tilesheet->tile_valid = calloc(tilesheet->total_tiles + 1, sizeof(bool));
|
tilesheet->tile_valid = pxl8_calloc(tilesheet->total_tiles + 1, sizeof(bool));
|
||||||
if (!tilesheet->tile_valid) {
|
if (!tilesheet->tile_valid) {
|
||||||
free(tilesheet->data);
|
pxl8_free(tilesheet->data);
|
||||||
tilesheet->data = NULL;
|
tilesheet->data = NULL;
|
||||||
pxl8_ase_destroy(&ase_file);
|
pxl8_ase_destroy(&ase_file);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
@ -259,14 +260,14 @@ pxl8_result pxl8_tilesheet_add_animation(pxl8_tilesheet* tilesheet, u16 base_til
|
||||||
if (base_tile_id == 0 || base_tile_id > tilesheet->total_tiles) return PXL8_ERROR_INVALID_ARGUMENT;
|
if (base_tile_id == 0 || base_tile_id > tilesheet->total_tiles) return PXL8_ERROR_INVALID_ARGUMENT;
|
||||||
|
|
||||||
if (!tilesheet->animations) {
|
if (!tilesheet->animations) {
|
||||||
tilesheet->animations = calloc(tilesheet->total_tiles + 1, sizeof(pxl8_tile_animation));
|
tilesheet->animations = pxl8_calloc(tilesheet->total_tiles + 1, sizeof(pxl8_tile_animation));
|
||||||
if (!tilesheet->animations) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!tilesheet->animations) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_tile_animation* anim = &tilesheet->animations[base_tile_id];
|
pxl8_tile_animation* anim = &tilesheet->animations[base_tile_id];
|
||||||
if (anim->frames) free(anim->frames);
|
if (anim->frames) pxl8_free(anim->frames);
|
||||||
|
|
||||||
anim->frames = malloc(frame_count * sizeof(u16));
|
anim->frames = pxl8_malloc(frame_count * sizeof(u16));
|
||||||
if (!anim->frames) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!anim->frames) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
memcpy(anim->frames, frames, frame_count * sizeof(u16));
|
memcpy(anim->frames, frames, frame_count * sizeof(u16));
|
||||||
|
|
@ -340,7 +341,7 @@ void pxl8_tilesheet_set_tile_property(pxl8_tilesheet* tilesheet, u16 tile_id,
|
||||||
if (!tilesheet || !props || tile_id == 0 || tile_id > tilesheet->total_tiles) return;
|
if (!tilesheet || !props || tile_id == 0 || tile_id > tilesheet->total_tiles) return;
|
||||||
|
|
||||||
if (!tilesheet->properties) {
|
if (!tilesheet->properties) {
|
||||||
tilesheet->properties = calloc(tilesheet->total_tiles + 1, sizeof(pxl8_tile_properties));
|
tilesheet->properties = pxl8_calloc(tilesheet->total_tiles + 1, sizeof(pxl8_tile_properties));
|
||||||
if (!tilesheet->properties) return;
|
if (!tilesheet->properties) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -365,15 +366,15 @@ pxl8_result pxl8_tilesheet_add_autotile_rule(pxl8_tilesheet* tilesheet, u16 base
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tilesheet->autotile_rules) {
|
if (!tilesheet->autotile_rules) {
|
||||||
tilesheet->autotile_rules = calloc(tilesheet->total_tiles + 1, sizeof(pxl8_autotile_rule*));
|
tilesheet->autotile_rules = pxl8_calloc(tilesheet->total_tiles + 1, sizeof(pxl8_autotile_rule*));
|
||||||
tilesheet->autotile_rule_counts = calloc(tilesheet->total_tiles + 1, sizeof(u32));
|
tilesheet->autotile_rule_counts = pxl8_calloc(tilesheet->total_tiles + 1, sizeof(u32));
|
||||||
if (!tilesheet->autotile_rules || !tilesheet->autotile_rule_counts) {
|
if (!tilesheet->autotile_rules || !tilesheet->autotile_rule_counts) {
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 count = tilesheet->autotile_rule_counts[base_tile_id];
|
u32 count = tilesheet->autotile_rule_counts[base_tile_id];
|
||||||
pxl8_autotile_rule* new_rules = realloc(tilesheet->autotile_rules[base_tile_id],
|
pxl8_autotile_rule* new_rules = pxl8_realloc(tilesheet->autotile_rules[base_tile_id],
|
||||||
(count + 1) * sizeof(pxl8_autotile_rule));
|
(count + 1) * sizeof(pxl8_autotile_rule));
|
||||||
if (!new_rules) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!new_rules) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "pxl8_gfx.h"
|
#include "pxl8_gfx.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
#include "pxl8_math.h"
|
#include "pxl8_math.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
pxl8_transition* pxl8_transition_create(pxl8_transition_type type, f32 duration) {
|
pxl8_transition* pxl8_transition_create(pxl8_transition_type type, f32 duration) {
|
||||||
if (duration <= 0.0f) {
|
if (duration <= 0.0f) {
|
||||||
|
|
@ -13,7 +14,7 @@ pxl8_transition* pxl8_transition_create(pxl8_transition_type type, f32 duration)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_transition* transition = (pxl8_transition*)calloc(1, sizeof(pxl8_transition));
|
pxl8_transition* transition = (pxl8_transition*)pxl8_calloc(1, sizeof(pxl8_transition));
|
||||||
if (!transition) {
|
if (!transition) {
|
||||||
pxl8_error("Failed to allocate transition");
|
pxl8_error("Failed to allocate transition");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -33,7 +34,7 @@ pxl8_transition* pxl8_transition_create(pxl8_transition_type type, f32 duration)
|
||||||
|
|
||||||
void pxl8_transition_destroy(pxl8_transition* transition) {
|
void pxl8_transition_destroy(pxl8_transition* transition) {
|
||||||
if (!transition) return;
|
if (!transition) return;
|
||||||
free(transition);
|
pxl8_free(transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 pxl8_transition_get_progress(const pxl8_transition* transition) {
|
f32 pxl8_transition_get_progress(const pxl8_transition* transition) {
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,10 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "pxl8_gfx.h"
|
#include "pxl8_gfx.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
pxl8_gui_state* pxl8_gui_state_create(void) {
|
pxl8_gui_state* pxl8_gui_state_create(void) {
|
||||||
pxl8_gui_state* state = (pxl8_gui_state*)malloc(sizeof(pxl8_gui_state));
|
pxl8_gui_state* state = (pxl8_gui_state*)pxl8_malloc(sizeof(pxl8_gui_state));
|
||||||
if (!state) return NULL;
|
if (!state) return NULL;
|
||||||
|
|
||||||
memset(state, 0, sizeof(pxl8_gui_state));
|
memset(state, 0, sizeof(pxl8_gui_state));
|
||||||
|
|
@ -15,7 +16,7 @@ pxl8_gui_state* pxl8_gui_state_create(void) {
|
||||||
|
|
||||||
void pxl8_gui_state_destroy(pxl8_gui_state* state) {
|
void pxl8_gui_state_destroy(pxl8_gui_state* state) {
|
||||||
if (!state) return;
|
if (!state) return;
|
||||||
free(state);
|
pxl8_free(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_gui_begin_frame(pxl8_gui_state* state, pxl8_gfx* gfx) {
|
void pxl8_gui_begin_frame(pxl8_gui_state* state, pxl8_gfx* gfx) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include "pxl8_sdl3.h"
|
#include "pxl8_hal.h"
|
||||||
|
|
||||||
#define SDL_MAIN_USE_CALLBACKS
|
#define SDL_MAIN_USE_CALLBACKS
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
@ -8,13 +8,15 @@
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
#include "pxl8_sys.h"
|
#include "pxl8_sys.h"
|
||||||
|
|
||||||
|
extern const pxl8_hal pxl8_hal_sdl3;
|
||||||
|
|
||||||
typedef struct pxl8_sdl3_context {
|
typedef struct pxl8_sdl3_context {
|
||||||
SDL_Texture* framebuffer;
|
SDL_Texture* framebuffer;
|
||||||
SDL_Renderer* renderer;
|
SDL_Renderer* renderer;
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
|
|
||||||
u32* rgba_buffer;
|
u32* rgba_buffer;
|
||||||
size_t rgba_buffer_size;
|
usize rgba_buffer_size;
|
||||||
} pxl8_sdl3_context;
|
} pxl8_sdl3_context;
|
||||||
|
|
||||||
static void* sdl3_create(i32 render_w, i32 render_h,
|
static void* sdl3_create(i32 render_w, i32 render_h,
|
||||||
|
|
@ -101,7 +103,7 @@ static void sdl3_upload_texture(void* platform_data, const void* pixels, u32 w,
|
||||||
if (!platform_data || !pixels) return;
|
if (!platform_data || !pixels) return;
|
||||||
|
|
||||||
pxl8_sdl3_context* ctx = (pxl8_sdl3_context*)platform_data;
|
pxl8_sdl3_context* ctx = (pxl8_sdl3_context*)platform_data;
|
||||||
size_t pixel_count = w * h;
|
usize pixel_count = w * h;
|
||||||
|
|
||||||
if (bpp == 4) {
|
if (bpp == 4) {
|
||||||
SDL_UpdateTexture(ctx->framebuffer, NULL, pixels, w * 4);
|
SDL_UpdateTexture(ctx->framebuffer, NULL, pixels, w * 4);
|
||||||
8
src/hal/pxl8_mem.h
Normal file
8
src/hal/pxl8_mem.h
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "pxl8_types.h"
|
||||||
|
|
||||||
|
void* pxl8_malloc(usize size);
|
||||||
|
void* pxl8_calloc(usize count, usize size);
|
||||||
|
void* pxl8_realloc(void* ptr, usize size);
|
||||||
|
void pxl8_free(void* ptr);
|
||||||
19
src/hal/pxl8_mem_sdl3.c
Normal file
19
src/hal/pxl8_mem_sdl3.c
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
void* pxl8_malloc(usize size) {
|
||||||
|
return SDL_malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* pxl8_calloc(usize count, usize size) {
|
||||||
|
return SDL_calloc(count, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* pxl8_realloc(void* ptr, usize size) {
|
||||||
|
return SDL_realloc(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pxl8_free(void* ptr) {
|
||||||
|
SDL_free(ptr);
|
||||||
|
}
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "pxl8_hal.h"
|
|
||||||
|
|
||||||
extern const pxl8_hal pxl8_hal_sdl3;
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "pxl8_net.h"
|
#include "pxl8_net.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -94,7 +95,7 @@ bool pxl8_net_connected(const pxl8_net* net) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_net* pxl8_net_create(const pxl8_net_config* config) {
|
pxl8_net* pxl8_net_create(const pxl8_net_config* config) {
|
||||||
pxl8_net* net = calloc(1, sizeof(pxl8_net));
|
pxl8_net* net = pxl8_calloc(1, sizeof(pxl8_net));
|
||||||
if (!net) return NULL;
|
if (!net) return NULL;
|
||||||
|
|
||||||
net->mode = config->mode;
|
net->mode = config->mode;
|
||||||
|
|
@ -116,7 +117,7 @@ pxl8_net* pxl8_net_create(const pxl8_net_config* config) {
|
||||||
void pxl8_net_destroy(pxl8_net* net) {
|
void pxl8_net_destroy(pxl8_net* net) {
|
||||||
if (!net) return;
|
if (!net) return;
|
||||||
pxl8_net_disconnect(net);
|
pxl8_net_disconnect(net);
|
||||||
free(net);
|
pxl8_free(net);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_net_disconnect(pxl8_net* net) {
|
void pxl8_net_disconnect(pxl8_net* net) {
|
||||||
|
|
@ -203,11 +204,11 @@ u64 pxl8_net_player_id(const pxl8_net* net) {
|
||||||
bool pxl8_net_poll(pxl8_net* net) {
|
bool pxl8_net_poll(pxl8_net* net) {
|
||||||
if (!net || !net->connected) return false;
|
if (!net || !net->connected) return false;
|
||||||
|
|
||||||
size_t len = pxl8_net_recv(net, net->recv_buf, sizeof(net->recv_buf));
|
usize len = pxl8_net_recv(net, net->recv_buf, sizeof(net->recv_buf));
|
||||||
if (len < sizeof(pxl8_msg_header)) return false;
|
if (len < sizeof(pxl8_msg_header)) return false;
|
||||||
|
|
||||||
pxl8_msg_header hdr;
|
pxl8_msg_header hdr;
|
||||||
size_t offset = pxl8_protocol_deserialize_header(net->recv_buf, len, &hdr);
|
usize offset = pxl8_protocol_deserialize_header(net->recv_buf, len, &hdr);
|
||||||
if (hdr.type != PXL8_MSG_SNAPSHOT) return false;
|
if (hdr.type != PXL8_MSG_SNAPSHOT) return false;
|
||||||
|
|
||||||
pxl8_snapshot_header snap;
|
pxl8_snapshot_header snap;
|
||||||
|
|
@ -243,17 +244,17 @@ void pxl8_net_predicted_tick_set(pxl8_net* net, u64 tick) {
|
||||||
net->predicted_tick = tick;
|
net->predicted_tick = tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_net_recv(pxl8_net* net, u8* buf, size_t len) {
|
usize pxl8_net_recv(pxl8_net* net, u8* buf, usize len) {
|
||||||
if (!net || !net->connected) return 0;
|
if (!net || !net->connected) return 0;
|
||||||
|
|
||||||
struct sockaddr_in from;
|
struct sockaddr_in from;
|
||||||
socklen_t from_len = sizeof(from);
|
socklen_t from_len = sizeof(from);
|
||||||
ssize_t received = recvfrom(net->sock, (char*)buf, len, 0,
|
ssize_t received = recvfrom(net->sock, (char*)buf, len, 0,
|
||||||
(struct sockaddr*)&from, &from_len);
|
(struct sockaddr*)&from, &from_len);
|
||||||
return (received > 0) ? (size_t)received : 0;
|
return (received > 0) ? (usize)received : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_net_send(pxl8_net* net, const u8* data, size_t len) {
|
pxl8_result pxl8_net_send(pxl8_net* net, const u8* data, usize len) {
|
||||||
if (!net || !net->connected) return PXL8_ERROR_INVALID_ARGUMENT;
|
if (!net || !net->connected) return PXL8_ERROR_INVALID_ARGUMENT;
|
||||||
|
|
||||||
ssize_t sent = sendto(net->sock, (const char*)data, len, 0,
|
ssize_t sent = sendto(net->sock, (const char*)data, len, 0,
|
||||||
|
|
@ -273,7 +274,7 @@ pxl8_result pxl8_net_send_command(pxl8_net* net, const pxl8_command_msg* cmd) {
|
||||||
.sequence = 0
|
.sequence = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t offset = pxl8_protocol_serialize_header(&hdr, buf, sizeof(buf));
|
usize offset = pxl8_protocol_serialize_header(&hdr, buf, sizeof(buf));
|
||||||
offset += pxl8_protocol_serialize_command(cmd, buf + offset, sizeof(buf) - offset);
|
offset += pxl8_protocol_serialize_command(cmd, buf + offset, sizeof(buf) - offset);
|
||||||
|
|
||||||
return pxl8_net_send(net, buf, offset);
|
return pxl8_net_send(net, buf, offset);
|
||||||
|
|
@ -290,7 +291,7 @@ pxl8_result pxl8_net_send_input(pxl8_net* net, const pxl8_input_msg* input) {
|
||||||
.sequence = 0
|
.sequence = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t offset = pxl8_protocol_serialize_header(&hdr, buf, sizeof(buf));
|
usize offset = pxl8_protocol_serialize_header(&hdr, buf, sizeof(buf));
|
||||||
offset += pxl8_protocol_serialize_input(input, buf + offset, sizeof(buf) - offset);
|
offset += pxl8_protocol_serialize_input(input, buf + offset, sizeof(buf) - offset);
|
||||||
|
|
||||||
return pxl8_net_send(net, buf, offset);
|
return pxl8_net_send(net, buf, offset);
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ u64 pxl8_net_player_id(const pxl8_net* net);
|
||||||
bool pxl8_net_poll(pxl8_net* net);
|
bool pxl8_net_poll(pxl8_net* net);
|
||||||
u8* pxl8_net_predicted_state(pxl8_net* net);
|
u8* pxl8_net_predicted_state(pxl8_net* net);
|
||||||
void pxl8_net_predicted_tick_set(pxl8_net* net, u64 tick);
|
void pxl8_net_predicted_tick_set(pxl8_net* net, u64 tick);
|
||||||
size_t pxl8_net_recv(pxl8_net* net, u8* buf, size_t len);
|
usize pxl8_net_recv(pxl8_net* net, u8* buf, usize len);
|
||||||
pxl8_result pxl8_net_send(pxl8_net* net, const u8* data, size_t len);
|
pxl8_result pxl8_net_send(pxl8_net* net, const u8* data, usize len);
|
||||||
pxl8_result pxl8_net_send_command(pxl8_net* net, const pxl8_command_msg* cmd);
|
pxl8_result pxl8_net_send_command(pxl8_net* net, const pxl8_command_msg* cmd);
|
||||||
pxl8_result pxl8_net_send_input(pxl8_net* net, const pxl8_input_msg* input);
|
pxl8_result pxl8_net_send_input(pxl8_net* net, const pxl8_input_msg* input);
|
||||||
const pxl8_snapshot_header* pxl8_net_snapshot(const pxl8_net* net);
|
const pxl8_snapshot_header* pxl8_net_snapshot(const pxl8_net* net);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include "pxl8_protocol.h"
|
#include "pxl8_protocol.h"
|
||||||
#include "pxl8_bytes.h"
|
#include "pxl8_bytes.h"
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_header(const pxl8_msg_header* msg, u8* buf, size_t len) {
|
usize pxl8_protocol_serialize_header(const pxl8_msg_header* msg, u8* buf, usize len) {
|
||||||
if (len < sizeof(pxl8_msg_header)) return 0;
|
if (len < sizeof(pxl8_msg_header)) return 0;
|
||||||
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
||||||
pxl8_write_u32_be(&s, msg->sequence);
|
pxl8_write_u32_be(&s, msg->sequence);
|
||||||
|
|
@ -11,7 +11,7 @@ size_t pxl8_protocol_serialize_header(const pxl8_msg_header* msg, u8* buf, size_
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_deserialize_header(const u8* buf, size_t len, pxl8_msg_header* msg) {
|
usize pxl8_protocol_deserialize_header(const u8* buf, usize len, pxl8_msg_header* msg) {
|
||||||
if (len < sizeof(pxl8_msg_header)) return 0;
|
if (len < sizeof(pxl8_msg_header)) return 0;
|
||||||
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
||||||
msg->sequence = pxl8_read_u32_be(&s);
|
msg->sequence = pxl8_read_u32_be(&s);
|
||||||
|
|
@ -21,7 +21,7 @@ size_t pxl8_protocol_deserialize_header(const u8* buf, size_t len, pxl8_msg_head
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_input(const pxl8_input_msg* msg, u8* buf, size_t len) {
|
usize pxl8_protocol_serialize_input(const pxl8_input_msg* msg, u8* buf, usize len) {
|
||||||
if (len < sizeof(pxl8_input_msg)) return 0;
|
if (len < sizeof(pxl8_input_msg)) return 0;
|
||||||
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
||||||
pxl8_write_u32_be(&s, msg->buttons);
|
pxl8_write_u32_be(&s, msg->buttons);
|
||||||
|
|
@ -35,7 +35,7 @@ size_t pxl8_protocol_serialize_input(const pxl8_input_msg* msg, u8* buf, size_t
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_deserialize_input(const u8* buf, size_t len, pxl8_input_msg* msg) {
|
usize pxl8_protocol_deserialize_input(const u8* buf, usize len, pxl8_input_msg* msg) {
|
||||||
if (len < sizeof(pxl8_input_msg)) return 0;
|
if (len < sizeof(pxl8_input_msg)) return 0;
|
||||||
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
||||||
msg->buttons = pxl8_read_u32_be(&s);
|
msg->buttons = pxl8_read_u32_be(&s);
|
||||||
|
|
@ -49,7 +49,7 @@ size_t pxl8_protocol_deserialize_input(const u8* buf, size_t len, pxl8_input_msg
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_command(const pxl8_command_msg* msg, u8* buf, size_t len) {
|
usize pxl8_protocol_serialize_command(const pxl8_command_msg* msg, u8* buf, usize len) {
|
||||||
if (len < sizeof(pxl8_command_msg)) return 0;
|
if (len < sizeof(pxl8_command_msg)) return 0;
|
||||||
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
||||||
pxl8_write_u16_be(&s, msg->cmd_type);
|
pxl8_write_u16_be(&s, msg->cmd_type);
|
||||||
|
|
@ -59,7 +59,7 @@ size_t pxl8_protocol_serialize_command(const pxl8_command_msg* msg, u8* buf, siz
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_deserialize_command(const u8* buf, size_t len, pxl8_command_msg* msg) {
|
usize pxl8_protocol_deserialize_command(const u8* buf, usize len, pxl8_command_msg* msg) {
|
||||||
if (len < sizeof(pxl8_command_msg)) return 0;
|
if (len < sizeof(pxl8_command_msg)) return 0;
|
||||||
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
||||||
msg->cmd_type = pxl8_read_u16_be(&s);
|
msg->cmd_type = pxl8_read_u16_be(&s);
|
||||||
|
|
@ -69,7 +69,7 @@ size_t pxl8_protocol_deserialize_command(const u8* buf, size_t len, pxl8_command
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_entity_state(const pxl8_entity_state* state, u8* buf, size_t len) {
|
usize pxl8_protocol_serialize_entity_state(const pxl8_entity_state* state, u8* buf, usize len) {
|
||||||
if (len < sizeof(pxl8_entity_state)) return 0;
|
if (len < sizeof(pxl8_entity_state)) return 0;
|
||||||
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
||||||
pxl8_write_u64_be(&s, state->entity_id);
|
pxl8_write_u64_be(&s, state->entity_id);
|
||||||
|
|
@ -77,7 +77,7 @@ size_t pxl8_protocol_serialize_entity_state(const pxl8_entity_state* state, u8*
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_deserialize_entity_state(const u8* buf, size_t len, pxl8_entity_state* state) {
|
usize pxl8_protocol_deserialize_entity_state(const u8* buf, usize len, pxl8_entity_state* state) {
|
||||||
if (len < sizeof(pxl8_entity_state)) return 0;
|
if (len < sizeof(pxl8_entity_state)) return 0;
|
||||||
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
||||||
state->entity_id = pxl8_read_u64_be(&s);
|
state->entity_id = pxl8_read_u64_be(&s);
|
||||||
|
|
@ -85,7 +85,7 @@ size_t pxl8_protocol_deserialize_entity_state(const u8* buf, size_t len, pxl8_en
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_event(const pxl8_event_msg* msg, u8* buf, size_t len) {
|
usize pxl8_protocol_serialize_event(const pxl8_event_msg* msg, u8* buf, usize len) {
|
||||||
if (len < sizeof(pxl8_event_msg)) return 0;
|
if (len < sizeof(pxl8_event_msg)) return 0;
|
||||||
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
||||||
pxl8_write_u8(&s, msg->event_type);
|
pxl8_write_u8(&s, msg->event_type);
|
||||||
|
|
@ -93,7 +93,7 @@ size_t pxl8_protocol_serialize_event(const pxl8_event_msg* msg, u8* buf, size_t
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_deserialize_event(const u8* buf, size_t len, pxl8_event_msg* msg) {
|
usize pxl8_protocol_deserialize_event(const u8* buf, usize len, pxl8_event_msg* msg) {
|
||||||
if (len < sizeof(pxl8_event_msg)) return 0;
|
if (len < sizeof(pxl8_event_msg)) return 0;
|
||||||
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
||||||
msg->event_type = pxl8_read_u8(&s);
|
msg->event_type = pxl8_read_u8(&s);
|
||||||
|
|
@ -101,7 +101,7 @@ size_t pxl8_protocol_deserialize_event(const u8* buf, size_t len, pxl8_event_msg
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_snapshot_header(const pxl8_snapshot_header* hdr, u8* buf, size_t len) {
|
usize pxl8_protocol_serialize_snapshot_header(const pxl8_snapshot_header* hdr, u8* buf, usize len) {
|
||||||
if (len < sizeof(pxl8_snapshot_header)) return 0;
|
if (len < sizeof(pxl8_snapshot_header)) return 0;
|
||||||
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len);
|
||||||
pxl8_write_u16_be(&s, hdr->entity_count);
|
pxl8_write_u16_be(&s, hdr->entity_count);
|
||||||
|
|
@ -112,7 +112,7 @@ size_t pxl8_protocol_serialize_snapshot_header(const pxl8_snapshot_header* hdr,
|
||||||
return s.offset;
|
return s.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pxl8_protocol_deserialize_snapshot_header(const u8* buf, size_t len, pxl8_snapshot_header* hdr) {
|
usize pxl8_protocol_deserialize_snapshot_header(const u8* buf, usize len, pxl8_snapshot_header* hdr) {
|
||||||
if (len < sizeof(pxl8_snapshot_header)) return 0;
|
if (len < sizeof(pxl8_snapshot_header)) return 0;
|
||||||
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
pxl8_stream s = pxl8_stream_create(buf, (u32)len);
|
||||||
hdr->entity_count = pxl8_read_u16_be(&s);
|
hdr->entity_count = pxl8_read_u16_be(&s);
|
||||||
|
|
|
||||||
|
|
@ -70,23 +70,23 @@ typedef struct pxl8_snapshot_header {
|
||||||
f32 time;
|
f32 time;
|
||||||
} pxl8_snapshot_header;
|
} pxl8_snapshot_header;
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_header(const pxl8_msg_header* msg, u8* buf, size_t len);
|
usize pxl8_protocol_serialize_header(const pxl8_msg_header* msg, u8* buf, usize len);
|
||||||
size_t pxl8_protocol_deserialize_header(const u8* buf, size_t len, pxl8_msg_header* msg);
|
usize pxl8_protocol_deserialize_header(const u8* buf, usize len, pxl8_msg_header* msg);
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_input(const pxl8_input_msg* msg, u8* buf, size_t len);
|
usize pxl8_protocol_serialize_input(const pxl8_input_msg* msg, u8* buf, usize len);
|
||||||
size_t pxl8_protocol_deserialize_input(const u8* buf, size_t len, pxl8_input_msg* msg);
|
usize pxl8_protocol_deserialize_input(const u8* buf, usize len, pxl8_input_msg* msg);
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_command(const pxl8_command_msg* msg, u8* buf, size_t len);
|
usize pxl8_protocol_serialize_command(const pxl8_command_msg* msg, u8* buf, usize len);
|
||||||
size_t pxl8_protocol_deserialize_command(const u8* buf, size_t len, pxl8_command_msg* msg);
|
usize pxl8_protocol_deserialize_command(const u8* buf, usize len, pxl8_command_msg* msg);
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_entity_state(const pxl8_entity_state* state, u8* buf, size_t len);
|
usize pxl8_protocol_serialize_entity_state(const pxl8_entity_state* state, u8* buf, usize len);
|
||||||
size_t pxl8_protocol_deserialize_entity_state(const u8* buf, size_t len, pxl8_entity_state* state);
|
usize pxl8_protocol_deserialize_entity_state(const u8* buf, usize len, pxl8_entity_state* state);
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_event(const pxl8_event_msg* msg, u8* buf, size_t len);
|
usize pxl8_protocol_serialize_event(const pxl8_event_msg* msg, u8* buf, usize len);
|
||||||
size_t pxl8_protocol_deserialize_event(const u8* buf, size_t len, pxl8_event_msg* msg);
|
usize pxl8_protocol_deserialize_event(const u8* buf, usize len, pxl8_event_msg* msg);
|
||||||
|
|
||||||
size_t pxl8_protocol_serialize_snapshot_header(const pxl8_snapshot_header* hdr, u8* buf, size_t len);
|
usize pxl8_protocol_serialize_snapshot_header(const pxl8_snapshot_header* hdr, u8* buf, usize len);
|
||||||
size_t pxl8_protocol_deserialize_snapshot_header(const u8* buf, size_t len, pxl8_snapshot_header* hdr);
|
usize pxl8_protocol_deserialize_snapshot_header(const u8* buf, usize len, pxl8_snapshot_header* hdr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "pxl8_math.h"
|
#include "pxl8_math.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
static inline u32 hash2d(i32 x, i32 y, u32 seed) {
|
static inline u32 hash2d(i32 x, i32 y, u32 seed) {
|
||||||
return pxl8_hash32((u32)x ^ ((u32)y * 2654435769u) ^ seed);
|
return pxl8_hash32((u32)x ^ ((u32)y * 2654435769u) ^ seed);
|
||||||
|
|
@ -168,12 +169,12 @@ static f32 gradient_radial(f32 x, f32 y, f32 cx, f32 cy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_graph* pxl8_graph_create(u32 capacity) {
|
pxl8_graph* pxl8_graph_create(u32 capacity) {
|
||||||
pxl8_graph* graph = calloc(1, sizeof(pxl8_graph));
|
pxl8_graph* graph = pxl8_calloc(1, sizeof(pxl8_graph));
|
||||||
if (!graph) return NULL;
|
if (!graph) return NULL;
|
||||||
|
|
||||||
graph->nodes = calloc(capacity, sizeof(pxl8_node));
|
graph->nodes = pxl8_calloc(capacity, sizeof(pxl8_node));
|
||||||
if (!graph->nodes) {
|
if (!graph->nodes) {
|
||||||
free(graph);
|
pxl8_free(graph);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,8 +187,8 @@ pxl8_graph* pxl8_graph_create(u32 capacity) {
|
||||||
|
|
||||||
void pxl8_graph_destroy(pxl8_graph* graph) {
|
void pxl8_graph_destroy(pxl8_graph* graph) {
|
||||||
if (!graph) return;
|
if (!graph) return;
|
||||||
free(graph->nodes);
|
pxl8_free(graph->nodes);
|
||||||
free(graph);
|
pxl8_free(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_graph_clear(pxl8_graph* graph) {
|
void pxl8_graph_clear(pxl8_graph* graph) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "pxl8_repl.h"
|
#include "pxl8_repl.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
|
|
@ -55,15 +56,15 @@ static void pxl8_repl_completion(const char* buf, linenoiseCompletions* lc) {
|
||||||
"pxl8.error", "pxl8.debug", "pxl8.trace"
|
"pxl8.error", "pxl8.debug", "pxl8.trace"
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t buf_len = strlen(buf);
|
usize buf_len = strlen(buf);
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(fennel_keywords) / sizeof(fennel_keywords[0]); i++) {
|
for (usize i = 0; i < sizeof(fennel_keywords) / sizeof(fennel_keywords[0]); i++) {
|
||||||
if (strncmp(buf, fennel_keywords[i], buf_len) == 0) {
|
if (strncmp(buf, fennel_keywords[i], buf_len) == 0) {
|
||||||
linenoiseAddCompletion(lc, fennel_keywords[i]);
|
linenoiseAddCompletion(lc, fennel_keywords[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(pxl8_functions) / sizeof(pxl8_functions[0]); i++) {
|
for (usize i = 0; i < sizeof(pxl8_functions) / sizeof(pxl8_functions[0]); i++) {
|
||||||
if (strncmp(buf, pxl8_functions[i], buf_len) == 0) {
|
if (strncmp(buf, pxl8_functions[i], buf_len) == 0) {
|
||||||
linenoiseAddCompletion(lc, pxl8_functions[i]);
|
linenoiseAddCompletion(lc, pxl8_functions[i]);
|
||||||
}
|
}
|
||||||
|
|
@ -216,7 +217,7 @@ static int pxl8_repl_thread(void* arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_repl* pxl8_repl_create(void) {
|
pxl8_repl* pxl8_repl_create(void) {
|
||||||
pxl8_repl* repl = (pxl8_repl*)calloc(1, sizeof(pxl8_repl));
|
pxl8_repl* repl = (pxl8_repl*)pxl8_calloc(1, sizeof(pxl8_repl));
|
||||||
if (!repl) return NULL;
|
if (!repl) return NULL;
|
||||||
|
|
||||||
repl->accumulator[0] = '\0';
|
repl->accumulator[0] = '\0';
|
||||||
|
|
@ -237,7 +238,7 @@ pxl8_repl* pxl8_repl_create(void) {
|
||||||
|
|
||||||
repl->thread = SDL_CreateThread(pxl8_repl_thread, "pxl8-repl", repl);
|
repl->thread = SDL_CreateThread(pxl8_repl_thread, "pxl8-repl", repl);
|
||||||
if (!repl->thread) {
|
if (!repl->thread) {
|
||||||
free(repl);
|
pxl8_free(repl);
|
||||||
g_repl = NULL;
|
g_repl = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -261,7 +262,7 @@ void pxl8_repl_destroy(pxl8_repl* repl) {
|
||||||
g_repl = NULL;
|
g_repl = NULL;
|
||||||
|
|
||||||
system("stty sane 2>/dev/null");
|
system("stty sane 2>/dev/null");
|
||||||
free(repl);
|
pxl8_free(repl);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_repl_command* pxl8_repl_pop_command(pxl8_repl* repl) {
|
pxl8_repl_command* pxl8_repl_pop_command(pxl8_repl* repl) {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#include "pxl8_gui.h"
|
#include "pxl8_gui.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
#include "pxl8_macros.h"
|
#include "pxl8_macros.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
#include "pxl8_script_ffi.h"
|
#include "pxl8_script_ffi.h"
|
||||||
|
|
||||||
struct pxl8_script {
|
struct pxl8_script {
|
||||||
|
|
@ -37,7 +38,7 @@ struct pxl8_script {
|
||||||
static int pxl8_cart_loader(lua_State* L) {
|
static int pxl8_cart_loader(lua_State* L) {
|
||||||
const char* found_path = lua_tostring(L, lua_upvalueindex(1));
|
const char* found_path = lua_tostring(L, lua_upvalueindex(1));
|
||||||
const char* code = lua_tostring(L, lua_upvalueindex(2));
|
const char* code = lua_tostring(L, lua_upvalueindex(2));
|
||||||
size_t code_len = lua_objlen(L, lua_upvalueindex(2));
|
usize code_len = lua_objlen(L, lua_upvalueindex(2));
|
||||||
bool is_fennel = lua_toboolean(L, lua_upvalueindex(3));
|
bool is_fennel = lua_toboolean(L, lua_upvalueindex(3));
|
||||||
|
|
||||||
if (is_fennel) {
|
if (is_fennel) {
|
||||||
|
|
@ -75,9 +76,9 @@ static int pxl8_cart_searcher(lua_State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char path[512];
|
char path[512];
|
||||||
size_t len = strlen(modname);
|
usize len = strlen(modname);
|
||||||
size_t j = 0;
|
usize j = 0;
|
||||||
for (size_t i = 0; i < len && j < sizeof(path) - 5; i++) {
|
for (usize i = 0; i < len && j < sizeof(path) - 5; i++) {
|
||||||
if (modname[i] == '.') {
|
if (modname[i] == '.') {
|
||||||
path[j++] = '/';
|
path[j++] = '/';
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -114,9 +115,9 @@ static int pxl8_cart_searcher(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pxl8_script_repl_promote_locals(const char* input, char* output, size_t output_size) {
|
static void pxl8_script_repl_promote_locals(const char* input, char* output, usize output_size) {
|
||||||
size_t i = 0;
|
usize i = 0;
|
||||||
size_t j = 0;
|
usize j = 0;
|
||||||
bool in_string = false;
|
bool in_string = false;
|
||||||
bool in_comment = false;
|
bool in_comment = false;
|
||||||
|
|
||||||
|
|
@ -182,18 +183,18 @@ static void pxl8_script_set_error(pxl8_script* script, const char* error) {
|
||||||
src += 9;
|
src += 9;
|
||||||
const char* mod_start = src;
|
const char* mod_start = src;
|
||||||
while (*src && !(*src == '"' && *(src+1) == ']')) src++;
|
while (*src && !(*src == '"' && *(src+1) == ']')) src++;
|
||||||
size_t mod_len = src - mod_start;
|
usize mod_len = src - mod_start;
|
||||||
|
|
||||||
if (mod_len > 4 && strncmp(mod_start, "pxl8", 4) == 0) {
|
if (mod_len > 4 && strncmp(mod_start, "pxl8", 4) == 0) {
|
||||||
const char* prefix = "src/lua/";
|
const char* prefix = "src/lua/";
|
||||||
while (*prefix && dst < end) *dst++ = *prefix++;
|
while (*prefix && dst < end) *dst++ = *prefix++;
|
||||||
for (size_t i = 0; i < mod_len && dst < end; i++) {
|
for (usize i = 0; i < mod_len && dst < end; i++) {
|
||||||
*dst++ = (mod_start[i] == '.') ? '/' : mod_start[i];
|
*dst++ = (mod_start[i] == '.') ? '/' : mod_start[i];
|
||||||
}
|
}
|
||||||
const char* suffix = ".lua";
|
const char* suffix = ".lua";
|
||||||
while (*suffix && dst < end) *dst++ = *suffix++;
|
while (*suffix && dst < end) *dst++ = *suffix++;
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < mod_len && dst < end; i++) {
|
for (usize i = 0; i < mod_len && dst < end; i++) {
|
||||||
*dst++ = mod_start[i];
|
*dst++ = mod_start[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -244,13 +245,13 @@ static void pxl8_install_embed_searcher(lua_State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_script* pxl8_script_create(bool repl_mode) {
|
pxl8_script* pxl8_script_create(bool repl_mode) {
|
||||||
pxl8_script* script = (pxl8_script*)calloc(1, sizeof(pxl8_script));
|
pxl8_script* script = (pxl8_script*)pxl8_calloc(1, sizeof(pxl8_script));
|
||||||
if (!script) return NULL;
|
if (!script) return NULL;
|
||||||
script->repl_mode = repl_mode;
|
script->repl_mode = repl_mode;
|
||||||
|
|
||||||
script->L = luaL_newstate();
|
script->L = luaL_newstate();
|
||||||
if (!script->L) {
|
if (!script->L) {
|
||||||
free(script);
|
pxl8_free(script);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -349,7 +350,7 @@ void pxl8_script_destroy(pxl8_script* script) {
|
||||||
}
|
}
|
||||||
lua_close(script->L);
|
lua_close(script->L);
|
||||||
}
|
}
|
||||||
free(script);
|
pxl8_free(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_script_set_gfx(pxl8_script* script, pxl8_gfx* gfx) {
|
void pxl8_script_set_gfx(pxl8_script* script, pxl8_gfx* gfx) {
|
||||||
|
|
@ -395,7 +396,7 @@ void pxl8_script_set_sys(pxl8_script* script, void* sys) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static pxl8_result pxl8_script_prepare_path(pxl8_script* script, const char* filename, char* out_basename, size_t basename_size) {
|
static pxl8_result pxl8_script_prepare_path(pxl8_script* script, const char* filename, char* out_basename, usize basename_size) {
|
||||||
char filename_copy[PATH_MAX];
|
char filename_copy[PATH_MAX];
|
||||||
pxl8_strncpy(filename_copy, filename, sizeof(filename_copy));
|
pxl8_strncpy(filename_copy, filename, sizeof(filename_copy));
|
||||||
|
|
||||||
|
|
@ -470,7 +471,7 @@ static time_t get_latest_script_mod_time(const char* dir_path) {
|
||||||
latest = subdir_time;
|
latest = subdir_time;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
size_t len = strlen(entry->d_name);
|
usize len = strlen(entry->d_name);
|
||||||
bool is_script = (len > 4 && strcmp(entry->d_name + len - 4, ".fnl") == 0) ||
|
bool is_script = (len > 4 && strcmp(entry->d_name + len - 4, ".fnl") == 0) ||
|
||||||
(len > 4 && strcmp(entry->d_name + len - 4, ".lua") == 0);
|
(len > 4 && strcmp(entry->d_name + len - 4, ".lua") == 0);
|
||||||
|
|
||||||
|
|
@ -618,8 +619,8 @@ static pxl8_result pxl8_script_eval_internal(pxl8_script* script, const char* co
|
||||||
const char* error = lua_tostring(script->L, -1);
|
const char* error = lua_tostring(script->L, -1);
|
||||||
if (error) {
|
if (error) {
|
||||||
char cleaned_error[2048];
|
char cleaned_error[2048];
|
||||||
size_t j = 0;
|
usize j = 0;
|
||||||
for (size_t i = 0; error[i] && j < sizeof(cleaned_error) - 1; i++) {
|
for (usize i = 0; error[i] && j < sizeof(cleaned_error) - 1; i++) {
|
||||||
if (error[i] == '\t') {
|
if (error[i] == '\t') {
|
||||||
cleaned_error[j++] = ' ';
|
cleaned_error[j++] = ' ';
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -877,7 +878,7 @@ typedef struct {
|
||||||
|
|
||||||
static void ser_buffer_init(ser_buffer* buf) {
|
static void ser_buffer_init(ser_buffer* buf) {
|
||||||
buf->capacity = 1024;
|
buf->capacity = 1024;
|
||||||
buf->data = malloc(buf->capacity);
|
buf->data = pxl8_malloc(buf->capacity);
|
||||||
buf->size = 0;
|
buf->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -886,7 +887,7 @@ static void ser_buffer_grow(ser_buffer* buf, u32 needed) {
|
||||||
while (buf->size + needed > buf->capacity) {
|
while (buf->size + needed > buf->capacity) {
|
||||||
buf->capacity *= 2;
|
buf->capacity *= 2;
|
||||||
}
|
}
|
||||||
buf->data = realloc(buf->data, buf->capacity);
|
buf->data = pxl8_realloc(buf->data, buf->capacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -930,7 +931,7 @@ static void ser_write_value(ser_buffer* buf, lua_State* L, int idx, int depth) {
|
||||||
ser_write_f64(buf, lua_tonumber(L, idx));
|
ser_write_f64(buf, lua_tonumber(L, idx));
|
||||||
break;
|
break;
|
||||||
case LUA_TSTRING: {
|
case LUA_TSTRING: {
|
||||||
size_t len;
|
usize len;
|
||||||
const char* str = lua_tolstring(L, idx, &len);
|
const char* str = lua_tolstring(L, idx, &len);
|
||||||
ser_write_u8(buf, SER_STRING);
|
ser_write_u8(buf, SER_STRING);
|
||||||
ser_write_u32(buf, (u32)len);
|
ser_write_u32(buf, (u32)len);
|
||||||
|
|
@ -1080,7 +1081,7 @@ void pxl8_script_deserialize_globals(pxl8_script* script, const u8* data, u32 si
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_script_free_serialized(u8* data) {
|
void pxl8_script_free_serialized(u8* data) {
|
||||||
free(data);
|
pxl8_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_script_load_main(pxl8_script* script, const char* path) {
|
pxl8_result pxl8_script_load_main(pxl8_script* script, const char* path) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ static const char* pxl8_ffi_cdefs =
|
||||||
"typedef int64_t i64;\n"
|
"typedef int64_t i64;\n"
|
||||||
"typedef float f32;\n"
|
"typedef float f32;\n"
|
||||||
"typedef double f64;\n"
|
"typedef double f64;\n"
|
||||||
|
"typedef size_t usize;\n"
|
||||||
|
"typedef ptrdiff_t isize;\n"
|
||||||
"typedef struct pxl8 pxl8;\n"
|
"typedef struct pxl8 pxl8;\n"
|
||||||
"typedef struct pxl8_gfx pxl8_gfx;\n"
|
"typedef struct pxl8_gfx pxl8_gfx;\n"
|
||||||
"typedef struct { int x, y, w, h; } pxl8_bounds;\n"
|
"typedef struct { int x, y, w, h; } pxl8_bounds;\n"
|
||||||
|
|
@ -579,40 +581,40 @@ static const char* pxl8_ffi_cdefs =
|
||||||
"bool pxl8_bit_test(u32 val, u8 bit);\n"
|
"bool pxl8_bit_test(u32 val, u8 bit);\n"
|
||||||
"void pxl8_bit_toggle(u32* val, u8 bit);\n"
|
"void pxl8_bit_toggle(u32* val, u8 bit);\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void pxl8_pack_u8(u8* buf, size_t offset, u8 val);\n"
|
"void pxl8_pack_u8(u8* buf, usize offset, u8 val);\n"
|
||||||
"void pxl8_pack_u16_be(u8* buf, size_t offset, u16 val);\n"
|
"void pxl8_pack_u16_be(u8* buf, usize offset, u16 val);\n"
|
||||||
"void pxl8_pack_u16_le(u8* buf, size_t offset, u16 val);\n"
|
"void pxl8_pack_u16_le(u8* buf, usize offset, u16 val);\n"
|
||||||
"void pxl8_pack_u32_be(u8* buf, size_t offset, u32 val);\n"
|
"void pxl8_pack_u32_be(u8* buf, usize offset, u32 val);\n"
|
||||||
"void pxl8_pack_u32_le(u8* buf, size_t offset, u32 val);\n"
|
"void pxl8_pack_u32_le(u8* buf, usize offset, u32 val);\n"
|
||||||
"void pxl8_pack_u64_be(u8* buf, size_t offset, u64 val);\n"
|
"void pxl8_pack_u64_be(u8* buf, usize offset, u64 val);\n"
|
||||||
"void pxl8_pack_u64_le(u8* buf, size_t offset, u64 val);\n"
|
"void pxl8_pack_u64_le(u8* buf, usize offset, u64 val);\n"
|
||||||
"void pxl8_pack_i8(u8* buf, size_t offset, i8 val);\n"
|
"void pxl8_pack_i8(u8* buf, usize offset, i8 val);\n"
|
||||||
"void pxl8_pack_i16_be(u8* buf, size_t offset, i16 val);\n"
|
"void pxl8_pack_i16_be(u8* buf, usize offset, i16 val);\n"
|
||||||
"void pxl8_pack_i16_le(u8* buf, size_t offset, i16 val);\n"
|
"void pxl8_pack_i16_le(u8* buf, usize offset, i16 val);\n"
|
||||||
"void pxl8_pack_i32_be(u8* buf, size_t offset, i32 val);\n"
|
"void pxl8_pack_i32_be(u8* buf, usize offset, i32 val);\n"
|
||||||
"void pxl8_pack_i32_le(u8* buf, size_t offset, i32 val);\n"
|
"void pxl8_pack_i32_le(u8* buf, usize offset, i32 val);\n"
|
||||||
"void pxl8_pack_i64_be(u8* buf, size_t offset, i64 val);\n"
|
"void pxl8_pack_i64_be(u8* buf, usize offset, i64 val);\n"
|
||||||
"void pxl8_pack_i64_le(u8* buf, size_t offset, i64 val);\n"
|
"void pxl8_pack_i64_le(u8* buf, usize offset, i64 val);\n"
|
||||||
"void pxl8_pack_f32_be(u8* buf, size_t offset, f32 val);\n"
|
"void pxl8_pack_f32_be(u8* buf, usize offset, f32 val);\n"
|
||||||
"void pxl8_pack_f32_le(u8* buf, size_t offset, f32 val);\n"
|
"void pxl8_pack_f32_le(u8* buf, usize offset, f32 val);\n"
|
||||||
"void pxl8_pack_f64_be(u8* buf, size_t offset, f64 val);\n"
|
"void pxl8_pack_f64_be(u8* buf, usize offset, f64 val);\n"
|
||||||
"void pxl8_pack_f64_le(u8* buf, size_t offset, f64 val);\n"
|
"void pxl8_pack_f64_le(u8* buf, usize offset, f64 val);\n"
|
||||||
"\n"
|
"\n"
|
||||||
"u8 pxl8_unpack_u8(const u8* buf, size_t offset);\n"
|
"u8 pxl8_unpack_u8(const u8* buf, usize offset);\n"
|
||||||
"u16 pxl8_unpack_u16_be(const u8* buf, size_t offset);\n"
|
"u16 pxl8_unpack_u16_be(const u8* buf, usize offset);\n"
|
||||||
"u16 pxl8_unpack_u16_le(const u8* buf, size_t offset);\n"
|
"u16 pxl8_unpack_u16_le(const u8* buf, usize offset);\n"
|
||||||
"u32 pxl8_unpack_u32_be(const u8* buf, size_t offset);\n"
|
"u32 pxl8_unpack_u32_be(const u8* buf, usize offset);\n"
|
||||||
"u32 pxl8_unpack_u32_le(const u8* buf, size_t offset);\n"
|
"u32 pxl8_unpack_u32_le(const u8* buf, usize offset);\n"
|
||||||
"u64 pxl8_unpack_u64_be(const u8* buf, size_t offset);\n"
|
"u64 pxl8_unpack_u64_be(const u8* buf, usize offset);\n"
|
||||||
"u64 pxl8_unpack_u64_le(const u8* buf, size_t offset);\n"
|
"u64 pxl8_unpack_u64_le(const u8* buf, usize offset);\n"
|
||||||
"i8 pxl8_unpack_i8(const u8* buf, size_t offset);\n"
|
"i8 pxl8_unpack_i8(const u8* buf, usize offset);\n"
|
||||||
"i16 pxl8_unpack_i16_be(const u8* buf, size_t offset);\n"
|
"i16 pxl8_unpack_i16_be(const u8* buf, usize offset);\n"
|
||||||
"i16 pxl8_unpack_i16_le(const u8* buf, size_t offset);\n"
|
"i16 pxl8_unpack_i16_le(const u8* buf, usize offset);\n"
|
||||||
"i32 pxl8_unpack_i32_be(const u8* buf, size_t offset);\n"
|
"i32 pxl8_unpack_i32_be(const u8* buf, usize offset);\n"
|
||||||
"i32 pxl8_unpack_i32_le(const u8* buf, size_t offset);\n"
|
"i32 pxl8_unpack_i32_le(const u8* buf, usize offset);\n"
|
||||||
"i64 pxl8_unpack_i64_be(const u8* buf, size_t offset);\n"
|
"i64 pxl8_unpack_i64_be(const u8* buf, usize offset);\n"
|
||||||
"i64 pxl8_unpack_i64_le(const u8* buf, size_t offset);\n"
|
"i64 pxl8_unpack_i64_le(const u8* buf, usize offset);\n"
|
||||||
"f32 pxl8_unpack_f32_be(const u8* buf, size_t offset);\n"
|
"f32 pxl8_unpack_f32_be(const u8* buf, usize offset);\n"
|
||||||
"f32 pxl8_unpack_f32_le(const u8* buf, size_t offset);\n"
|
"f32 pxl8_unpack_f32_le(const u8* buf, usize offset);\n"
|
||||||
"f64 pxl8_unpack_f64_be(const u8* buf, size_t offset);\n"
|
"f64 pxl8_unpack_f64_be(const u8* buf, usize offset);\n"
|
||||||
"f64 pxl8_unpack_f64_le(const u8* buf, size_t offset);\n";
|
"f64 pxl8_unpack_f64_le(const u8* buf, usize offset);\n";
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "pxl8_hal.h"
|
#include "pxl8_hal.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
#include "pxl8_math.h"
|
#include "pxl8_math.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#define VOICE_SCALE 0.15f
|
#define VOICE_SCALE 0.15f
|
||||||
|
|
||||||
|
|
@ -466,14 +467,14 @@ static void delay_process_stereo(void* state, f32* left, f32* right) {
|
||||||
static void delay_destroy_state(void* state) {
|
static void delay_destroy_state(void* state) {
|
||||||
delay_state* d = (delay_state*)state;
|
delay_state* d = (delay_state*)state;
|
||||||
if (d) {
|
if (d) {
|
||||||
free(d->buffer_l);
|
pxl8_free(d->buffer_l);
|
||||||
free(d->buffer_r);
|
pxl8_free(d->buffer_r);
|
||||||
free(d);
|
pxl8_free(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void comb_init(comb_filter* c, u32 size, f32 feedback, f32 damping) {
|
static void comb_init(comb_filter* c, u32 size, f32 feedback, f32 damping) {
|
||||||
c->buffer = (f32*)calloc(size, sizeof(f32));
|
c->buffer = (f32*)pxl8_calloc(size, sizeof(f32));
|
||||||
c->size = size;
|
c->size = size;
|
||||||
c->feedback = feedback;
|
c->feedback = feedback;
|
||||||
c->damping = damping;
|
c->damping = damping;
|
||||||
|
|
@ -482,7 +483,7 @@ static void comb_init(comb_filter* c, u32 size, f32 feedback, f32 damping) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void comb_destroy(comb_filter* c) {
|
static void comb_destroy(comb_filter* c) {
|
||||||
free(c->buffer);
|
pxl8_free(c->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static f32 comb_process(comb_filter* c, f32 input) {
|
static f32 comb_process(comb_filter* c, f32 input) {
|
||||||
|
|
@ -497,14 +498,14 @@ static f32 comb_process(comb_filter* c, f32 input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void allpass_init(allpass_filter* a, u32 size) {
|
static void allpass_init(allpass_filter* a, u32 size) {
|
||||||
a->buffer = (f32*)calloc(size, sizeof(f32));
|
a->buffer = (f32*)pxl8_calloc(size, sizeof(f32));
|
||||||
a->size = size;
|
a->size = size;
|
||||||
a->feedback = 0.5f;
|
a->feedback = 0.5f;
|
||||||
a->index = 0;
|
a->index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void allpass_destroy(allpass_filter* a) {
|
static void allpass_destroy(allpass_filter* a) {
|
||||||
free(a->buffer);
|
pxl8_free(a->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static f32 allpass_process(allpass_filter* a, f32 input) {
|
static f32 allpass_process(allpass_filter* a, f32 input) {
|
||||||
|
|
@ -560,7 +561,7 @@ static void reverb_destroy_state(void* state) {
|
||||||
if (r) {
|
if (r) {
|
||||||
for (int i = 0; i < 4; i++) comb_destroy(&r->combs[i]);
|
for (int i = 0; i < 4; i++) comb_destroy(&r->combs[i]);
|
||||||
for (int i = 0; i < 2; i++) allpass_destroy(&r->allpasses[i]);
|
for (int i = 0; i < 2; i++) allpass_destroy(&r->allpasses[i]);
|
||||||
free(r);
|
pxl8_free(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -606,7 +607,7 @@ static void compressor_process_stereo(void* state, f32* left, f32* right) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compressor_destroy_state(void* state) {
|
static void compressor_destroy_state(void* state) {
|
||||||
free(state);
|
pxl8_free(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void context_process_sample(pxl8_sfx_context* ctx, f32* out_left, f32* out_right) {
|
static void context_process_sample(pxl8_sfx_context* ctx, f32* out_left, f32* out_right) {
|
||||||
|
|
@ -654,12 +655,12 @@ static void context_process_sample(pxl8_sfx_context* ctx, f32* out_left, f32* ou
|
||||||
pxl8_sfx_mixer* pxl8_sfx_mixer_create(const pxl8_hal* hal) {
|
pxl8_sfx_mixer* pxl8_sfx_mixer_create(const pxl8_hal* hal) {
|
||||||
if (!hal || !hal->audio_create) return NULL;
|
if (!hal || !hal->audio_create) return NULL;
|
||||||
|
|
||||||
pxl8_sfx_mixer* mixer = (pxl8_sfx_mixer*)calloc(1, sizeof(pxl8_sfx_mixer));
|
pxl8_sfx_mixer* mixer = (pxl8_sfx_mixer*)pxl8_calloc(1, sizeof(pxl8_sfx_mixer));
|
||||||
if (!mixer) return NULL;
|
if (!mixer) return NULL;
|
||||||
|
|
||||||
mixer->output_buffer = (f32*)calloc(PXL8_SFX_BUFFER_SIZE * 2, sizeof(f32));
|
mixer->output_buffer = (f32*)pxl8_calloc(PXL8_SFX_BUFFER_SIZE * 2, sizeof(f32));
|
||||||
if (!mixer->output_buffer) {
|
if (!mixer->output_buffer) {
|
||||||
free(mixer);
|
pxl8_free(mixer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -668,8 +669,8 @@ pxl8_sfx_mixer* pxl8_sfx_mixer_create(const pxl8_hal* hal) {
|
||||||
|
|
||||||
mixer->audio_handle = hal->audio_create(PXL8_SFX_SAMPLE_RATE, 2);
|
mixer->audio_handle = hal->audio_create(PXL8_SFX_SAMPLE_RATE, 2);
|
||||||
if (!mixer->audio_handle) {
|
if (!mixer->audio_handle) {
|
||||||
free(mixer->output_buffer);
|
pxl8_free(mixer->output_buffer);
|
||||||
free(mixer);
|
pxl8_free(mixer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -686,8 +687,8 @@ void pxl8_sfx_mixer_destroy(pxl8_sfx_mixer* mixer) {
|
||||||
mixer->hal->audio_destroy(mixer->audio_handle);
|
mixer->hal->audio_destroy(mixer->audio_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(mixer->output_buffer);
|
pxl8_free(mixer->output_buffer);
|
||||||
free(mixer);
|
pxl8_free(mixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_sfx_mixer_process(pxl8_sfx_mixer* mixer) {
|
void pxl8_sfx_mixer_process(pxl8_sfx_mixer* mixer) {
|
||||||
|
|
@ -790,7 +791,7 @@ f32 pxl8_sfx_mixer_get_master_volume(const pxl8_sfx_mixer* mixer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_sfx_context* pxl8_sfx_context_create(void) {
|
pxl8_sfx_context* pxl8_sfx_context_create(void) {
|
||||||
pxl8_sfx_context* ctx = (pxl8_sfx_context*)calloc(1, sizeof(pxl8_sfx_context));
|
pxl8_sfx_context* ctx = (pxl8_sfx_context*)pxl8_calloc(1, sizeof(pxl8_sfx_context));
|
||||||
if (!ctx) return NULL;
|
if (!ctx) return NULL;
|
||||||
|
|
||||||
ctx->volume = 1.0f;
|
ctx->volume = 1.0f;
|
||||||
|
|
@ -809,7 +810,7 @@ void pxl8_sfx_context_destroy(pxl8_sfx_context* ctx) {
|
||||||
node = next;
|
node = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(ctx);
|
pxl8_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_sfx_context_set_volume(pxl8_sfx_context* ctx, f32 volume) {
|
void pxl8_sfx_context_set_volume(pxl8_sfx_context* ctx, f32 volume) {
|
||||||
|
|
@ -876,26 +877,26 @@ void pxl8_sfx_node_destroy(pxl8_sfx_node* node) {
|
||||||
if (node->destroy && node->state) {
|
if (node->destroy && node->state) {
|
||||||
node->destroy(node->state);
|
node->destroy(node->state);
|
||||||
}
|
}
|
||||||
free(node);
|
pxl8_free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_sfx_node* pxl8_sfx_delay_create(pxl8_sfx_delay_config cfg) {
|
pxl8_sfx_node* pxl8_sfx_delay_create(pxl8_sfx_delay_config cfg) {
|
||||||
pxl8_sfx_node* node = (pxl8_sfx_node*)calloc(1, sizeof(pxl8_sfx_node));
|
pxl8_sfx_node* node = (pxl8_sfx_node*)pxl8_calloc(1, sizeof(pxl8_sfx_node));
|
||||||
if (!node) return NULL;
|
if (!node) return NULL;
|
||||||
|
|
||||||
delay_state* d = (delay_state*)calloc(1, sizeof(delay_state));
|
delay_state* d = (delay_state*)pxl8_calloc(1, sizeof(delay_state));
|
||||||
if (!d) {
|
if (!d) {
|
||||||
free(node);
|
pxl8_free(node);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->buffer_l = (f32*)calloc(PXL8_SFX_MAX_DELAY_SAMPLES, sizeof(f32));
|
d->buffer_l = (f32*)pxl8_calloc(PXL8_SFX_MAX_DELAY_SAMPLES, sizeof(f32));
|
||||||
d->buffer_r = (f32*)calloc(PXL8_SFX_MAX_DELAY_SAMPLES, sizeof(f32));
|
d->buffer_r = (f32*)pxl8_calloc(PXL8_SFX_MAX_DELAY_SAMPLES, sizeof(f32));
|
||||||
if (!d->buffer_l || !d->buffer_r) {
|
if (!d->buffer_l || !d->buffer_r) {
|
||||||
free(d->buffer_l);
|
pxl8_free(d->buffer_l);
|
||||||
free(d->buffer_r);
|
pxl8_free(d->buffer_r);
|
||||||
free(d);
|
pxl8_free(d);
|
||||||
free(node);
|
pxl8_free(node);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -938,12 +939,12 @@ void pxl8_sfx_delay_set_mix(pxl8_sfx_node* node, f32 mix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_sfx_node* pxl8_sfx_reverb_create(pxl8_sfx_reverb_config cfg) {
|
pxl8_sfx_node* pxl8_sfx_reverb_create(pxl8_sfx_reverb_config cfg) {
|
||||||
pxl8_sfx_node* node = (pxl8_sfx_node*)calloc(1, sizeof(pxl8_sfx_node));
|
pxl8_sfx_node* node = (pxl8_sfx_node*)pxl8_calloc(1, sizeof(pxl8_sfx_node));
|
||||||
if (!node) return NULL;
|
if (!node) return NULL;
|
||||||
|
|
||||||
reverb_state* r = (reverb_state*)calloc(1, sizeof(reverb_state));
|
reverb_state* r = (reverb_state*)pxl8_calloc(1, sizeof(reverb_state));
|
||||||
if (!r) {
|
if (!r) {
|
||||||
free(node);
|
pxl8_free(node);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -996,12 +997,12 @@ void pxl8_sfx_reverb_set_mix(pxl8_sfx_node* node, f32 mix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_sfx_node* pxl8_sfx_compressor_create(pxl8_sfx_compressor_config cfg) {
|
pxl8_sfx_node* pxl8_sfx_compressor_create(pxl8_sfx_compressor_config cfg) {
|
||||||
pxl8_sfx_node* node = (pxl8_sfx_node*)calloc(1, sizeof(pxl8_sfx_node));
|
pxl8_sfx_node* node = (pxl8_sfx_node*)pxl8_calloc(1, sizeof(pxl8_sfx_node));
|
||||||
if (!node) return NULL;
|
if (!node) return NULL;
|
||||||
|
|
||||||
compressor_state* c = (compressor_state*)calloc(1, sizeof(compressor_state));
|
compressor_state* c = (compressor_state*)pxl8_calloc(1, sizeof(compressor_state));
|
||||||
if (!c) {
|
if (!c) {
|
||||||
free(node);
|
pxl8_free(node);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include "pxl8_gfx.h"
|
#include "pxl8_gfx.h"
|
||||||
#include "pxl8_io.h"
|
#include "pxl8_io.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
#define BSP_VERSION 29
|
#define BSP_VERSION 29
|
||||||
|
|
||||||
|
|
@ -56,7 +57,7 @@ static inline pxl8_vec3 read_vec3(pxl8_stream* stream) {
|
||||||
return (pxl8_vec3){x, z, y};
|
return (pxl8_vec3){x, z, y};
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool validate_chunk(const pxl8_bsp_chunk* chunk, u32 element_size, size_t file_size) {
|
static bool validate_chunk(const pxl8_bsp_chunk* chunk, u32 element_size, usize file_size) {
|
||||||
if (chunk->size == 0) return true;
|
if (chunk->size == 0) return true;
|
||||||
if (chunk->offset >= file_size) return false;
|
if (chunk->offset >= file_size) return false;
|
||||||
if (chunk->offset + chunk->size > file_size) return false;
|
if (chunk->offset + chunk->size > file_size) return false;
|
||||||
|
|
@ -89,7 +90,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
memset(bsp, 0, sizeof(*bsp));
|
memset(bsp, 0, sizeof(*bsp));
|
||||||
|
|
||||||
u8* file_data = NULL;
|
u8* file_data = NULL;
|
||||||
size_t file_size = 0;
|
usize file_size = 0;
|
||||||
pxl8_result result = pxl8_io_read_binary_file(path, &file_data, &file_size);
|
pxl8_result result = pxl8_io_read_binary_file(path, &file_data, &file_size);
|
||||||
if (result != PXL8_OK) {
|
if (result != PXL8_OK) {
|
||||||
pxl8_error("Failed to load BSP file: %s", path);
|
pxl8_error("Failed to load BSP file: %s", path);
|
||||||
|
|
@ -98,7 +99,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
|
|
||||||
if (file_size < sizeof(pxl8_bsp_header)) {
|
if (file_size < sizeof(pxl8_bsp_header)) {
|
||||||
pxl8_error("BSP file too small: %s", path);
|
pxl8_error("BSP file too small: %s", path);
|
||||||
free(file_data);
|
pxl8_free(file_data);
|
||||||
return PXL8_ERROR_INVALID_FORMAT;
|
return PXL8_ERROR_INVALID_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,7 +110,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
|
|
||||||
if (header.version != BSP_VERSION) {
|
if (header.version != BSP_VERSION) {
|
||||||
pxl8_error("Invalid BSP version: %u (expected %d)", header.version, BSP_VERSION);
|
pxl8_error("Invalid BSP version: %u (expected %d)", header.version, BSP_VERSION);
|
||||||
free(file_data);
|
pxl8_free(file_data);
|
||||||
return PXL8_ERROR_INVALID_FORMAT;
|
return PXL8_ERROR_INVALID_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,7 +123,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 12, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 12, file_size)) goto error_cleanup;
|
||||||
bsp->num_vertices = chunk->size / 12;
|
bsp->num_vertices = chunk->size / 12;
|
||||||
if (bsp->num_vertices > 0) {
|
if (bsp->num_vertices > 0) {
|
||||||
bsp->vertices = calloc(bsp->num_vertices, sizeof(pxl8_bsp_vertex));
|
bsp->vertices = pxl8_calloc(bsp->num_vertices, sizeof(pxl8_bsp_vertex));
|
||||||
if (!bsp->vertices) goto error_cleanup;
|
if (!bsp->vertices) goto error_cleanup;
|
||||||
pxl8_stream_seek(&stream, chunk->offset);
|
pxl8_stream_seek(&stream, chunk->offset);
|
||||||
for (u32 i = 0; i < bsp->num_vertices; i++) {
|
for (u32 i = 0; i < bsp->num_vertices; i++) {
|
||||||
|
|
@ -134,7 +135,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 4, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 4, file_size)) goto error_cleanup;
|
||||||
bsp->num_edges = chunk->size / 4;
|
bsp->num_edges = chunk->size / 4;
|
||||||
if (bsp->num_edges > 0) {
|
if (bsp->num_edges > 0) {
|
||||||
bsp->edges = calloc(bsp->num_edges, sizeof(pxl8_bsp_edge));
|
bsp->edges = pxl8_calloc(bsp->num_edges, sizeof(pxl8_bsp_edge));
|
||||||
pxl8_stream_seek(&stream, chunk->offset);
|
pxl8_stream_seek(&stream, chunk->offset);
|
||||||
for (u32 i = 0; i < bsp->num_edges; i++) {
|
for (u32 i = 0; i < bsp->num_edges; i++) {
|
||||||
bsp->edges[i].vertex[0] = pxl8_read_u16(&stream);
|
bsp->edges[i].vertex[0] = pxl8_read_u16(&stream);
|
||||||
|
|
@ -146,7 +147,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 4, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 4, file_size)) goto error_cleanup;
|
||||||
bsp->num_surfedges = chunk->size / 4;
|
bsp->num_surfedges = chunk->size / 4;
|
||||||
if (bsp->num_surfedges > 0) {
|
if (bsp->num_surfedges > 0) {
|
||||||
bsp->surfedges = calloc(bsp->num_surfedges, sizeof(i32));
|
bsp->surfedges = pxl8_calloc(bsp->num_surfedges, sizeof(i32));
|
||||||
pxl8_stream_seek(&stream, chunk->offset);
|
pxl8_stream_seek(&stream, chunk->offset);
|
||||||
for (u32 i = 0; i < bsp->num_surfedges; i++) {
|
for (u32 i = 0; i < bsp->num_surfedges; i++) {
|
||||||
bsp->surfedges[i] = pxl8_read_i32(&stream);
|
bsp->surfedges[i] = pxl8_read_i32(&stream);
|
||||||
|
|
@ -157,7 +158,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 20, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 20, file_size)) goto error_cleanup;
|
||||||
bsp->num_planes = chunk->size / 20;
|
bsp->num_planes = chunk->size / 20;
|
||||||
if (bsp->num_planes > 0) {
|
if (bsp->num_planes > 0) {
|
||||||
bsp->planes = calloc(bsp->num_planes, sizeof(pxl8_bsp_plane));
|
bsp->planes = pxl8_calloc(bsp->num_planes, sizeof(pxl8_bsp_plane));
|
||||||
pxl8_stream_seek(&stream, chunk->offset);
|
pxl8_stream_seek(&stream, chunk->offset);
|
||||||
for (u32 i = 0; i < bsp->num_planes; i++) {
|
for (u32 i = 0; i < bsp->num_planes; i++) {
|
||||||
bsp->planes[i].normal = read_vec3(&stream);
|
bsp->planes[i].normal = read_vec3(&stream);
|
||||||
|
|
@ -170,7 +171,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 40, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 40, file_size)) goto error_cleanup;
|
||||||
bsp->num_materials = chunk->size / 40;
|
bsp->num_materials = chunk->size / 40;
|
||||||
if (bsp->num_materials > 0) {
|
if (bsp->num_materials > 0) {
|
||||||
bsp->materials = calloc(bsp->num_materials, sizeof(pxl8_gfx_material));
|
bsp->materials = pxl8_calloc(bsp->num_materials, sizeof(pxl8_gfx_material));
|
||||||
pxl8_stream_seek(&stream, chunk->offset);
|
pxl8_stream_seek(&stream, chunk->offset);
|
||||||
for (u32 i = 0; i < bsp->num_materials; i++) {
|
for (u32 i = 0; i < bsp->num_materials; i++) {
|
||||||
bsp->materials[i].u_axis = read_vec3(&stream);
|
bsp->materials[i].u_axis = read_vec3(&stream);
|
||||||
|
|
@ -189,7 +190,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 20, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 20, file_size)) goto error_cleanup;
|
||||||
bsp->num_faces = chunk->size / 20;
|
bsp->num_faces = chunk->size / 20;
|
||||||
if (bsp->num_faces > 0) {
|
if (bsp->num_faces > 0) {
|
||||||
bsp->faces = calloc(bsp->num_faces, sizeof(pxl8_bsp_face));
|
bsp->faces = pxl8_calloc(bsp->num_faces, sizeof(pxl8_bsp_face));
|
||||||
pxl8_stream_seek(&stream, chunk->offset);
|
pxl8_stream_seek(&stream, chunk->offset);
|
||||||
for (u32 i = 0; i < bsp->num_faces; i++) {
|
for (u32 i = 0; i < bsp->num_faces; i++) {
|
||||||
bsp->faces[i].plane_id = pxl8_read_u16(&stream);
|
bsp->faces[i].plane_id = pxl8_read_u16(&stream);
|
||||||
|
|
@ -212,7 +213,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 24, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 24, file_size)) goto error_cleanup;
|
||||||
bsp->num_nodes = chunk->size / 24;
|
bsp->num_nodes = chunk->size / 24;
|
||||||
if (bsp->num_nodes > 0) {
|
if (bsp->num_nodes > 0) {
|
||||||
bsp->nodes = calloc(bsp->num_nodes, sizeof(pxl8_bsp_node));
|
bsp->nodes = pxl8_calloc(bsp->num_nodes, sizeof(pxl8_bsp_node));
|
||||||
pxl8_stream_seek(&stream, chunk->offset);
|
pxl8_stream_seek(&stream, chunk->offset);
|
||||||
for (u32 i = 0; i < bsp->num_nodes; i++) {
|
for (u32 i = 0; i < bsp->num_nodes; i++) {
|
||||||
bsp->nodes[i].plane_id = pxl8_read_u32(&stream);
|
bsp->nodes[i].plane_id = pxl8_read_u32(&stream);
|
||||||
|
|
@ -239,7 +240,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 28, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 28, file_size)) goto error_cleanup;
|
||||||
bsp->num_leafs = chunk->size / 28;
|
bsp->num_leafs = chunk->size / 28;
|
||||||
if (bsp->num_leafs > 0) {
|
if (bsp->num_leafs > 0) {
|
||||||
bsp->leafs = calloc(bsp->num_leafs, sizeof(pxl8_bsp_leaf));
|
bsp->leafs = pxl8_calloc(bsp->num_leafs, sizeof(pxl8_bsp_leaf));
|
||||||
pxl8_stream_seek(&stream, chunk->offset);
|
pxl8_stream_seek(&stream, chunk->offset);
|
||||||
for (u32 i = 0; i < bsp->num_leafs; i++) {
|
for (u32 i = 0; i < bsp->num_leafs; i++) {
|
||||||
bsp->leafs[i].contents = pxl8_read_i32(&stream);
|
bsp->leafs[i].contents = pxl8_read_i32(&stream);
|
||||||
|
|
@ -266,7 +267,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 2, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 2, file_size)) goto error_cleanup;
|
||||||
bsp->num_marksurfaces = chunk->size / 2;
|
bsp->num_marksurfaces = chunk->size / 2;
|
||||||
if (bsp->num_marksurfaces > 0) {
|
if (bsp->num_marksurfaces > 0) {
|
||||||
bsp->marksurfaces = calloc(bsp->num_marksurfaces, sizeof(u16));
|
bsp->marksurfaces = pxl8_calloc(bsp->num_marksurfaces, sizeof(u16));
|
||||||
pxl8_stream_seek(&stream, chunk->offset);
|
pxl8_stream_seek(&stream, chunk->offset);
|
||||||
for (u32 i = 0; i < bsp->num_marksurfaces; i++) {
|
for (u32 i = 0; i < bsp->num_marksurfaces; i++) {
|
||||||
bsp->marksurfaces[i] = pxl8_read_u16(&stream);
|
bsp->marksurfaces[i] = pxl8_read_u16(&stream);
|
||||||
|
|
@ -277,7 +278,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 64, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 64, file_size)) goto error_cleanup;
|
||||||
bsp->num_models = chunk->size / 64;
|
bsp->num_models = chunk->size / 64;
|
||||||
if (bsp->num_models > 0) {
|
if (bsp->num_models > 0) {
|
||||||
bsp->models = calloc(bsp->num_models, sizeof(pxl8_bsp_model));
|
bsp->models = pxl8_calloc(bsp->num_models, sizeof(pxl8_bsp_model));
|
||||||
pxl8_stream_seek(&stream, chunk->offset);
|
pxl8_stream_seek(&stream, chunk->offset);
|
||||||
for (u32 i = 0; i < bsp->num_models; i++) {
|
for (u32 i = 0; i < bsp->num_models; i++) {
|
||||||
f32 minx = pxl8_read_f32(&stream);
|
f32 minx = pxl8_read_f32(&stream);
|
||||||
|
|
@ -304,7 +305,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 1, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 1, file_size)) goto error_cleanup;
|
||||||
bsp->visdata_size = chunk->size;
|
bsp->visdata_size = chunk->size;
|
||||||
if (bsp->visdata_size > 0) {
|
if (bsp->visdata_size > 0) {
|
||||||
bsp->visdata = malloc(bsp->visdata_size);
|
bsp->visdata = pxl8_malloc(bsp->visdata_size);
|
||||||
memcpy(bsp->visdata, file_data + chunk->offset, bsp->visdata_size);
|
memcpy(bsp->visdata, file_data + chunk->offset, bsp->visdata_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,11 +313,11 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
if (!validate_chunk(chunk, 1, file_size)) goto error_cleanup;
|
if (!validate_chunk(chunk, 1, file_size)) goto error_cleanup;
|
||||||
bsp->lightdata_size = chunk->size;
|
bsp->lightdata_size = chunk->size;
|
||||||
if (bsp->lightdata_size > 0) {
|
if (bsp->lightdata_size > 0) {
|
||||||
bsp->lightdata = malloc(bsp->lightdata_size);
|
bsp->lightdata = pxl8_malloc(bsp->lightdata_size);
|
||||||
memcpy(bsp->lightdata, file_data + chunk->offset, bsp->lightdata_size);
|
memcpy(bsp->lightdata, file_data + chunk->offset, bsp->lightdata_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(file_data);
|
pxl8_free(file_data);
|
||||||
|
|
||||||
for (u32 i = 0; i < bsp->num_faces; i++) {
|
for (u32 i = 0; i < bsp->num_faces; i++) {
|
||||||
pxl8_bsp_face* face = &bsp->faces[i];
|
pxl8_bsp_face* face = &bsp->faces[i];
|
||||||
|
|
@ -350,7 +351,7 @@ pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp) {
|
||||||
|
|
||||||
error_cleanup:
|
error_cleanup:
|
||||||
pxl8_error("BSP chunk validation failed: %s", path);
|
pxl8_error("BSP chunk validation failed: %s", path);
|
||||||
free(file_data);
|
pxl8_free(file_data);
|
||||||
pxl8_bsp_destroy(bsp);
|
pxl8_bsp_destroy(bsp);
|
||||||
return PXL8_ERROR_INVALID_FORMAT;
|
return PXL8_ERROR_INVALID_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
@ -358,21 +359,21 @@ error_cleanup:
|
||||||
void pxl8_bsp_destroy(pxl8_bsp* bsp) {
|
void pxl8_bsp_destroy(pxl8_bsp* bsp) {
|
||||||
if (!bsp) return;
|
if (!bsp) return;
|
||||||
|
|
||||||
free(bsp->cell_portals);
|
pxl8_free(bsp->cell_portals);
|
||||||
free(bsp->edges);
|
pxl8_free(bsp->edges);
|
||||||
free(bsp->faces);
|
pxl8_free(bsp->faces);
|
||||||
free(bsp->leafs);
|
pxl8_free(bsp->leafs);
|
||||||
free(bsp->lightdata);
|
pxl8_free(bsp->lightdata);
|
||||||
free(bsp->marksurfaces);
|
pxl8_free(bsp->marksurfaces);
|
||||||
free(bsp->materials);
|
pxl8_free(bsp->materials);
|
||||||
free(bsp->models);
|
pxl8_free(bsp->models);
|
||||||
free(bsp->nodes);
|
pxl8_free(bsp->nodes);
|
||||||
free(bsp->planes);
|
pxl8_free(bsp->planes);
|
||||||
free(bsp->render_face_flags);
|
pxl8_free(bsp->render_face_flags);
|
||||||
free(bsp->surfedges);
|
pxl8_free(bsp->surfedges);
|
||||||
free(bsp->vertex_lights);
|
pxl8_free(bsp->vertex_lights);
|
||||||
free(bsp->vertices);
|
pxl8_free(bsp->vertices);
|
||||||
free(bsp->visdata);
|
pxl8_free(bsp->visdata);
|
||||||
|
|
||||||
memset(bsp, 0, sizeof(*bsp));
|
memset(bsp, 0, sizeof(*bsp));
|
||||||
}
|
}
|
||||||
|
|
@ -434,7 +435,7 @@ pxl8_bsp_pvs pxl8_bsp_decompress_pvs(const pxl8_bsp* bsp, i32 leaf) {
|
||||||
pxl8_bsp_pvs pvs = {0};
|
pxl8_bsp_pvs pvs = {0};
|
||||||
|
|
||||||
u32 row = (bsp->num_leafs + 7) >> 3;
|
u32 row = (bsp->num_leafs + 7) >> 3;
|
||||||
pvs.data = malloc(row);
|
pvs.data = pxl8_malloc(row);
|
||||||
pvs.size = row;
|
pvs.size = row;
|
||||||
|
|
||||||
if (!pvs.data) return pvs;
|
if (!pvs.data) return pvs;
|
||||||
|
|
@ -472,7 +473,7 @@ pxl8_bsp_pvs pxl8_bsp_decompress_pvs(const pxl8_bsp* bsp, i32 leaf) {
|
||||||
|
|
||||||
void pxl8_bsp_pvs_destroy(pxl8_bsp_pvs* pvs) {
|
void pxl8_bsp_pvs_destroy(pxl8_bsp_pvs* pvs) {
|
||||||
if (pvs) {
|
if (pvs) {
|
||||||
free(pvs->data);
|
pxl8_free(pvs->data);
|
||||||
pvs->data = NULL;
|
pvs->data = NULL;
|
||||||
pvs->size = 0;
|
pvs->size = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -756,7 +757,7 @@ void pxl8_bsp_render(pxl8_gfx* gfx, const pxl8_bsp* bsp, pxl8_vec3 camera_pos) {
|
||||||
|
|
||||||
pxl8_bsp* bsp_mut = (pxl8_bsp*)bsp;
|
pxl8_bsp* bsp_mut = (pxl8_bsp*)bsp;
|
||||||
if (!bsp_mut->render_face_flags) {
|
if (!bsp_mut->render_face_flags) {
|
||||||
bsp_mut->render_face_flags = calloc(bsp->num_faces, 1);
|
bsp_mut->render_face_flags = pxl8_calloc(bsp->num_faces, 1);
|
||||||
if (!bsp_mut->render_face_flags) return;
|
if (!bsp_mut->render_face_flags) return;
|
||||||
}
|
}
|
||||||
memset(bsp_mut->render_face_flags, 0, bsp->num_faces);
|
memset(bsp_mut->render_face_flags, 0, bsp->num_faces);
|
||||||
|
|
@ -764,13 +765,13 @@ void pxl8_bsp_render(pxl8_gfx* gfx, const pxl8_bsp* bsp, pxl8_vec3 camera_pos) {
|
||||||
pxl8_bsp_pvs pvs = pxl8_bsp_decompress_pvs(bsp, camera_leaf);
|
pxl8_bsp_pvs pvs = pxl8_bsp_decompress_pvs(bsp, camera_leaf);
|
||||||
|
|
||||||
u32 visited_bytes = (bsp->num_leafs + 7) / 8;
|
u32 visited_bytes = (bsp->num_leafs + 7) / 8;
|
||||||
u8* visited = calloc(visited_bytes, 1);
|
u8* visited = pxl8_calloc(visited_bytes, 1);
|
||||||
screen_rect* cell_windows = calloc(bsp->num_leafs, sizeof(screen_rect));
|
screen_rect* cell_windows = pxl8_calloc(bsp->num_leafs, sizeof(screen_rect));
|
||||||
portal_queue_entry* queue = malloc(bsp->num_leafs * 4 * sizeof(portal_queue_entry));
|
portal_queue_entry* queue = pxl8_malloc(bsp->num_leafs * 4 * sizeof(portal_queue_entry));
|
||||||
if (!visited || !cell_windows || !queue) {
|
if (!visited || !cell_windows || !queue) {
|
||||||
free(visited);
|
pxl8_free(visited);
|
||||||
free(cell_windows);
|
pxl8_free(cell_windows);
|
||||||
free(queue);
|
pxl8_free(queue);
|
||||||
pxl8_bsp_pvs_destroy(&pvs);
|
pxl8_bsp_pvs_destroy(&pvs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -829,9 +830,9 @@ void pxl8_bsp_render(pxl8_gfx* gfx, const pxl8_bsp* bsp, pxl8_vec3 camera_pos) {
|
||||||
|
|
||||||
pxl8_mesh* mesh = pxl8_mesh_create(8192, 16384);
|
pxl8_mesh* mesh = pxl8_mesh_create(8192, 16384);
|
||||||
if (!mesh) {
|
if (!mesh) {
|
||||||
free(visited);
|
pxl8_free(visited);
|
||||||
free(cell_windows);
|
pxl8_free(cell_windows);
|
||||||
free(queue);
|
pxl8_free(queue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -890,8 +891,8 @@ void pxl8_bsp_render(pxl8_gfx* gfx, const pxl8_bsp* bsp, pxl8_vec3 camera_pos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_bsp_pvs_destroy(&pvs);
|
pxl8_bsp_pvs_destroy(&pvs);
|
||||||
free(visited);
|
pxl8_free(visited);
|
||||||
free(cell_windows);
|
pxl8_free(cell_windows);
|
||||||
free(queue);
|
pxl8_free(queue);
|
||||||
pxl8_mesh_destroy(mesh);
|
pxl8_mesh_destroy(mesh);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
#include "pxl8_rng.h"
|
#include "pxl8_rng.h"
|
||||||
|
|
||||||
#define CELL_SIZE 64.0f
|
#define CELL_SIZE 64.0f
|
||||||
|
|
@ -33,7 +34,7 @@ typedef struct light_source {
|
||||||
static bool room_grid_init(room_grid* grid, i32 width, i32 height) {
|
static bool room_grid_init(room_grid* grid, i32 width, i32 height) {
|
||||||
grid->width = width;
|
grid->width = width;
|
||||||
grid->height = height;
|
grid->height = height;
|
||||||
grid->cells = calloc(width * height, sizeof(u8));
|
grid->cells = pxl8_calloc(width * height, sizeof(u8));
|
||||||
|
|
||||||
return grid->cells != NULL;
|
return grid->cells != NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -126,7 +127,7 @@ static void compute_bsp_vertex_lighting(
|
||||||
) {
|
) {
|
||||||
if (!bsp || bsp->num_vertices == 0) return;
|
if (!bsp || bsp->num_vertices == 0) return;
|
||||||
|
|
||||||
bsp->vertex_lights = calloc(bsp->num_vertices, sizeof(u32));
|
bsp->vertex_lights = pxl8_calloc(bsp->num_vertices, sizeof(u32));
|
||||||
if (!bsp->vertex_lights) return;
|
if (!bsp->vertex_lights) return;
|
||||||
bsp->num_vertex_lights = bsp->num_vertices;
|
bsp->num_vertex_lights = bsp->num_vertices;
|
||||||
|
|
||||||
|
|
@ -169,7 +170,7 @@ static void compute_bsp_vertex_lighting(
|
||||||
|
|
||||||
static pxl8_bsp_cell_portals* build_pxl8_bsp_cell_portals(const room_grid* grid, f32 cell_size) {
|
static pxl8_bsp_cell_portals* build_pxl8_bsp_cell_portals(const room_grid* grid, f32 cell_size) {
|
||||||
i32 total_cells = grid->width * grid->height;
|
i32 total_cells = grid->width * grid->height;
|
||||||
pxl8_bsp_cell_portals* portals = calloc(total_cells, sizeof(pxl8_bsp_cell_portals));
|
pxl8_bsp_cell_portals* portals = pxl8_calloc(total_cells, sizeof(pxl8_bsp_cell_portals));
|
||||||
if (!portals) return NULL;
|
if (!portals) return NULL;
|
||||||
|
|
||||||
for (i32 y = 0; y < grid->height; y++) {
|
for (i32 y = 0; y < grid->height; y++) {
|
||||||
|
|
@ -235,11 +236,11 @@ static void portal_flood_bfs(
|
||||||
(void)grid_width;
|
(void)grid_width;
|
||||||
|
|
||||||
u32 pvs_bytes = (num_leafs + 7) / 8;
|
u32 pvs_bytes = (num_leafs + 7) / 8;
|
||||||
u8* visited = calloc(pvs_bytes, 1);
|
u8* visited = pxl8_calloc(pvs_bytes, 1);
|
||||||
flood_entry* queue = malloc(num_leafs * sizeof(flood_entry));
|
flood_entry* queue = pxl8_malloc(num_leafs * sizeof(flood_entry));
|
||||||
if (!visited || !queue) {
|
if (!visited || !queue) {
|
||||||
free(visited);
|
pxl8_free(visited);
|
||||||
free(queue);
|
pxl8_free(queue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -271,15 +272,15 @@ static void portal_flood_bfs(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(visited);
|
pxl8_free(visited);
|
||||||
free(queue);
|
pxl8_free(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8* compute_leaf_pvs(u32 start_leaf, const pxl8_bsp_cell_portals* portals,
|
static u8* compute_leaf_pvs(u32 start_leaf, const pxl8_bsp_cell_portals* portals,
|
||||||
u32 num_leafs, const pxl8_bsp_leaf* leafs,
|
u32 num_leafs, const pxl8_bsp_leaf* leafs,
|
||||||
const room_grid* grid, f32 cell_size) {
|
const room_grid* grid, f32 cell_size) {
|
||||||
u32 pvs_bytes = (num_leafs + 7) / 8;
|
u32 pvs_bytes = (num_leafs + 7) / 8;
|
||||||
u8* pvs = calloc(pvs_bytes, 1);
|
u8* pvs = pxl8_calloc(pvs_bytes, 1);
|
||||||
if (!pvs) return NULL;
|
if (!pvs) return NULL;
|
||||||
|
|
||||||
portal_flood_bfs(start_leaf, portals, leafs, pvs, num_leafs, cell_size, grid->width);
|
portal_flood_bfs(start_leaf, portals, leafs, pvs, num_leafs, cell_size, grid->width);
|
||||||
|
|
@ -313,14 +314,14 @@ static pxl8_result build_pvs_data(pxl8_bsp* bsp, const pxl8_bsp_cell_portals* po
|
||||||
u32 pvs_bytes = (num_leafs + 7) / 8;
|
u32 pvs_bytes = (num_leafs + 7) / 8;
|
||||||
|
|
||||||
u32 max_visdata = num_leafs * pvs_bytes * 2;
|
u32 max_visdata = num_leafs * pvs_bytes * 2;
|
||||||
u8* visdata = malloc(max_visdata);
|
u8* visdata = pxl8_malloc(max_visdata);
|
||||||
if (!visdata) return PXL8_ERROR_OUT_OF_MEMORY;
|
if (!visdata) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
u32 visdata_pos = 0;
|
u32 visdata_pos = 0;
|
||||||
|
|
||||||
u8* compressed = malloc(pvs_bytes * 2);
|
u8* compressed = pxl8_malloc(pvs_bytes * 2);
|
||||||
if (!compressed) {
|
if (!compressed) {
|
||||||
free(visdata);
|
pxl8_free(visdata);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,8 +334,8 @@ static pxl8_result build_pvs_data(pxl8_bsp* bsp, const pxl8_bsp_cell_portals* po
|
||||||
|
|
||||||
u8* pvs = compute_leaf_pvs(leaf, portals, num_leafs, bsp->leafs, grid, cell_size);
|
u8* pvs = compute_leaf_pvs(leaf, portals, num_leafs, bsp->leafs, grid, cell_size);
|
||||||
if (!pvs) {
|
if (!pvs) {
|
||||||
free(compressed);
|
pxl8_free(compressed);
|
||||||
free(visdata);
|
pxl8_free(visdata);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -355,11 +356,11 @@ static pxl8_result build_pvs_data(pxl8_bsp* bsp, const pxl8_bsp_cell_portals* po
|
||||||
memcpy(visdata + visdata_pos, compressed, compressed_size);
|
memcpy(visdata + visdata_pos, compressed, compressed_size);
|
||||||
visdata_pos += compressed_size;
|
visdata_pos += compressed_size;
|
||||||
|
|
||||||
free(pvs);
|
pxl8_free(pvs);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(compressed);
|
pxl8_free(compressed);
|
||||||
bsp->visdata = realloc(visdata, visdata_pos > 0 ? visdata_pos : 1);
|
bsp->visdata = pxl8_realloc(visdata, visdata_pos > 0 ? visdata_pos : 1);
|
||||||
bsp->visdata_size = visdata_pos;
|
bsp->visdata_size = visdata_pos;
|
||||||
|
|
||||||
pxl8_debug("Built PVS: %u leafs, %u bytes visdata", num_leafs, visdata_pos);
|
pxl8_debug("Built PVS: %u leafs, %u bytes visdata", num_leafs, visdata_pos);
|
||||||
|
|
@ -429,18 +430,18 @@ static pxl8_result grid_to_bsp(pxl8_bsp* bsp, const room_grid* grid) {
|
||||||
u32 max_nodes = 2 * total_cells;
|
u32 max_nodes = 2 * total_cells;
|
||||||
u32 total_planes = face_count + max_nodes;
|
u32 total_planes = face_count + max_nodes;
|
||||||
|
|
||||||
bsp->vertices = calloc(vertex_count, sizeof(pxl8_bsp_vertex));
|
bsp->vertices = pxl8_calloc(vertex_count, sizeof(pxl8_bsp_vertex));
|
||||||
bsp->faces = calloc(face_count, sizeof(pxl8_bsp_face));
|
bsp->faces = pxl8_calloc(face_count, sizeof(pxl8_bsp_face));
|
||||||
bsp->planes = calloc(total_planes, sizeof(pxl8_bsp_plane));
|
bsp->planes = pxl8_calloc(total_planes, sizeof(pxl8_bsp_plane));
|
||||||
bsp->edges = calloc(vertex_count, sizeof(pxl8_bsp_edge));
|
bsp->edges = pxl8_calloc(vertex_count, sizeof(pxl8_bsp_edge));
|
||||||
bsp->surfedges = calloc(vertex_count, sizeof(i32));
|
bsp->surfedges = pxl8_calloc(vertex_count, sizeof(i32));
|
||||||
bsp->nodes = calloc(max_nodes, sizeof(pxl8_bsp_node));
|
bsp->nodes = pxl8_calloc(max_nodes, sizeof(pxl8_bsp_node));
|
||||||
|
|
||||||
u32* face_cell = calloc(face_count, sizeof(u32));
|
u32* face_cell = pxl8_calloc(face_count, sizeof(u32));
|
||||||
|
|
||||||
if (!bsp->vertices || !bsp->faces || !bsp->planes || !bsp->edges ||
|
if (!bsp->vertices || !bsp->faces || !bsp->planes || !bsp->edges ||
|
||||||
!bsp->surfedges || !bsp->nodes || !face_cell) {
|
!bsp->surfedges || !bsp->nodes || !face_cell) {
|
||||||
free(face_cell);
|
pxl8_free(face_cell);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -617,26 +618,26 @@ static pxl8_result grid_to_bsp(pxl8_bsp* bsp, const room_grid* grid) {
|
||||||
bsp->num_edges = vertex_count;
|
bsp->num_edges = vertex_count;
|
||||||
bsp->num_surfedges = vertex_count;
|
bsp->num_surfedges = vertex_count;
|
||||||
|
|
||||||
bsp->leafs = calloc(total_cells, sizeof(pxl8_bsp_leaf));
|
bsp->leafs = pxl8_calloc(total_cells, sizeof(pxl8_bsp_leaf));
|
||||||
bsp->marksurfaces = calloc(face_count, sizeof(u16));
|
bsp->marksurfaces = pxl8_calloc(face_count, sizeof(u16));
|
||||||
|
|
||||||
if (!bsp->leafs || !bsp->marksurfaces) {
|
if (!bsp->leafs || !bsp->marksurfaces) {
|
||||||
free(face_cell);
|
pxl8_free(face_cell);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
bsp->num_leafs = total_cells;
|
bsp->num_leafs = total_cells;
|
||||||
bsp->num_marksurfaces = face_count;
|
bsp->num_marksurfaces = face_count;
|
||||||
|
|
||||||
u32* faces_per_cell = calloc(total_cells, sizeof(u32));
|
u32* faces_per_cell = pxl8_calloc(total_cells, sizeof(u32));
|
||||||
u32* cell_offset = calloc(total_cells, sizeof(u32));
|
u32* cell_offset = pxl8_calloc(total_cells, sizeof(u32));
|
||||||
u32* cell_cursor = calloc(total_cells, sizeof(u32));
|
u32* cell_cursor = pxl8_calloc(total_cells, sizeof(u32));
|
||||||
|
|
||||||
if (!faces_per_cell || !cell_offset || !cell_cursor) {
|
if (!faces_per_cell || !cell_offset || !cell_cursor) {
|
||||||
free(faces_per_cell);
|
pxl8_free(faces_per_cell);
|
||||||
free(cell_offset);
|
pxl8_free(cell_offset);
|
||||||
free(cell_cursor);
|
pxl8_free(cell_cursor);
|
||||||
free(face_cell);
|
pxl8_free(face_cell);
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -683,10 +684,10 @@ static pxl8_result grid_to_bsp(pxl8_bsp* bsp, const room_grid* grid) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(faces_per_cell);
|
pxl8_free(faces_per_cell);
|
||||||
free(cell_offset);
|
pxl8_free(cell_offset);
|
||||||
free(cell_cursor);
|
pxl8_free(cell_cursor);
|
||||||
free(face_cell);
|
pxl8_free(face_cell);
|
||||||
|
|
||||||
bsp_build_context ctx = {
|
bsp_build_context ctx = {
|
||||||
.bsp = bsp,
|
.bsp = bsp,
|
||||||
|
|
@ -722,8 +723,8 @@ static pxl8_result grid_to_bsp(pxl8_bsp* bsp, const room_grid* grid) {
|
||||||
|
|
||||||
if (first_walkable >= 0) {
|
if (first_walkable >= 0) {
|
||||||
u32 pvs_bytes = (total_cells + 7) / 8;
|
u32 pvs_bytes = (total_cells + 7) / 8;
|
||||||
u8* visited = calloc(pvs_bytes, 1);
|
u8* visited = pxl8_calloc(pvs_bytes, 1);
|
||||||
u8* queue = malloc(total_cells * sizeof(u32));
|
u8* queue = pxl8_malloc(total_cells * sizeof(u32));
|
||||||
u32 head = 0, tail = 0;
|
u32 head = 0, tail = 0;
|
||||||
((u32*)queue)[tail++] = first_walkable;
|
((u32*)queue)[tail++] = first_walkable;
|
||||||
visited[first_walkable >> 3] |= (1 << (first_walkable & 7));
|
visited[first_walkable >> 3] |= (1 << (first_walkable & 7));
|
||||||
|
|
@ -742,13 +743,13 @@ static pxl8_result grid_to_bsp(pxl8_bsp* bsp, const room_grid* grid) {
|
||||||
}
|
}
|
||||||
pxl8_debug("Connectivity: %u/%u walkable cells reachable from leaf %d",
|
pxl8_debug("Connectivity: %u/%u walkable cells reachable from leaf %d",
|
||||||
reachable, walkable_cells, first_walkable);
|
reachable, walkable_cells, first_walkable);
|
||||||
free(visited);
|
pxl8_free(visited);
|
||||||
free(queue);
|
pxl8_free(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pvs_result = build_pvs_data(bsp, portals, grid, cell_size);
|
pxl8_result pvs_result = build_pvs_data(bsp, portals, grid, cell_size);
|
||||||
if (pvs_result != PXL8_OK) {
|
if (pvs_result != PXL8_OK) {
|
||||||
free(portals);
|
pxl8_free(portals);
|
||||||
return pvs_result;
|
return pvs_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -852,7 +853,7 @@ static pxl8_result procgen_rooms(pxl8_bsp* bsp, const pxl8_procgen_params* param
|
||||||
params->width, params->height, room_count);
|
params->width, params->height, room_count);
|
||||||
|
|
||||||
pxl8_result result = grid_to_bsp(bsp, &grid);
|
pxl8_result result = grid_to_bsp(bsp, &grid);
|
||||||
free(grid.cells);
|
pxl8_free(grid.cells);
|
||||||
|
|
||||||
if (result != PXL8_OK) {
|
if (result != PXL8_OK) {
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "pxl8_gen.h"
|
#include "pxl8_gen.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
#include "pxl8_math.h"
|
#include "pxl8_math.h"
|
||||||
|
#include "pxl8_mem.h"
|
||||||
|
|
||||||
struct pxl8_world {
|
struct pxl8_world {
|
||||||
pxl8_bsp bsp;
|
pxl8_bsp bsp;
|
||||||
|
|
@ -14,7 +15,7 @@ struct pxl8_world {
|
||||||
};
|
};
|
||||||
|
|
||||||
pxl8_world* pxl8_world_create(void) {
|
pxl8_world* pxl8_world_create(void) {
|
||||||
pxl8_world* world = (pxl8_world*)calloc(1, sizeof(pxl8_world));
|
pxl8_world* world = (pxl8_world*)pxl8_calloc(1, sizeof(pxl8_world));
|
||||||
if (!world) {
|
if (!world) {
|
||||||
pxl8_error("Failed to allocate world");
|
pxl8_error("Failed to allocate world");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -32,7 +33,7 @@ void pxl8_world_destroy(pxl8_world* world) {
|
||||||
pxl8_bsp_destroy(&world->bsp);
|
pxl8_bsp_destroy(&world->bsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(world);
|
pxl8_free(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_result pxl8_world_generate(pxl8_world* world, pxl8_gfx* gfx, const pxl8_procgen_params* params) {
|
pxl8_result pxl8_world_generate(pxl8_world* world, pxl8_gfx* gfx, const pxl8_procgen_params* params) {
|
||||||
|
|
@ -96,7 +97,7 @@ pxl8_result pxl8_world_apply_textures(pxl8_world* world, const pxl8_world_textur
|
||||||
pxl8_bsp* bsp = &world->bsp;
|
pxl8_bsp* bsp = &world->bsp;
|
||||||
|
|
||||||
u32 max_materials = count * 6;
|
u32 max_materials = count * 6;
|
||||||
bsp->materials = calloc(max_materials, sizeof(pxl8_gfx_material));
|
bsp->materials = pxl8_calloc(max_materials, sizeof(pxl8_gfx_material));
|
||||||
if (!bsp->materials) {
|
if (!bsp->materials) {
|
||||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue