improve sw renderer

This commit is contained in:
asrael 2026-01-21 23:19:50 -06:00
parent 415d424057
commit 39ee0fefb7
89 changed files with 9380 additions and 2307 deletions

View file

@ -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));