diff --git a/src/lua/pxl8.lua b/src/lua/pxl8.lua index d8b5e9e..3827340 100644 --- a/src/lua/pxl8.lua +++ b/src/lua/pxl8.lua @@ -13,7 +13,7 @@ local world = require("pxl8.world") local transition = require("pxl8.transition") local anim = require("pxl8.anim") -core.init(_pxl8_game, _pxl8_gfx, _pxl8_input, _pxl8_ui) +core.init(_pxl8_gfx, _pxl8_input, _pxl8_sys, _pxl8_ui) local pxl8 = {} diff --git a/src/lua/pxl8/core.lua b/src/lua/pxl8/core.lua index a00f2c2..d80e434 100644 --- a/src/lua/pxl8/core.lua +++ b/src/lua/pxl8/core.lua @@ -3,15 +3,15 @@ local C = ffi.C local core = {} -function core.init(game_ptr, gfx_ptr, input_ptr, ui_ptr) - core.game = game_ptr +function core.init(gfx_ptr, input_ptr, sys_ptr, ui_ptr) core.gfx = gfx_ptr core.input = input_ptr + core.sys = sys_ptr core.ui = ui_ptr end function core.get_fps() - return C.pxl8_game_get_fps(core.game) + return C.pxl8_get_fps(core.sys) end function core.get_width() diff --git a/src/pxl8.c b/src/pxl8.c index 16163e5..8347b34 100644 --- a/src/pxl8.c +++ b/src/pxl8.c @@ -14,19 +14,66 @@ #include "pxl8_hal.h" #include "pxl8_macros.h" #include "pxl8_script.h" +#include "pxl8_sys.h" #include "pxl8_types.h" #include "pxl8_ui.h" -pxl8_game_result pxl8_init(pxl8_game* game, i32 argc, char* argv[]) { - if (!game) { - return PXL8_GAME_FAILURE; +struct pxl8 { + pxl8_cart* cart; + pxl8_game* game; + const pxl8_hal* hal; + void* platform_data; +}; + +pxl8* pxl8_create(const pxl8_hal* hal) { + if (!hal) { + pxl8_error("HAL cannot be NULL"); + return NULL; } - if (!game->hal) { - pxl8_error("HAL must be set before calling pxl8_init"); - return PXL8_GAME_FAILURE; + pxl8* sys = (pxl8*)calloc(1, sizeof(pxl8)); + if (!sys) { + pxl8_error("Failed to allocate pxl8 system"); + return NULL; } + sys->hal = hal; + + sys->game = (pxl8_game*)calloc(1, sizeof(pxl8_game)); + if (!sys->game) { + pxl8_error("Failed to allocate game"); + free(sys); + return NULL; + } + + return sys; +} + +void pxl8_destroy(pxl8* sys) { + if (!sys) return; + + if (sys->game) { + free(sys->game); + } + + if (sys->cart) { + pxl8_cart_destroy(sys->cart); + } + + if (sys->hal && sys->platform_data) { + sys->hal->destroy(sys->platform_data); + } + + free(sys); +} + +pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) { + if (!sys || !sys->game) { + return PXL8_ERROR_INVALID_ARGUMENT; + } + + pxl8_game* game = sys->game; + game->color_mode = PXL8_COLOR_MODE_MEGA; game->resolution = PXL8_RESOLUTION_640x360; @@ -45,7 +92,7 @@ pxl8_game_result pxl8_init(pxl8_game* game, i32 argc, char* argv[]) { pack_output = argv[++i]; } else { pxl8_error("--pack requires "); - return PXL8_GAME_FAILURE; + return PXL8_ERROR_INVALID_ARGUMENT; } } else if (!script_arg) { script_arg = argv[i]; @@ -54,39 +101,42 @@ pxl8_game_result pxl8_init(pxl8_game* game, i32 argc, char* argv[]) { if (pack_mode) { pxl8_result result = pxl8_cart_pack(pack_input, pack_output); - return (result == PXL8_OK) ? PXL8_GAME_SUCCESS : PXL8_GAME_FAILURE; + return result; } - - + if (game->repl_mode) { fprintf(stderr, "\033[38;2;184;187;38m[pxl8]\033[0m Starting in REPL mode with script: %s\n", game->script_path); } pxl8_info("Starting up"); - game->gfx = pxl8_gfx_create(game->hal, game->color_mode, game->resolution, "pxl8", 1280, 720); + sys->platform_data = sys->hal->create(game->color_mode, game->resolution, "pxl8", 1280, 720); + if (!sys->platform_data) { + pxl8_error("Failed to create platform context"); + return PXL8_ERROR_INITIALIZATION_FAILED; + } + + game->gfx = pxl8_gfx_create(sys->hal, sys->platform_data, game->color_mode, game->resolution); if (!game->gfx) { pxl8_error("Failed to create graphics context"); - return PXL8_GAME_FAILURE; + return PXL8_ERROR_INITIALIZATION_FAILED; } if (pxl8_gfx_load_font_atlas(game->gfx) != PXL8_OK) { pxl8_error("Failed to load font atlas"); - return PXL8_GAME_FAILURE; + return PXL8_ERROR_INITIALIZATION_FAILED; } game->ui = pxl8_ui_create(game->gfx); if (!game->ui) { pxl8_error("Failed to create UI"); - pxl8_gfx_destroy(game->gfx); - return PXL8_GAME_FAILURE; + return PXL8_ERROR_INITIALIZATION_FAILED; } game->script = pxl8_script_create(); if (!game->script) { pxl8_error("Failed to initialize scripting: %s", pxl8_script_get_last_error(game->script)); - pxl8_gfx_destroy(game->gfx); - return PXL8_GAME_FAILURE; + return PXL8_ERROR_INITIALIZATION_FAILED; } const char* cart_path = script_arg ? script_arg : "demo"; @@ -97,19 +147,19 @@ pxl8_game_result pxl8_init(pxl8_game* game, i32 argc, char* argv[]) { if (is_cart) { char* original_cwd = getcwd(NULL, 0); - game->cart = pxl8_cart_create(); - if (!game->cart) { + sys->cart = pxl8_cart_create(); + if (!sys->cart) { pxl8_error("Failed to create cart"); - return PXL8_GAME_FAILURE; + return PXL8_ERROR_INITIALIZATION_FAILED; } - if (pxl8_cart_load(game->cart, cart_path) == PXL8_OK) { - pxl8_script_set_cart_path(game->script, pxl8_cart_get_base_path(game->cart), original_cwd); - pxl8_cart_mount(game->cart); + if (pxl8_cart_load(sys->cart, cart_path) == PXL8_OK) { + pxl8_script_set_cart_path(game->script, pxl8_cart_get_base_path(sys->cart), original_cwd); + pxl8_cart_mount(sys->cart); strcpy(game->script_path, "main.fnl"); - pxl8_info("Loaded cart: %s", pxl8_cart_get_name(game->cart)); + pxl8_info("Loaded cart: %s", pxl8_cart_get_name(sys->cart)); } else { pxl8_error("Failed to load cart: %s", cart_path); - return PXL8_GAME_FAILURE; + return PXL8_ERROR_INITIALIZATION_FAILED; } free(original_cwd); } else if (script_arg) { @@ -119,8 +169,8 @@ pxl8_game_result pxl8_init(pxl8_game* game, i32 argc, char* argv[]) { pxl8_script_set_gfx(game->script, game->gfx); pxl8_script_set_input(game->script, &game->input); + pxl8_script_set_sys(game->script, sys); pxl8_script_set_ui(game->script, game->ui); - pxl8_script_set_game(game->script, game); if (game->script_path[0] != '\0') { pxl8_result result = pxl8_script_load_main(game->script, game->script_path); @@ -131,19 +181,20 @@ pxl8_game_result pxl8_init(pxl8_game* game, i32 argc, char* argv[]) { } } - game->last_time = game->hal->get_ticks(); + game->last_time = sys->hal->get_ticks(); game->running = true; - - return PXL8_GAME_CONTINUE; + return PXL8_OK; } -pxl8_game_result pxl8_update(pxl8_game* game) { - if (!game) { - return PXL8_GAME_FAILURE; +pxl8_result pxl8_update(pxl8* sys) { + if (!sys || !sys->game) { + return PXL8_ERROR_INVALID_ARGUMENT; } - u64 current_time = game->hal->get_ticks(); + pxl8_game* game = sys->game; + + u64 current_time = sys->hal->get_ticks(); f32 dt = (f32)(current_time - game->last_time) / 1000000000.0f; game->last_time = current_time; @@ -236,14 +287,15 @@ pxl8_game_result pxl8_update(pxl8_game* game) { pxl8_script_call_function_f32(game->script, "update", dt); } - return PXL8_GAME_CONTINUE; + return PXL8_OK; } -pxl8_game_result pxl8_frame(pxl8_game* game) { - if (!game) { - return PXL8_GAME_FAILURE; +pxl8_result pxl8_frame(pxl8* sys) { + if (!sys || !sys->game) { + return PXL8_ERROR_INVALID_ARGUMENT; } + pxl8_game* game = sys->game; pxl8_bounds bounds = pxl8_gfx_get_bounds(game->gfx); if (game->script_loaded) { @@ -284,11 +336,15 @@ pxl8_game_result pxl8_frame(pxl8_game* game) { game->input.mouse_wheel_x = 0; game->input.mouse_wheel_y = 0; - return game->running ? PXL8_GAME_CONTINUE : PXL8_GAME_SUCCESS; + game->frame_count++; + + return PXL8_OK; } -void pxl8_quit(pxl8_game* game) { - if (!game) return; +void pxl8_quit(pxl8* sys) { + if (!sys || !sys->game) return; + + pxl8_game* game = sys->game; if (game->repl_mode && game->repl) { fprintf(stderr, "\r\033[K"); @@ -299,10 +355,8 @@ void pxl8_quit(pxl8_game* game) { pxl8_info("Shutting down"); - if (game->cart) { - pxl8_cart_unload(game->cart); - free(game->cart); - game->cart = NULL; + if (sys->cart) { + pxl8_cart_unmount(sys->cart); } pxl8_gfx_destroy(game->gfx); @@ -310,6 +364,28 @@ void pxl8_quit(pxl8_game* game) { if (game->ui) pxl8_ui_destroy(game->ui); } -f32 pxl8_game_get_fps(const pxl8_game* game) { - return game ? game->fps : 0.0f; +bool pxl8_is_running(const pxl8* sys) { + return sys && sys->game && sys->game->running; +} + +void pxl8_set_running(pxl8* sys, bool running) { + if (sys && sys->game) { + sys->game->running = running; + } +} + +f32 pxl8_get_fps(const pxl8* sys) { + return (sys && sys->game) ? sys->game->fps : 0.0f; +} + +pxl8_gfx* pxl8_get_gfx(pxl8* sys) { + return (sys && sys->game) ? sys->game->gfx : NULL; +} + +pxl8_input_state* pxl8_get_input(pxl8* sys) { + return (sys && sys->game) ? &sys->game->input : NULL; +} + +pxl8_resolution pxl8_get_resolution(pxl8* sys) { + return (sys && sys->game) ? sys->game->resolution : PXL8_RESOLUTION_640x360; } diff --git a/src/pxl8_game.h b/src/pxl8_game.h index 9557806..c2fb2ff 100644 --- a/src/pxl8_game.h +++ b/src/pxl8_game.h @@ -1,22 +1,11 @@ #pragma once -#include "pxl8_cart.h" #include "pxl8_gfx.h" -#include "pxl8_hal.h" #include "pxl8_script.h" #include "pxl8_types.h" #include "pxl8_ui.h" -typedef enum pxl8_game_result { - PXL8_GAME_CONTINUE, - PXL8_GAME_SUCCESS, - PXL8_GAME_FAILURE -} pxl8_game_result; - typedef struct pxl8_game { - const pxl8_hal* hal; - - pxl8_cart* cart; pxl8_color_mode color_mode; pxl8_gfx* gfx; pxl8_resolution resolution; @@ -31,25 +20,12 @@ typedef struct pxl8_game { i32 fps_frame_count; f32 fps; + pxl8_input_state input; + pxl8_script_repl* repl; + bool repl_mode; bool repl_started; bool running; bool script_loaded; char script_path[256]; - - pxl8_input_state input; - pxl8_script_repl* repl; } pxl8_game; - -typedef struct pxl8_game_callbacks { - pxl8_game_result (*init)(pxl8_game* game, i32 argc, char* argv[]); - pxl8_game_result (*update)(pxl8_game* game); - pxl8_game_result (*frame)(pxl8_game* game); - void (*quit)(pxl8_game* game); -} pxl8_game_callbacks; - -pxl8_game_result pxl8_init(pxl8_game* game, i32 argc, char* argv[]); -pxl8_game_result pxl8_update(pxl8_game* game); -pxl8_game_result pxl8_frame(pxl8_game* game); -void pxl8_quit(pxl8_game* game); -f32 pxl8_game_get_fps(const pxl8_game* game); diff --git a/src/pxl8_gfx.c b/src/pxl8_gfx.c index b3cb16d..3380d04 100644 --- a/src/pxl8_gfx.c +++ b/src/pxl8_gfx.c @@ -135,11 +135,9 @@ u32 pxl8_gfx_get_palette_size(const pxl8_gfx* gfx) { pxl8_gfx* pxl8_gfx_create( const pxl8_hal* hal, + void* platform_data, pxl8_color_mode mode, - pxl8_resolution resolution, - const char* title, - i32 window_width, - i32 window_height + pxl8_resolution resolution ) { pxl8_gfx* gfx = (pxl8_gfx*)calloc(1, sizeof(pxl8_gfx)); if (!gfx) { @@ -148,6 +146,7 @@ pxl8_gfx* pxl8_gfx_create( } gfx->hal = hal; + gfx->platform_data = platform_data; gfx->color_mode = mode; pxl8_gfx_get_resolution_dimensions( @@ -156,9 +155,8 @@ pxl8_gfx* pxl8_gfx_create( &gfx->framebuffer_height ); - gfx->platform_data = gfx->hal->create(mode, resolution, title, window_width, window_height); if (!gfx->platform_data) { - pxl8_error("Failed to create platform context"); + pxl8_error("Platform data cannot be NULL"); free(gfx); return NULL; } @@ -213,11 +211,6 @@ void pxl8_gfx_destroy(pxl8_gfx* gfx) { pxl8_atlas_destroy(gfx->atlas); free(gfx->sprite_cache); - - if (gfx->hal && gfx->platform_data) { - gfx->hal->destroy(gfx->platform_data); - } - free(gfx->framebuffer); free(gfx->palette); free(gfx->zbuffer); diff --git a/src/pxl8_gfx.h b/src/pxl8_gfx.h index 7f3f2b7..e3f81ac 100644 --- a/src/pxl8_gfx.h +++ b/src/pxl8_gfx.h @@ -49,7 +49,7 @@ typedef struct pxl8_triangle { extern "C" { #endif -pxl8_gfx* pxl8_gfx_create(const pxl8_hal* hal, pxl8_color_mode mode, pxl8_resolution resolution, const char* title, i32 window_width, i32 window_height); +pxl8_gfx* pxl8_gfx_create(const pxl8_hal* hal, void* platform_data, pxl8_color_mode mode, pxl8_resolution resolution); void pxl8_gfx_destroy(pxl8_gfx* gfx); pxl8_bounds pxl8_gfx_get_bounds(pxl8_gfx* gfx); diff --git a/src/pxl8_script.c b/src/pxl8_script.c index 36a486f..88f51d7 100644 --- a/src/pxl8_script.c +++ b/src/pxl8_script.c @@ -80,12 +80,12 @@ static const char* pxl8_ffi_cdefs = "typedef int64_t i64;\n" "typedef float f32;\n" "typedef double f64;\n" +"typedef struct pxl8 pxl8;\n" "typedef struct pxl8_gfx pxl8_gfx;\n" -"typedef struct pxl8_game pxl8_game;\n" "typedef struct { int x, y, w, h; } pxl8_bounds;\n" "typedef struct { int x, y; } pxl8_point;\n" "\n" -"f32 pxl8_game_get_fps(const pxl8_game* game);\n" +"f32 pxl8_get_fps(const pxl8* sys);\n" "\n" "i32 pxl8_gfx_get_height(pxl8_gfx* ctx);\n" "i32 pxl8_gfx_get_width(pxl8_gfx* ctx);\n" @@ -451,11 +451,11 @@ void pxl8_script_set_ui(pxl8_script* script, pxl8_ui* ui) { } } -void pxl8_script_set_game(pxl8_script* script, void* game) { +void pxl8_script_set_sys(pxl8_script* script, void* sys) { if (!script) return; - if (script->L && game) { - lua_pushlightuserdata(script->L, game); - lua_setglobal(script->L, "_pxl8_game"); + if (script->L && sys) { + lua_pushlightuserdata(script->L, sys); + lua_setglobal(script->L, "_pxl8_sys"); } } diff --git a/src/pxl8_script.h b/src/pxl8_script.h index 4c7a188..813d756 100644 --- a/src/pxl8_script.h +++ b/src/pxl8_script.h @@ -19,8 +19,8 @@ const char* pxl8_script_get_last_error(pxl8_script* script); void pxl8_script_set_cart_path(pxl8_script* script, const char* cart_path, const char* original_cwd); void pxl8_script_set_gfx(pxl8_script* script, pxl8_gfx* gfx); void pxl8_script_set_input(pxl8_script* script, pxl8_input_state* input); +void pxl8_script_set_sys(pxl8_script* script, void* sys); void pxl8_script_set_ui(pxl8_script* script, pxl8_ui* ui); -void pxl8_script_set_game(pxl8_script* script, void* game); pxl8_result pxl8_script_call_function(pxl8_script* script, const char* name); pxl8_result pxl8_script_call_function_f32(pxl8_script* script, const char* name, f32 arg); diff --git a/src/pxl8_sdl3.c b/src/pxl8_sdl3.c index 6ecda08..a29a24b 100644 --- a/src/pxl8_sdl3.c +++ b/src/pxl8_sdl3.c @@ -5,8 +5,8 @@ #include #include "pxl8_atlas.h" -#include "pxl8_game.h" #include "pxl8_macros.h" +#include "pxl8_sys.h" typedef struct pxl8_sdl3_context { SDL_Texture* atlas_texture; @@ -236,75 +236,73 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { return SDL_APP_FAILURE; } - pxl8_game* game = (pxl8_game*)SDL_calloc(1, sizeof(pxl8_game)); - if (!game) { - pxl8_error("Failed to allocate game instance"); + pxl8* sys = pxl8_create(&pxl8_hal_sdl3); + if (!sys) { + pxl8_error("Failed to create pxl8 system"); SDL_Quit(); return SDL_APP_FAILURE; } - game->hal = &pxl8_hal_sdl3; - - pxl8_game_result result = pxl8_init(game, argc, argv); - if (result != PXL8_GAME_CONTINUE) { - SDL_free(game); + pxl8_result result = pxl8_init(sys, argc, argv); + if (result != PXL8_OK) { + pxl8_destroy(sys); SDL_Quit(); return SDL_APP_FAILURE; } - *appstate = game; + *appstate = sys; return SDL_APP_CONTINUE; } SDL_AppResult SDL_AppIterate(void* appstate) { - pxl8_game* game = (pxl8_game*)appstate; - - if (!game) { + pxl8* sys = (pxl8*)appstate; + if (!sys) { return SDL_APP_FAILURE; } - pxl8_game_result update_result = pxl8_update(game); - if (update_result == PXL8_GAME_FAILURE) { - return SDL_APP_FAILURE; - } - if (update_result == PXL8_GAME_SUCCESS) { - return SDL_APP_SUCCESS; - } - - pxl8_game_result frame_result = pxl8_frame(game); - if (frame_result == PXL8_GAME_FAILURE) { + pxl8_result update_result = pxl8_update(sys); + if (update_result != PXL8_OK) { return SDL_APP_FAILURE; } - return (frame_result == PXL8_GAME_SUCCESS) ? SDL_APP_SUCCESS : SDL_APP_CONTINUE; + pxl8_result frame_result = pxl8_frame(sys); + if (frame_result != PXL8_OK) { + return SDL_APP_FAILURE; + } + + return pxl8_is_running(sys) ? SDL_APP_CONTINUE : SDL_APP_SUCCESS; } SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { - pxl8_game* game = (pxl8_game*)appstate; + pxl8* sys = (pxl8*)appstate; + if (!sys) { + return SDL_APP_CONTINUE; + } - if (!game) { + pxl8_input_state* input = pxl8_get_input(sys); + if (!input) { return SDL_APP_CONTINUE; } switch (event->type) { case SDL_EVENT_QUIT: - game->running = false; + pxl8_set_running(sys, false); break; case SDL_EVENT_KEY_DOWN: { #ifdef DEBUG if (event->key.key == SDLK_ESCAPE) { - game->running = false; + pxl8_set_running(sys, false); } #endif SDL_Scancode scancode = event->key.scancode; if (scancode < 256) { - if (!game->input.keys_down[scancode]) { - game->input.keys_pressed[scancode] = true; + if (!input->keys_down[scancode]) { + input->keys_pressed[scancode] = true; } - game->input.keys_down[scancode] = true; - game->input.keys_released[scancode] = false; + input->keys_down[scancode] = true; + input->keys_released[scancode] = false; } break; } @@ -312,9 +310,9 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { case SDL_EVENT_KEY_UP: { SDL_Scancode scancode = event->key.scancode; if (scancode < 256) { - game->input.keys_down[scancode] = false; - game->input.keys_pressed[scancode] = false; - game->input.keys_released[scancode] = true; + input->keys_down[scancode] = false; + input->keys_pressed[scancode] = false; + input->keys_released[scancode] = true; } break; } @@ -322,11 +320,11 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { case SDL_EVENT_MOUSE_BUTTON_DOWN: { u8 button = event->button.button - 1; if (button < 3) { - if (!game->input.mouse_buttons_down[button]) { - game->input.mouse_buttons_pressed[button] = true; + if (!input->mouse_buttons_down[button]) { + input->mouse_buttons_pressed[button] = true; } - game->input.mouse_buttons_down[button] = true; - game->input.mouse_buttons_released[button] = false; + input->mouse_buttons_down[button] = true; + input->mouse_buttons_released[button] = false; } break; } @@ -334,15 +332,16 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { case SDL_EVENT_MOUSE_BUTTON_UP: { u8 button = event->button.button - 1; if (button < 3) { - game->input.mouse_buttons_down[button] = false; - game->input.mouse_buttons_pressed[button] = false; - game->input.mouse_buttons_released[button] = true; + input->mouse_buttons_down[button] = false; + input->mouse_buttons_pressed[button] = false; + input->mouse_buttons_released[button] = true; } break; } case SDL_EVENT_MOUSE_MOTION: { - if (!game->gfx) break; + pxl8_gfx* gfx = pxl8_get_gfx(sys); + if (!gfx) break; i32 window_mouse_x = (i32)event->motion.x; i32 window_mouse_y = (i32)event->motion.y; @@ -354,19 +353,20 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { SDL_GetWindowSize(window, &window_width, &window_height); i32 render_width, render_height; - pxl8_gfx_get_resolution_dimensions(game->resolution, &render_width, &render_height); + pxl8_resolution resolution = pxl8_get_resolution(sys); + pxl8_gfx_get_resolution_dimensions(resolution, &render_width, &render_height); pxl8_bounds window_bounds = {0, 0, window_width, window_height}; pxl8_viewport vp = pxl8_gfx_viewport(window_bounds, render_width, render_height); - game->input.mouse_x = (i32)((window_mouse_x - vp.offset_x) / vp.scale); - game->input.mouse_y = (i32)((window_mouse_y - vp.offset_y) / vp.scale); + input->mouse_x = (i32)((window_mouse_x - vp.offset_x) / vp.scale); + input->mouse_y = (i32)((window_mouse_y - vp.offset_y) / vp.scale); break; } case SDL_EVENT_MOUSE_WHEEL: { - game->input.mouse_wheel_x = (i32)event->wheel.x; - game->input.mouse_wheel_y = (i32)event->wheel.y; + input->mouse_wheel_x = (i32)event->wheel.x; + input->mouse_wheel_y = (i32)event->wheel.y; break; } } @@ -377,10 +377,10 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { void SDL_AppQuit(void* appstate, SDL_AppResult result) { (void)result; - pxl8_game* game = (pxl8_game*)appstate; - if (game) { - pxl8_quit(game); - SDL_free(game); + pxl8* sys = (pxl8*)appstate; + if (sys) { + pxl8_quit(sys); + pxl8_destroy(sys); } SDL_Quit(); diff --git a/src/pxl8_sys.h b/src/pxl8_sys.h new file mode 100644 index 0000000..207b991 --- /dev/null +++ b/src/pxl8_sys.h @@ -0,0 +1,24 @@ +#pragma once + +#include "pxl8_gfx.h" +#include "pxl8_hal.h" +#include "pxl8_io.h" +#include "pxl8_types.h" + +typedef struct pxl8 pxl8; + +pxl8* pxl8_create(const pxl8_hal* hal); +void pxl8_destroy(pxl8* sys); + +bool pxl8_is_running(const pxl8* sys); +void pxl8_set_running(pxl8* sys, bool running); + +f32 pxl8_get_fps(const pxl8* sys); +pxl8_gfx* pxl8_get_gfx(pxl8* sys); +pxl8_input_state* pxl8_get_input(pxl8* sys); +pxl8_resolution pxl8_get_resolution(pxl8* sys); + +pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]); +pxl8_result pxl8_update(pxl8* sys); +pxl8_result pxl8_frame(pxl8* sys); +void pxl8_quit(pxl8* sys);