refactor: add helpers for file I/O, main script detection, safe strncpy, & make hal generic

This commit is contained in:
asrael 2025-12-06 15:04:53 -06:00
parent a33d4c0068
commit db82efe269
No known key found for this signature in database
GPG key ID: 2786557804DFAE24
19 changed files with 327 additions and 457 deletions

View file

@ -4,37 +4,27 @@
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include "pxl8_atlas.h"
#include "pxl8_color.h"
#include "pxl8_log.h"
#include "pxl8_rec.h"
#include "pxl8_sys.h"
typedef struct pxl8_sdl3_context {
SDL_Texture* atlas_texture;
SDL_Texture* framebuffer_texture;
SDL_Texture* framebuffer;
SDL_Renderer* renderer;
SDL_Window* window;
u32* rgba_buffer;
size_t rgba_buffer_size;
u32 atlas_width;
u32 atlas_height;
} pxl8_sdl3_context;
static void* sdl3_create(pxl8_pixel_mode mode, pxl8_resolution resolution,
static void* sdl3_create(i32 render_w, i32 render_h,
const char* title, i32 win_w, i32 win_h) {
(void)mode;
pxl8_sdl3_context* ctx = (pxl8_sdl3_context*)SDL_calloc(1, sizeof(pxl8_sdl3_context));
if (!ctx) {
pxl8_error("Failed to allocate SDL3 context");
return NULL;
}
pxl8_size fb_size = pxl8_get_resolution_dimensions(resolution);
ctx->window = SDL_CreateWindow(title, win_w, win_h, SDL_WINDOW_RESIZABLE);
if (!ctx->window) {
pxl8_error("Failed to create window: %s", SDL_GetError());
@ -54,11 +44,11 @@ static void* sdl3_create(pxl8_pixel_mode mode, pxl8_resolution resolution,
pxl8_error("Failed to set vsync: %s", SDL_GetError());
}
ctx->framebuffer_texture = SDL_CreateTexture(ctx->renderer,
ctx->framebuffer = SDL_CreateTexture(ctx->renderer,
SDL_PIXELFORMAT_RGBA32,
SDL_TEXTUREACCESS_STREAMING,
fb_size.w, fb_size.h);
if (!ctx->framebuffer_texture) {
render_w, render_h);
if (!ctx->framebuffer) {
pxl8_error("Failed to create framebuffer texture: %s", SDL_GetError());
SDL_DestroyRenderer(ctx->renderer);
SDL_DestroyWindow(ctx->window);
@ -66,7 +56,7 @@ static void* sdl3_create(pxl8_pixel_mode mode, pxl8_resolution resolution,
return NULL;
}
SDL_SetTextureScaleMode(ctx->framebuffer_texture, SDL_SCALEMODE_NEAREST);
SDL_SetTextureScaleMode(ctx->framebuffer, SDL_SCALEMODE_NEAREST);
ctx->rgba_buffer = NULL;
ctx->rgba_buffer_size = 0;
@ -79,21 +69,10 @@ static void sdl3_destroy(void* platform_data) {
pxl8_sdl3_context* ctx = (pxl8_sdl3_context*)platform_data;
if (ctx->rgba_buffer) {
SDL_free(ctx->rgba_buffer);
}
if (ctx->atlas_texture) {
SDL_DestroyTexture(ctx->atlas_texture);
}
if (ctx->framebuffer_texture) {
SDL_DestroyTexture(ctx->framebuffer_texture);
}
if (ctx->renderer) {
SDL_DestroyRenderer(ctx->renderer);
}
if (ctx->window) {
SDL_DestroyWindow(ctx->window);
}
if (ctx->rgba_buffer) SDL_free(ctx->rgba_buffer);
if (ctx->framebuffer) SDL_DestroyTexture(ctx->framebuffer);
if (ctx->renderer) SDL_DestroyRenderer(ctx->renderer);
if (ctx->window) SDL_DestroyWindow(ctx->window);
SDL_free(ctx);
}
@ -111,17 +90,16 @@ static void sdl3_present(void* platform_data) {
SDL_SetRenderDrawColor(ctx->renderer, 0, 0, 0, 255);
SDL_RenderClear(ctx->renderer);
if (ctx->framebuffer_texture) {
SDL_RenderTexture(ctx->renderer, ctx->framebuffer_texture, NULL, NULL);
if (ctx->framebuffer) {
SDL_RenderTexture(ctx->renderer, ctx->framebuffer, NULL, NULL);
}
SDL_RenderPresent(ctx->renderer);
}
static void sdl3_upload_framebuffer(void* platform_data, const u8* fb,
i32 w, i32 h, const u32* palette,
pxl8_pixel_mode mode) {
if (!platform_data || !fb) return;
static void sdl3_upload_texture(void* platform_data, const u8* pixels, u32 w, u32 h,
const u32* palette, u32 bpp) {
if (!platform_data || !pixels) return;
pxl8_sdl3_context* ctx = (pxl8_sdl3_context*)platform_data;
size_t needed_size = w * h;
@ -133,81 +111,18 @@ static void sdl3_upload_framebuffer(void* platform_data, const u8* fb,
ctx->rgba_buffer_size = needed_size;
}
if (mode == PXL8_PIXEL_HICOLOR) {
const u16* fb16 = (const u16*)fb;
for (i32 i = 0; i < w * h; i++) {
ctx->rgba_buffer[i] = pxl8_rgb565_to_rgba32(fb16[i]);
if (bpp == 2) {
const u16* pixels16 = (const u16*)pixels;
for (u32 i = 0; i < w * h; i++) {
ctx->rgba_buffer[i] = pxl8_rgb565_to_rgba32(pixels16[i]);
}
} else {
for (i32 i = 0; i < w * h; i++) {
u8 index = fb[i];
ctx->rgba_buffer[i] = palette[index];
for (u32 i = 0; i < w * h; i++) {
ctx->rgba_buffer[i] = palette[pixels[i]];
}
}
SDL_UpdateTexture(ctx->framebuffer_texture, NULL, ctx->rgba_buffer, w * 4);
}
static void sdl3_upload_atlas(void* platform_data, const pxl8_atlas* atlas,
const u32* palette, pxl8_pixel_mode mode) {
if (!platform_data || !atlas) return;
pxl8_sdl3_context* ctx = (pxl8_sdl3_context*)platform_data;
if (!pxl8_atlas_is_dirty(atlas)) return;
u32 atlas_w = pxl8_atlas_get_width(atlas);
u32 atlas_h = pxl8_atlas_get_height(atlas);
const u8* atlas_pixels = pxl8_atlas_get_pixels(atlas);
if (!ctx->atlas_texture || ctx->atlas_width != atlas_w || ctx->atlas_height != atlas_h) {
if (ctx->atlas_texture) {
SDL_DestroyTexture(ctx->atlas_texture);
}
ctx->atlas_texture = SDL_CreateTexture(
ctx->renderer,
SDL_PIXELFORMAT_RGBA32,
SDL_TEXTUREACCESS_STREAMING,
atlas_w,
atlas_h
);
if (!ctx->atlas_texture) {
pxl8_error("Failed to create atlas texture: %s", SDL_GetError());
return;
}
SDL_SetTextureScaleMode(ctx->atlas_texture, SDL_SCALEMODE_NEAREST);
SDL_SetTextureBlendMode(ctx->atlas_texture, SDL_BLENDMODE_BLEND);
ctx->atlas_width = atlas_w;
ctx->atlas_height = atlas_h;
}
size_t needed_size = atlas_w * atlas_h;
if (ctx->rgba_buffer_size < needed_size) {
u32* new_buffer = (u32*)SDL_realloc(ctx->rgba_buffer, needed_size * 4);
if (!new_buffer) return;
ctx->rgba_buffer = new_buffer;
ctx->rgba_buffer_size = needed_size;
}
if (mode == PXL8_PIXEL_HICOLOR) {
const u16* atlas16 = (const u16*)atlas_pixels;
for (u32 i = 0; i < atlas_w * atlas_h; i++) {
u16 pixel = atlas16[i];
ctx->rgba_buffer[i] = (pixel != 0) ? pxl8_rgb565_to_rgba32(pixel) : 0x00000000;
}
} else {
for (u32 i = 0; i < atlas_w * atlas_h; i++) {
u8 index = atlas_pixels[i];
ctx->rgba_buffer[i] = palette[index];
}
}
SDL_UpdateTexture(ctx->atlas_texture, NULL, ctx->rgba_buffer, atlas_w * 4);
SDL_UpdateTexture(ctx->framebuffer, NULL, ctx->rgba_buffer, w * 4);
}
SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) {
@ -371,7 +286,7 @@ static void sdl3_set_relative_mouse_mode(void* platform_data, bool enabled) {
}
}
static void sdl3_set_cursor(void* platform_data, pxl8_cursor cursor) {
static void sdl3_set_cursor(void* platform_data, u32 cursor) {
if (!platform_data) return;
SDL_SystemCursor sdl_cursor;
@ -410,7 +325,6 @@ const pxl8_hal pxl8_hal_sdl3 = {
.center_cursor = sdl3_center_cursor,
.present = sdl3_present,
.set_cursor = sdl3_set_cursor,
.upload_atlas = sdl3_upload_atlas,
.upload_framebuffer = sdl3_upload_framebuffer,
.upload_texture = sdl3_upload_texture,
.set_relative_mouse_mode = sdl3_set_relative_mouse_mode,
};