refactor a bit into pxl8 sys struct
This commit is contained in:
parent
b2682a2d40
commit
f19b06d705
10 changed files with 217 additions and 148 deletions
|
|
@ -13,7 +13,7 @@ local world = require("pxl8.world")
|
||||||
local transition = require("pxl8.transition")
|
local transition = require("pxl8.transition")
|
||||||
local anim = require("pxl8.anim")
|
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 = {}
|
local pxl8 = {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@ local C = ffi.C
|
||||||
|
|
||||||
local core = {}
|
local core = {}
|
||||||
|
|
||||||
function core.init(game_ptr, gfx_ptr, input_ptr, ui_ptr)
|
function core.init(gfx_ptr, input_ptr, sys_ptr, ui_ptr)
|
||||||
core.game = game_ptr
|
|
||||||
core.gfx = gfx_ptr
|
core.gfx = gfx_ptr
|
||||||
core.input = input_ptr
|
core.input = input_ptr
|
||||||
|
core.sys = sys_ptr
|
||||||
core.ui = ui_ptr
|
core.ui = ui_ptr
|
||||||
end
|
end
|
||||||
|
|
||||||
function core.get_fps()
|
function core.get_fps()
|
||||||
return C.pxl8_game_get_fps(core.game)
|
return C.pxl8_get_fps(core.sys)
|
||||||
end
|
end
|
||||||
|
|
||||||
function core.get_width()
|
function core.get_width()
|
||||||
|
|
|
||||||
166
src/pxl8.c
166
src/pxl8.c
|
|
@ -14,19 +14,66 @@
|
||||||
#include "pxl8_hal.h"
|
#include "pxl8_hal.h"
|
||||||
#include "pxl8_macros.h"
|
#include "pxl8_macros.h"
|
||||||
#include "pxl8_script.h"
|
#include "pxl8_script.h"
|
||||||
|
#include "pxl8_sys.h"
|
||||||
#include "pxl8_types.h"
|
#include "pxl8_types.h"
|
||||||
#include "pxl8_ui.h"
|
#include "pxl8_ui.h"
|
||||||
|
|
||||||
pxl8_game_result pxl8_init(pxl8_game* game, i32 argc, char* argv[]) {
|
struct pxl8 {
|
||||||
if (!game) {
|
pxl8_cart* cart;
|
||||||
return PXL8_GAME_FAILURE;
|
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* sys = (pxl8*)calloc(1, sizeof(pxl8));
|
||||||
pxl8_error("HAL must be set before calling pxl8_init");
|
if (!sys) {
|
||||||
return PXL8_GAME_FAILURE;
|
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->color_mode = PXL8_COLOR_MODE_MEGA;
|
||||||
game->resolution = PXL8_RESOLUTION_640x360;
|
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];
|
pack_output = argv[++i];
|
||||||
} else {
|
} else {
|
||||||
pxl8_error("--pack requires <folder> <output.pxc>");
|
pxl8_error("--pack requires <folder> <output.pxc>");
|
||||||
return PXL8_GAME_FAILURE;
|
return PXL8_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
} else if (!script_arg) {
|
} else if (!script_arg) {
|
||||||
script_arg = argv[i];
|
script_arg = argv[i];
|
||||||
|
|
@ -54,39 +101,42 @@ pxl8_game_result pxl8_init(pxl8_game* game, i32 argc, char* argv[]) {
|
||||||
|
|
||||||
if (pack_mode) {
|
if (pack_mode) {
|
||||||
pxl8_result result = pxl8_cart_pack(pack_input, pack_output);
|
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) {
|
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);
|
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");
|
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) {
|
if (!game->gfx) {
|
||||||
pxl8_error("Failed to create graphics context");
|
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) {
|
if (pxl8_gfx_load_font_atlas(game->gfx) != PXL8_OK) {
|
||||||
pxl8_error("Failed to load font atlas");
|
pxl8_error("Failed to load font atlas");
|
||||||
return PXL8_GAME_FAILURE;
|
return PXL8_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
game->ui = pxl8_ui_create(game->gfx);
|
game->ui = pxl8_ui_create(game->gfx);
|
||||||
if (!game->ui) {
|
if (!game->ui) {
|
||||||
pxl8_error("Failed to create UI");
|
pxl8_error("Failed to create UI");
|
||||||
pxl8_gfx_destroy(game->gfx);
|
return PXL8_ERROR_INITIALIZATION_FAILED;
|
||||||
return PXL8_GAME_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
game->script = pxl8_script_create();
|
game->script = pxl8_script_create();
|
||||||
if (!game->script) {
|
if (!game->script) {
|
||||||
pxl8_error("Failed to initialize scripting: %s", pxl8_script_get_last_error(game->script));
|
pxl8_error("Failed to initialize scripting: %s", pxl8_script_get_last_error(game->script));
|
||||||
pxl8_gfx_destroy(game->gfx);
|
return PXL8_ERROR_INITIALIZATION_FAILED;
|
||||||
return PXL8_GAME_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* cart_path = script_arg ? script_arg : "demo";
|
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) {
|
if (is_cart) {
|
||||||
char* original_cwd = getcwd(NULL, 0);
|
char* original_cwd = getcwd(NULL, 0);
|
||||||
game->cart = pxl8_cart_create();
|
sys->cart = pxl8_cart_create();
|
||||||
if (!game->cart) {
|
if (!sys->cart) {
|
||||||
pxl8_error("Failed to create 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) {
|
if (pxl8_cart_load(sys->cart, cart_path) == PXL8_OK) {
|
||||||
pxl8_script_set_cart_path(game->script, pxl8_cart_get_base_path(game->cart), original_cwd);
|
pxl8_script_set_cart_path(game->script, pxl8_cart_get_base_path(sys->cart), original_cwd);
|
||||||
pxl8_cart_mount(game->cart);
|
pxl8_cart_mount(sys->cart);
|
||||||
strcpy(game->script_path, "main.fnl");
|
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 {
|
} else {
|
||||||
pxl8_error("Failed to load cart: %s", cart_path);
|
pxl8_error("Failed to load cart: %s", cart_path);
|
||||||
return PXL8_GAME_FAILURE;
|
return PXL8_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
free(original_cwd);
|
free(original_cwd);
|
||||||
} else if (script_arg) {
|
} 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_gfx(game->script, game->gfx);
|
||||||
pxl8_script_set_input(game->script, &game->input);
|
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_ui(game->script, game->ui);
|
||||||
pxl8_script_set_game(game->script, game);
|
|
||||||
|
|
||||||
if (game->script_path[0] != '\0') {
|
if (game->script_path[0] != '\0') {
|
||||||
pxl8_result result = pxl8_script_load_main(game->script, game->script_path);
|
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;
|
game->running = true;
|
||||||
|
|
||||||
|
return PXL8_OK;
|
||||||
return PXL8_GAME_CONTINUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_game_result pxl8_update(pxl8_game* game) {
|
pxl8_result pxl8_update(pxl8* sys) {
|
||||||
if (!game) {
|
if (!sys || !sys->game) {
|
||||||
return PXL8_GAME_FAILURE;
|
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;
|
f32 dt = (f32)(current_time - game->last_time) / 1000000000.0f;
|
||||||
|
|
||||||
game->last_time = current_time;
|
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);
|
pxl8_script_call_function_f32(game->script, "update", dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PXL8_GAME_CONTINUE;
|
return PXL8_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_game_result pxl8_frame(pxl8_game* game) {
|
pxl8_result pxl8_frame(pxl8* sys) {
|
||||||
if (!game) {
|
if (!sys || !sys->game) {
|
||||||
return PXL8_GAME_FAILURE;
|
return PXL8_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pxl8_game* game = sys->game;
|
||||||
pxl8_bounds bounds = pxl8_gfx_get_bounds(game->gfx);
|
pxl8_bounds bounds = pxl8_gfx_get_bounds(game->gfx);
|
||||||
|
|
||||||
if (game->script_loaded) {
|
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_x = 0;
|
||||||
game->input.mouse_wheel_y = 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) {
|
void pxl8_quit(pxl8* sys) {
|
||||||
if (!game) return;
|
if (!sys || !sys->game) return;
|
||||||
|
|
||||||
|
pxl8_game* game = sys->game;
|
||||||
|
|
||||||
if (game->repl_mode && game->repl) {
|
if (game->repl_mode && game->repl) {
|
||||||
fprintf(stderr, "\r\033[K");
|
fprintf(stderr, "\r\033[K");
|
||||||
|
|
@ -299,10 +355,8 @@ void pxl8_quit(pxl8_game* game) {
|
||||||
|
|
||||||
pxl8_info("Shutting down");
|
pxl8_info("Shutting down");
|
||||||
|
|
||||||
if (game->cart) {
|
if (sys->cart) {
|
||||||
pxl8_cart_unload(game->cart);
|
pxl8_cart_unmount(sys->cart);
|
||||||
free(game->cart);
|
|
||||||
game->cart = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_gfx_destroy(game->gfx);
|
pxl8_gfx_destroy(game->gfx);
|
||||||
|
|
@ -310,6 +364,28 @@ void pxl8_quit(pxl8_game* game) {
|
||||||
if (game->ui) pxl8_ui_destroy(game->ui);
|
if (game->ui) pxl8_ui_destroy(game->ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 pxl8_game_get_fps(const pxl8_game* game) {
|
bool pxl8_is_running(const pxl8* sys) {
|
||||||
return game ? game->fps : 0.0f;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "pxl8_cart.h"
|
|
||||||
#include "pxl8_gfx.h"
|
#include "pxl8_gfx.h"
|
||||||
#include "pxl8_hal.h"
|
|
||||||
#include "pxl8_script.h"
|
#include "pxl8_script.h"
|
||||||
#include "pxl8_types.h"
|
#include "pxl8_types.h"
|
||||||
#include "pxl8_ui.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 {
|
typedef struct pxl8_game {
|
||||||
const pxl8_hal* hal;
|
|
||||||
|
|
||||||
pxl8_cart* cart;
|
|
||||||
pxl8_color_mode color_mode;
|
pxl8_color_mode color_mode;
|
||||||
pxl8_gfx* gfx;
|
pxl8_gfx* gfx;
|
||||||
pxl8_resolution resolution;
|
pxl8_resolution resolution;
|
||||||
|
|
@ -31,25 +20,12 @@ typedef struct pxl8_game {
|
||||||
i32 fps_frame_count;
|
i32 fps_frame_count;
|
||||||
f32 fps;
|
f32 fps;
|
||||||
|
|
||||||
|
pxl8_input_state input;
|
||||||
|
pxl8_script_repl* repl;
|
||||||
|
|
||||||
bool repl_mode;
|
bool repl_mode;
|
||||||
bool repl_started;
|
bool repl_started;
|
||||||
bool running;
|
bool running;
|
||||||
bool script_loaded;
|
bool script_loaded;
|
||||||
char script_path[256];
|
char script_path[256];
|
||||||
|
|
||||||
pxl8_input_state input;
|
|
||||||
pxl8_script_repl* repl;
|
|
||||||
} pxl8_game;
|
} 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);
|
|
||||||
|
|
|
||||||
|
|
@ -135,11 +135,9 @@ u32 pxl8_gfx_get_palette_size(const pxl8_gfx* gfx) {
|
||||||
|
|
||||||
pxl8_gfx* pxl8_gfx_create(
|
pxl8_gfx* pxl8_gfx_create(
|
||||||
const pxl8_hal* hal,
|
const pxl8_hal* hal,
|
||||||
|
void* platform_data,
|
||||||
pxl8_color_mode mode,
|
pxl8_color_mode mode,
|
||||||
pxl8_resolution resolution,
|
pxl8_resolution resolution
|
||||||
const char* title,
|
|
||||||
i32 window_width,
|
|
||||||
i32 window_height
|
|
||||||
) {
|
) {
|
||||||
pxl8_gfx* gfx = (pxl8_gfx*)calloc(1, sizeof(pxl8_gfx));
|
pxl8_gfx* gfx = (pxl8_gfx*)calloc(1, sizeof(pxl8_gfx));
|
||||||
if (!gfx) {
|
if (!gfx) {
|
||||||
|
|
@ -148,6 +146,7 @@ pxl8_gfx* pxl8_gfx_create(
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx->hal = hal;
|
gfx->hal = hal;
|
||||||
|
gfx->platform_data = platform_data;
|
||||||
|
|
||||||
gfx->color_mode = mode;
|
gfx->color_mode = mode;
|
||||||
pxl8_gfx_get_resolution_dimensions(
|
pxl8_gfx_get_resolution_dimensions(
|
||||||
|
|
@ -156,9 +155,8 @@ pxl8_gfx* pxl8_gfx_create(
|
||||||
&gfx->framebuffer_height
|
&gfx->framebuffer_height
|
||||||
);
|
);
|
||||||
|
|
||||||
gfx->platform_data = gfx->hal->create(mode, resolution, title, window_width, window_height);
|
|
||||||
if (!gfx->platform_data) {
|
if (!gfx->platform_data) {
|
||||||
pxl8_error("Failed to create platform context");
|
pxl8_error("Platform data cannot be NULL");
|
||||||
free(gfx);
|
free(gfx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -213,11 +211,6 @@ void pxl8_gfx_destroy(pxl8_gfx* gfx) {
|
||||||
|
|
||||||
pxl8_atlas_destroy(gfx->atlas);
|
pxl8_atlas_destroy(gfx->atlas);
|
||||||
free(gfx->sprite_cache);
|
free(gfx->sprite_cache);
|
||||||
|
|
||||||
if (gfx->hal && gfx->platform_data) {
|
|
||||||
gfx->hal->destroy(gfx->platform_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(gfx->framebuffer);
|
free(gfx->framebuffer);
|
||||||
free(gfx->palette);
|
free(gfx->palette);
|
||||||
free(gfx->zbuffer);
|
free(gfx->zbuffer);
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ typedef struct pxl8_triangle {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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);
|
void pxl8_gfx_destroy(pxl8_gfx* gfx);
|
||||||
|
|
||||||
pxl8_bounds pxl8_gfx_get_bounds(pxl8_gfx* gfx);
|
pxl8_bounds pxl8_gfx_get_bounds(pxl8_gfx* gfx);
|
||||||
|
|
|
||||||
|
|
@ -80,12 +80,12 @@ static const char* pxl8_ffi_cdefs =
|
||||||
"typedef int64_t i64;\n"
|
"typedef int64_t i64;\n"
|
||||||
"typedef float f32;\n"
|
"typedef float f32;\n"
|
||||||
"typedef double f64;\n"
|
"typedef double f64;\n"
|
||||||
|
"typedef struct pxl8 pxl8;\n"
|
||||||
"typedef struct pxl8_gfx pxl8_gfx;\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, w, h; } pxl8_bounds;\n"
|
||||||
"typedef struct { int x, y; } pxl8_point;\n"
|
"typedef struct { int x, y; } pxl8_point;\n"
|
||||||
"\n"
|
"\n"
|
||||||
"f32 pxl8_game_get_fps(const pxl8_game* game);\n"
|
"f32 pxl8_get_fps(const pxl8* sys);\n"
|
||||||
"\n"
|
"\n"
|
||||||
"i32 pxl8_gfx_get_height(pxl8_gfx* ctx);\n"
|
"i32 pxl8_gfx_get_height(pxl8_gfx* ctx);\n"
|
||||||
"i32 pxl8_gfx_get_width(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) return;
|
||||||
if (script->L && game) {
|
if (script->L && sys) {
|
||||||
lua_pushlightuserdata(script->L, game);
|
lua_pushlightuserdata(script->L, sys);
|
||||||
lua_setglobal(script->L, "_pxl8_game");
|
lua_setglobal(script->L, "_pxl8_sys");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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_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_gfx(pxl8_script* script, pxl8_gfx* gfx);
|
||||||
void pxl8_script_set_input(pxl8_script* script, pxl8_input_state* input);
|
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_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(pxl8_script* script, const char* name);
|
||||||
pxl8_result pxl8_script_call_function_f32(pxl8_script* script, const char* name, f32 arg);
|
pxl8_result pxl8_script_call_function_f32(pxl8_script* script, const char* name, f32 arg);
|
||||||
|
|
|
||||||
104
src/pxl8_sdl3.c
104
src/pxl8_sdl3.c
|
|
@ -5,8 +5,8 @@
|
||||||
#include <SDL3/SDL_main.h>
|
#include <SDL3/SDL_main.h>
|
||||||
|
|
||||||
#include "pxl8_atlas.h"
|
#include "pxl8_atlas.h"
|
||||||
#include "pxl8_game.h"
|
|
||||||
#include "pxl8_macros.h"
|
#include "pxl8_macros.h"
|
||||||
|
#include "pxl8_sys.h"
|
||||||
|
|
||||||
typedef struct pxl8_sdl3_context {
|
typedef struct pxl8_sdl3_context {
|
||||||
SDL_Texture* atlas_texture;
|
SDL_Texture* atlas_texture;
|
||||||
|
|
@ -236,75 +236,73 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) {
|
||||||
return SDL_APP_FAILURE;
|
return SDL_APP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_game* game = (pxl8_game*)SDL_calloc(1, sizeof(pxl8_game));
|
pxl8* sys = pxl8_create(&pxl8_hal_sdl3);
|
||||||
if (!game) {
|
if (!sys) {
|
||||||
pxl8_error("Failed to allocate game instance");
|
pxl8_error("Failed to create pxl8 system");
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return SDL_APP_FAILURE;
|
return SDL_APP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
game->hal = &pxl8_hal_sdl3;
|
pxl8_result result = pxl8_init(sys, argc, argv);
|
||||||
|
if (result != PXL8_OK) {
|
||||||
pxl8_game_result result = pxl8_init(game, argc, argv);
|
pxl8_destroy(sys);
|
||||||
if (result != PXL8_GAME_CONTINUE) {
|
|
||||||
SDL_free(game);
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return SDL_APP_FAILURE;
|
return SDL_APP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*appstate = game;
|
*appstate = sys;
|
||||||
return SDL_APP_CONTINUE;
|
return SDL_APP_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_AppResult SDL_AppIterate(void* appstate) {
|
SDL_AppResult SDL_AppIterate(void* appstate) {
|
||||||
pxl8_game* game = (pxl8_game*)appstate;
|
pxl8* sys = (pxl8*)appstate;
|
||||||
|
if (!sys) {
|
||||||
if (!game) {
|
|
||||||
return SDL_APP_FAILURE;
|
return SDL_APP_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_game_result update_result = pxl8_update(game);
|
pxl8_result update_result = pxl8_update(sys);
|
||||||
if (update_result == PXL8_GAME_FAILURE) {
|
if (update_result != PXL8_OK) {
|
||||||
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) {
|
|
||||||
return SDL_APP_FAILURE;
|
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) {
|
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;
|
return SDL_APP_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case SDL_EVENT_QUIT:
|
case SDL_EVENT_QUIT:
|
||||||
game->running = false;
|
pxl8_set_running(sys, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_EVENT_KEY_DOWN: {
|
case SDL_EVENT_KEY_DOWN: {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (event->key.key == SDLK_ESCAPE) {
|
if (event->key.key == SDLK_ESCAPE) {
|
||||||
game->running = false;
|
pxl8_set_running(sys, false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_Scancode scancode = event->key.scancode;
|
SDL_Scancode scancode = event->key.scancode;
|
||||||
if (scancode < 256) {
|
if (scancode < 256) {
|
||||||
if (!game->input.keys_down[scancode]) {
|
if (!input->keys_down[scancode]) {
|
||||||
game->input.keys_pressed[scancode] = true;
|
input->keys_pressed[scancode] = true;
|
||||||
}
|
}
|
||||||
game->input.keys_down[scancode] = true;
|
input->keys_down[scancode] = true;
|
||||||
game->input.keys_released[scancode] = false;
|
input->keys_released[scancode] = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -312,9 +310,9 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
|
||||||
case SDL_EVENT_KEY_UP: {
|
case SDL_EVENT_KEY_UP: {
|
||||||
SDL_Scancode scancode = event->key.scancode;
|
SDL_Scancode scancode = event->key.scancode;
|
||||||
if (scancode < 256) {
|
if (scancode < 256) {
|
||||||
game->input.keys_down[scancode] = false;
|
input->keys_down[scancode] = false;
|
||||||
game->input.keys_pressed[scancode] = false;
|
input->keys_pressed[scancode] = false;
|
||||||
game->input.keys_released[scancode] = true;
|
input->keys_released[scancode] = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -322,11 +320,11 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
|
||||||
case SDL_EVENT_MOUSE_BUTTON_DOWN: {
|
case SDL_EVENT_MOUSE_BUTTON_DOWN: {
|
||||||
u8 button = event->button.button - 1;
|
u8 button = event->button.button - 1;
|
||||||
if (button < 3) {
|
if (button < 3) {
|
||||||
if (!game->input.mouse_buttons_down[button]) {
|
if (!input->mouse_buttons_down[button]) {
|
||||||
game->input.mouse_buttons_pressed[button] = true;
|
input->mouse_buttons_pressed[button] = true;
|
||||||
}
|
}
|
||||||
game->input.mouse_buttons_down[button] = true;
|
input->mouse_buttons_down[button] = true;
|
||||||
game->input.mouse_buttons_released[button] = false;
|
input->mouse_buttons_released[button] = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -334,15 +332,16 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
|
||||||
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
||||||
u8 button = event->button.button - 1;
|
u8 button = event->button.button - 1;
|
||||||
if (button < 3) {
|
if (button < 3) {
|
||||||
game->input.mouse_buttons_down[button] = false;
|
input->mouse_buttons_down[button] = false;
|
||||||
game->input.mouse_buttons_pressed[button] = false;
|
input->mouse_buttons_pressed[button] = false;
|
||||||
game->input.mouse_buttons_released[button] = true;
|
input->mouse_buttons_released[button] = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_EVENT_MOUSE_MOTION: {
|
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_x = (i32)event->motion.x;
|
||||||
i32 window_mouse_y = (i32)event->motion.y;
|
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);
|
SDL_GetWindowSize(window, &window_width, &window_height);
|
||||||
|
|
||||||
i32 render_width, render_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_bounds window_bounds = {0, 0, window_width, window_height};
|
||||||
pxl8_viewport vp = pxl8_gfx_viewport(window_bounds, render_width, render_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);
|
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_y = (i32)((window_mouse_y - vp.offset_y) / vp.scale);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_EVENT_MOUSE_WHEEL: {
|
case SDL_EVENT_MOUSE_WHEEL: {
|
||||||
game->input.mouse_wheel_x = (i32)event->wheel.x;
|
input->mouse_wheel_x = (i32)event->wheel.x;
|
||||||
game->input.mouse_wheel_y = (i32)event->wheel.y;
|
input->mouse_wheel_y = (i32)event->wheel.y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -377,10 +377,10 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
|
||||||
void SDL_AppQuit(void* appstate, SDL_AppResult result) {
|
void SDL_AppQuit(void* appstate, SDL_AppResult result) {
|
||||||
(void)result;
|
(void)result;
|
||||||
|
|
||||||
pxl8_game* game = (pxl8_game*)appstate;
|
pxl8* sys = (pxl8*)appstate;
|
||||||
if (game) {
|
if (sys) {
|
||||||
pxl8_quit(game);
|
pxl8_quit(sys);
|
||||||
SDL_free(game);
|
pxl8_destroy(sys);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
|
||||||
24
src/pxl8_sys.h
Normal file
24
src/pxl8_sys.h
Normal file
|
|
@ -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);
|
||||||
Loading…
Add table
Add a link
Reference in a new issue