improve sw renderer
This commit is contained in:
parent
415d424057
commit
39ee0fefb7
89 changed files with 9380 additions and 2307 deletions
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "pxl8_io.h"
|
||||
#include "pxl8_log.h"
|
||||
#include "pxl8_mem.h"
|
||||
|
||||
static pxl8_result parse_ase_header(pxl8_stream* stream, pxl8_ase_header* header) {
|
||||
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->first_color = 0;
|
||||
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) {
|
||||
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);
|
||||
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;
|
||||
pxl8_read_bytes(stream, layer->name, name_len);
|
||||
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;
|
||||
}
|
||||
|
||||
palette->colors = (u32*)malloc(color_count * sizeof(u32));
|
||||
palette->colors = (u32*)pxl8_malloc(color_count * sizeof(u32));
|
||||
if (!palette->colors) {
|
||||
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) {
|
||||
u16 text_len = pxl8_read_u16(stream);
|
||||
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;
|
||||
pxl8_read_bytes(stream, user_data->text, text_len);
|
||||
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);
|
||||
|
||||
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;
|
||||
user_data->property_count = num_properties;
|
||||
|
||||
for (u32 i = 0; i < num_properties; i++) {
|
||||
u16 name_len = pxl8_read_u16(stream);
|
||||
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;
|
||||
pxl8_read_bytes(stream, user_data->properties[i].name, name_len);
|
||||
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: {
|
||||
u16 str_len = pxl8_read_u16(stream);
|
||||
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;
|
||||
pxl8_read_bytes(stream, user_data->properties[i].string_val, str_len);
|
||||
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);
|
||||
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;
|
||||
pxl8_read_bytes(stream, tileset->name, name_len);
|
||||
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) {
|
||||
u32 compressed_size = pxl8_read_u32(stream);
|
||||
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;
|
||||
|
||||
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);
|
||||
if (result != MZ_OK) {
|
||||
pxl8_error("Failed to decompress tileset data: miniz error %d", result);
|
||||
free(tileset->pixels);
|
||||
pxl8_free(tileset->pixels);
|
||||
tileset->pixels = NULL;
|
||||
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;
|
||||
|
||||
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 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;
|
||||
|
||||
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);
|
||||
if (result != MZ_OK) {
|
||||
pxl8_error("Failed to decompress cel data: miniz error %d", result);
|
||||
free(cel->image.pixels);
|
||||
pxl8_free(cel->image.pixels);
|
||||
cel->image.pixels = NULL;
|
||||
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 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;
|
||||
|
||||
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);
|
||||
if (result != MZ_OK) {
|
||||
pxl8_error("Failed to decompress tilemap data: miniz error %d", result);
|
||||
free(temp_buffer);
|
||||
pxl8_free(temp_buffer);
|
||||
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) {
|
||||
free(temp_buffer);
|
||||
pxl8_free(temp_buffer);
|
||||
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;
|
||||
|
|
@ -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));
|
||||
|
||||
u8* file_data;
|
||||
size_t file_size;
|
||||
usize file_size;
|
||||
pxl8_result result = pxl8_io_read_binary_file(filepath, &file_data, &file_size);
|
||||
if (result != PXL8_OK) {
|
||||
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->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) {
|
||||
pxl8_io_free_binary_data(file_data);
|
||||
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;
|
||||
|
||||
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) {
|
||||
result = PXL8_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
|
|
@ -457,7 +458,7 @@ pxl8_result pxl8_ase_load(const char* filepath, pxl8_ase_file* ase_file) {
|
|||
|
||||
case PXL8_ASE_CHUNK_LAYER: {
|
||||
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));
|
||||
if (!new_layers) {
|
||||
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};
|
||||
result = parse_cel_chunk(&stream, chunk_header.chunk_size - 6, &cel);
|
||||
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) {
|
||||
result = PXL8_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
|
|
@ -515,14 +516,14 @@ pxl8_result pxl8_ase_load(const char* filepath, pxl8_ase_file* ase_file) {
|
|||
|
||||
case PXL8_ASE_CHUNK_PALETTE:
|
||||
if (ase_file->palette.colors) {
|
||||
free(ase_file->palette.colors);
|
||||
pxl8_free(ase_file->palette.colors);
|
||||
ase_file->palette.colors = NULL;
|
||||
}
|
||||
result = parse_palette_chunk(&stream, &ase_file->palette);
|
||||
break;
|
||||
|
||||
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));
|
||||
if (!new_tilesets) {
|
||||
result = PXL8_ERROR_OUT_OF_MEMORY;
|
||||
|
|
@ -579,57 +580,57 @@ void pxl8_ase_destroy(pxl8_ase_file* ase_file) {
|
|||
|
||||
if (ase_file->frames) {
|
||||
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) {
|
||||
for (u32 j = 0; j < ase_file->frames[i].cel_count; j++) {
|
||||
pxl8_ase_cel* cel = &ase_file->frames[i].cels[j];
|
||||
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) {
|
||||
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) {
|
||||
free(ase_file->palette.colors);
|
||||
pxl8_free(ase_file->palette.colors);
|
||||
}
|
||||
|
||||
if (ase_file->layers) {
|
||||
for (u32 i = 0; i < ase_file->layer_count; i++) {
|
||||
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) {
|
||||
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].pixels) free(ase_file->tilesets[i].pixels);
|
||||
if (ase_file->tilesets[i].name) pxl8_free(ase_file->tilesets[i].name);
|
||||
if (ase_file->tilesets[i].pixels) pxl8_free(ase_file->tilesets[i].pixels);
|
||||
if (ase_file->tilesets[i].tile_user_data) {
|
||||
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];
|
||||
if (ud->text) free(ud->text);
|
||||
if (ud->text) pxl8_free(ud->text);
|
||||
if (ud->properties) {
|
||||
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) {
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "pxl8_log.h"
|
||||
#include "pxl8_mem.h"
|
||||
|
||||
#define PXL8_CART_MAGIC 0x43585850
|
||||
#define PXL8_CART_VERSION 1
|
||||
|
|
@ -62,7 +63,7 @@ static bool is_directory(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;
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +98,7 @@ static void collect_files_recursive(const char* dir_path, const char* prefix,
|
|||
} else {
|
||||
if (*count >= *capacity) {
|
||||
*capacity = (*capacity == 0) ? 64 : (*capacity * 2);
|
||||
*paths = realloc(*paths, *capacity * sizeof(char*));
|
||||
*paths = pxl8_realloc(*paths, *capacity * sizeof(char*));
|
||||
}
|
||||
(*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->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;
|
||||
memcpy(cart->data, data, size);
|
||||
cart->data_size = size;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
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);
|
||||
cart->files[i].path[entry->path_len] = '\0';
|
||||
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* cart = calloc(1, sizeof(pxl8_cart));
|
||||
pxl8_cart* cart = pxl8_calloc(1, sizeof(pxl8_cart));
|
||||
if (cart) {
|
||||
cart->resolution = PXL8_RESOLUTION_640x360;
|
||||
cart->window_size = (pxl8_size){1280, 720};
|
||||
|
|
@ -167,7 +168,7 @@ pxl8_cart* pxl8_get_cart(void) {
|
|||
void pxl8_cart_destroy(pxl8_cart* cart) {
|
||||
if (!cart) return;
|
||||
pxl8_cart_unload(cart);
|
||||
free(cart);
|
||||
pxl8_free(cart);
|
||||
}
|
||||
|
||||
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);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
u8* data = malloc(size);
|
||||
u8* data = pxl8_malloc(size);
|
||||
if (!data || fread(data, 1, size, file) != size) {
|
||||
free(data);
|
||||
pxl8_free(data);
|
||||
fclose(file);
|
||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
pxl8_result result = load_packed_cart(cart, data, size);
|
||||
free(data);
|
||||
pxl8_free(data);
|
||||
|
||||
if (result == PXL8_OK) {
|
||||
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);
|
||||
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) {
|
||||
free(data);
|
||||
pxl8_free(data);
|
||||
fclose(file);
|
||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
pxl8_result result = load_packed_cart(cart, data, trailer.cart_size);
|
||||
free(data);
|
||||
pxl8_free(data);
|
||||
|
||||
if (result == PXL8_OK) {
|
||||
pxl8_info("Loaded embedded cart");
|
||||
|
|
@ -265,7 +266,7 @@ void pxl8_cart_unload(pxl8_cart* cart) {
|
|||
if (cart->title) {
|
||||
pxl8_info("Unloaded cart: %s", cart->title);
|
||||
pxl8_cart_unmount(cart);
|
||||
free(cart->title);
|
||||
pxl8_free(cart->title);
|
||||
cart->title = NULL;
|
||||
} else if (cart->base_path || cart->data) {
|
||||
pxl8_info("Unloaded cart");
|
||||
|
|
@ -274,18 +275,18 @@ void pxl8_cart_unload(pxl8_cart* cart) {
|
|||
|
||||
if (cart->files) {
|
||||
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->file_count = 0;
|
||||
|
||||
free(cart->data);
|
||||
pxl8_free(cart->data);
|
||||
cart->data = NULL;
|
||||
cart->data_size = 0;
|
||||
|
||||
free(cart->base_path);
|
||||
pxl8_free(cart->base_path);
|
||||
cart->base_path = NULL;
|
||||
cart->is_folder = false;
|
||||
}
|
||||
|
|
@ -302,7 +303,7 @@ pxl8_result pxl8_cart_mount(pxl8_cart* cart) {
|
|||
pxl8_original_cwd = getcwd(NULL, 0);
|
||||
if (chdir(cart->base_path) != 0) {
|
||||
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;
|
||||
return PXL8_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
|
@ -323,7 +324,7 @@ void pxl8_cart_unmount(pxl8_cart* cart) {
|
|||
|
||||
if (pxl8_original_cwd) {
|
||||
chdir(pxl8_original_cwd);
|
||||
free(pxl8_original_cwd);
|
||||
pxl8_free(pxl8_original_cwd);
|
||||
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) {
|
||||
if (!cart || !title) return;
|
||||
free(cart->title);
|
||||
pxl8_free(cart->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;
|
||||
}
|
||||
|
||||
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->is_folder && cart->base_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);
|
||||
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) {
|
||||
|
|
@ -427,9 +428,9 @@ pxl8_result pxl8_cart_read_file(const pxl8_cart* cart, const char* path, u8** da
|
|||
*size_out = (u32)ftell(file);
|
||||
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) {
|
||||
free(*data_out);
|
||||
pxl8_free(*data_out);
|
||||
*data_out = NULL;
|
||||
fclose(file);
|
||||
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;
|
||||
|
||||
*size_out = cf->size;
|
||||
*data_out = malloc(cf->size);
|
||||
*data_out = pxl8_malloc(cf->size);
|
||||
if (!*data_out) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
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) {
|
||||
free(data);
|
||||
pxl8_free(data);
|
||||
}
|
||||
|
||||
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 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++) {
|
||||
char full_path[1024];
|
||||
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) {
|
||||
free(file_sizes);
|
||||
for (u32 i = 0; i < count; i++) free(paths[i]);
|
||||
free(paths);
|
||||
pxl8_free(file_sizes);
|
||||
for (u32 i = 0; i < count; i++) pxl8_free(paths[i]);
|
||||
pxl8_free(paths);
|
||||
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];
|
||||
free(paths[i]);
|
||||
pxl8_free(paths[i]);
|
||||
}
|
||||
free(paths);
|
||||
free(file_sizes);
|
||||
pxl8_free(paths);
|
||||
pxl8_free(file_sizes);
|
||||
|
||||
FILE* out = fopen(output_path, "wb");
|
||||
if (!out) {
|
||||
free(buffer);
|
||||
pxl8_free(buffer);
|
||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
fwrite(buffer, 1, total_size, out);
|
||||
fclose(out);
|
||||
free(buffer);
|
||||
pxl8_free(buffer);
|
||||
|
||||
pxl8_info("Cart packed: %u files, %u bytes", count, total_size);
|
||||
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);
|
||||
cart_size = (u32)ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
cart_data = malloc(cart_size);
|
||||
cart_data = pxl8_malloc(cart_size);
|
||||
fread(cart_data, 1, cart_size, f);
|
||||
fclose(f);
|
||||
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);
|
||||
cart_size = (u32)ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
cart_data = malloc(cart_size);
|
||||
cart_data = pxl8_malloc(cart_size);
|
||||
fread(cart_data, 1, cart_size, f);
|
||||
fclose(f);
|
||||
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");
|
||||
if (!exe) {
|
||||
if (free_cart) free(cart_data);
|
||||
if (free_cart) pxl8_free(cart_data);
|
||||
return PXL8_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
fseek(exe, 0, SEEK_END);
|
||||
u32 exe_size = (u32)ftell(exe);
|
||||
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);
|
||||
fclose(exe);
|
||||
|
||||
FILE* out = fopen(output_path, "wb");
|
||||
if (!out) {
|
||||
free(exe_data);
|
||||
if (free_cart) free(cart_data);
|
||||
pxl8_free(exe_data);
|
||||
if (free_cart) pxl8_free(cart_data);
|
||||
return PXL8_ERROR_SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
fwrite(exe_data, 1, exe_size, out);
|
||||
free(exe_data);
|
||||
pxl8_free(exe_data);
|
||||
|
||||
u32 cart_offset = exe_size;
|
||||
fwrite(cart_data, 1, cart_size, out);
|
||||
if (free_cart) free(cart_data);
|
||||
if (free_cart) pxl8_free(cart_data);
|
||||
|
||||
pxl8_cart_trailer trailer = {
|
||||
.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_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);
|
||||
void pxl8_cart_free_file(u8* data);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#endif
|
||||
|
||||
#include "pxl8_log.h"
|
||||
#include "pxl8_mem.h"
|
||||
|
||||
typedef struct {
|
||||
u32 magic;
|
||||
|
|
@ -40,7 +41,7 @@ static u32 pxl8_save_checksum(const u8* data, u32 size) {
|
|||
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) {
|
||||
snprintf(path, path_size, "%s%chotreload.sav", save->directory, PATH_SEP);
|
||||
} 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) {
|
||||
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;
|
||||
|
||||
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),
|
||||
"%s%cpxl8%c%s", base_dir, PATH_SEP, PATH_SEP, game_name);
|
||||
} else {
|
||||
free(save);
|
||||
pxl8_free(save);
|
||||
return NULL;
|
||||
}
|
||||
#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 (!home) {
|
||||
free(save);
|
||||
pxl8_free(save);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +107,7 @@ pxl8_save* pxl8_save_create(const char* game_name, u32 magic, u32 version) {
|
|||
#endif
|
||||
|
||||
if (pxl8_save_ensure_directory(save->directory) != PXL8_OK) {
|
||||
free(save);
|
||||
pxl8_free(save);
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
u8* data = (u8*)malloc(header.size);
|
||||
u8* data = (u8*)pxl8_malloc(header.size);
|
||||
if (!data) {
|
||||
fclose(file);
|
||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (fread(data, 1, header.size, file) != header.size) {
|
||||
free(data);
|
||||
pxl8_free(data);
|
||||
fclose(file);
|
||||
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);
|
||||
if (checksum != header.checksum) {
|
||||
free(data);
|
||||
pxl8_free(data);
|
||||
pxl8_error("Save file checksum mismatch");
|
||||
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) {
|
||||
if (data) {
|
||||
free(data);
|
||||
pxl8_free(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue