true 16-bit color... glorious

This commit is contained in:
asrael 2025-11-28 14:41:35 -06:00
parent 3dccce8a81
commit b1e8525c3e
30 changed files with 678 additions and 652 deletions

View file

@ -4,6 +4,7 @@
#include <string.h>
#include "pxl8_ase.h"
#include "pxl8_color.h"
#include "pxl8_macros.h"
#include "pxl8_tilemap.h"
@ -105,11 +106,11 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
tilesheet->total_tiles = (width / tilesheet->tile_size) * (height / tilesheet->tile_size);
tilesheet->color_mode = pxl8_gfx_get_color_mode(gfx);
size_t data_size = width * height;
if (pxl8_gfx_get_color_mode(gfx) == PXL8_COLOR_MODE_HICOLOR) {
data_size *= 4;
}
u32 pixel_count = width * height;
u16 ase_depth = ase_file.header.color_depth;
bool gfx_hicolor = (tilesheet->color_mode == PXL8_COLOR_MODE_HICOLOR);
size_t data_size = pixel_count * pxl8_bytes_per_pixel(tilesheet->color_mode);
tilesheet->data = malloc(data_size);
if (!tilesheet->data) {
pxl8_ase_destroy(&ase_file);
@ -117,7 +118,41 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
}
if (ase_file.frame_count > 0 && ase_file.frames[0].pixels) {
memcpy(tilesheet->data, ase_file.frames[0].pixels, data_size);
const u8* src = ase_file.frames[0].pixels;
if (ase_depth == 8 && !gfx_hicolor) {
memcpy(tilesheet->data, src, pixel_count);
} else if (ase_depth == 32 && gfx_hicolor) {
u16* dst = (u16*)tilesheet->data;
const u32* rgba = (const u32*)src;
for (u32 i = 0; i < pixel_count; i++) {
u32 c = rgba[i];
u8 a = (c >> 24) & 0xFF;
if (a == 0) {
dst[i] = 0;
} else {
dst[i] = pxl8_rgba32_to_rgb565(c);
}
}
} else if (ase_depth == 8 && gfx_hicolor) {
pxl8_warn("Indexed ASE with hicolor gfx - storing as indexed");
tilesheet->color_mode = PXL8_COLOR_MODE_FAMI;
u8* new_data = realloc(tilesheet->data, pixel_count);
if (!new_data) {
free(tilesheet->data);
tilesheet->data = NULL;
pxl8_ase_destroy(&ase_file);
return PXL8_ERROR_OUT_OF_MEMORY;
}
tilesheet->data = new_data;
memcpy(tilesheet->data, src, pixel_count);
} else {
pxl8_error("Unsupported ASE color depth %d for gfx mode", ase_depth);
free(tilesheet->data);
tilesheet->data = NULL;
pxl8_ase_destroy(&ase_file);
return PXL8_ERROR_INVALID_ARGUMENT;
}
}
tilesheet->tile_valid = calloc(tilesheet->total_tiles + 1, sizeof(bool));
@ -138,15 +173,13 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
bool has_content = false;
for (u32 py = 0; py < tilesheet->tile_size && !has_content; py++) {
for (u32 px = 0; px < tilesheet->tile_size; px++) {
u32 idx = (tile_y + py) * width + (tile_x + px);
if (is_hicolor) {
u32 idx = ((tile_y + py) * width + (tile_x + px)) * 4;
u8 alpha = tilesheet->data[idx + 3];
if (alpha > 0) {
if (((u16*)tilesheet->data)[idx] != 0) {
has_content = true;
break;
}
} else {
u32 idx = (tile_y + py) * width + (tile_x + px);
if (tilesheet->data[idx] != 0) {
has_content = true;
break;
@ -277,17 +310,17 @@ pxl8_result pxl8_tilesheet_set_tile_pixels(pxl8_tilesheet* tilesheet, u16 tile_i
u32 tile_x = (tile_id - 1) % tilesheet->tiles_per_row;
u32 tile_y = (tile_id - 1) / tilesheet->tiles_per_row;
u32 bytes_per_pixel = (tilesheet->color_mode == PXL8_COLOR_MODE_HICOLOR) ? 4 : 1;
u32 bytes_per_pixel = pxl8_bytes_per_pixel(tilesheet->color_mode);
for (u32 py = 0; py < tilesheet->tile_size; py++) {
for (u32 px = 0; px < tilesheet->tile_size; px++) {
u32 src_idx = py * tilesheet->tile_size + px;
u32 dst_x = tile_x * tilesheet->tile_size + px;
u32 dst_y = tile_y * tilesheet->tile_size + py;
u32 dst_idx = (dst_y * tilesheet->width + dst_x) * bytes_per_pixel;
u32 dst_idx = dst_y * tilesheet->width + dst_x;
if (bytes_per_pixel == 4) {
((u32*)tilesheet->data)[dst_idx / 4] = pixels[src_idx];
if (bytes_per_pixel == 2) {
((u16*)tilesheet->data)[dst_idx] = ((const u16*)pixels)[src_idx];
} else {
tilesheet->data[dst_idx] = pixels[src_idx];
}