add fps util for pxl8 in lua
This commit is contained in:
parent
7dd32ec453
commit
5637fa18c8
9 changed files with 57 additions and 76 deletions
|
|
@ -7,6 +7,7 @@
|
||||||
./pxl8.sh run [game.cart | project_dir] # Run pxl8 demo (or a specific game)
|
./pxl8.sh run [game.cart | project_dir] # Run pxl8 demo (or a specific game)
|
||||||
./pxl8.sh run [game.cart | project_dir] --repl # Run pxl8 demo (or a specific game) with a REPL
|
./pxl8.sh run [game.cart | project_dir] --repl # Run pxl8 demo (or a specific game) with a REPL
|
||||||
```
|
```
|
||||||
|
**Note** The demo has keys 1-9 bound for different examples.
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> <strong>Heavy development. So... <em>here be dragons :3</em></strong>
|
> <strong>Heavy development. So... <em>here be dragons :3</em></strong>
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,12 @@
|
||||||
(local pxl8 (require :pxl8))
|
(local pxl8 (require :pxl8))
|
||||||
(local debug-ui (require :mod.debug_ui))
|
|
||||||
|
|
||||||
(var world nil)
|
(var world nil)
|
||||||
(var cam-x 1000)
|
(var cam-x 1000)
|
||||||
(var cam-y 64)
|
(local cam-y 64)
|
||||||
(var cam-z 1000)
|
(var cam-z 1000)
|
||||||
(var cam-yaw 0)
|
(var cam-yaw 0)
|
||||||
(var cam-pitch 0)
|
(var cam-pitch 0)
|
||||||
(var bob-time 0)
|
(var bob-time 0)
|
||||||
(var show-debug-ui false)
|
|
||||||
(var affine false)
|
|
||||||
(var fps 0)
|
|
||||||
(var fps-accumulator 0)
|
|
||||||
(var fps-frame-count 0)
|
|
||||||
|
|
||||||
(local move-speed 200)
|
(local move-speed 200)
|
||||||
(local turn-speed 2.0)
|
(local turn-speed 2.0)
|
||||||
|
|
@ -33,17 +27,16 @@
|
||||||
:iterations 4})]
|
:iterations 4})]
|
||||||
(if (< result 0)
|
(if (< result 0)
|
||||||
(pxl8.error (.. "Failed to generate cave - result: " result))
|
(pxl8.error (.. "Failed to generate cave - result: " result))
|
||||||
(do
|
|
||||||
(let [floor-tex (pxl8.procgen_tex {:name "floor"
|
(let [floor-tex (pxl8.procgen_tex {:name "floor"
|
||||||
:seed 11111
|
:seed 11111
|
||||||
:width 64
|
:width 64
|
||||||
:height 64
|
:height 64
|
||||||
:base_color 20})
|
:base_color 19})
|
||||||
ceiling-tex (pxl8.procgen_tex {:name "ceiling"
|
ceiling-tex (pxl8.procgen_tex {:name "ceiling"
|
||||||
:seed 22222
|
:seed 22222
|
||||||
:width 64
|
:width 64
|
||||||
:height 64
|
:height 64
|
||||||
:base_color 0})
|
:base_color 1})
|
||||||
wall-tex (pxl8.procgen_tex {:name "wall"
|
wall-tex (pxl8.procgen_tex {:name "wall"
|
||||||
:seed 12345
|
:seed 12345
|
||||||
:width 64
|
:width 64
|
||||||
|
|
@ -63,21 +56,9 @@
|
||||||
:texture_id wall-tex
|
:texture_id wall-tex
|
||||||
:rule (fn [normal] (and (<= normal.y 0.7) (>= normal.y -0.7)))}])]
|
:rule (fn [normal] (and (<= normal.y 0.7) (>= normal.y -0.7)))}])]
|
||||||
(when (< result 0)
|
(when (< result 0)
|
||||||
(pxl8.error (.. "Failed to apply textures - result: " result)))))))))
|
(pxl8.error (.. "Failed to apply textures - result: " result))))))))
|
||||||
|
|
||||||
(fn update [dt]
|
(fn update [dt]
|
||||||
(set fps-accumulator (+ fps-accumulator dt))
|
|
||||||
(set fps-frame-count (+ fps-frame-count 1))
|
|
||||||
|
|
||||||
(when (>= fps-accumulator 0.25)
|
|
||||||
(set fps (/ fps-frame-count fps-accumulator))
|
|
||||||
(set fps-accumulator 0)
|
|
||||||
(set fps-frame-count 0))
|
|
||||||
|
|
||||||
(when (pxl8.key_pressed "F8")
|
|
||||||
(set show-debug-ui (not show-debug-ui))
|
|
||||||
(pxl8.ui_window_set_open "Debug Menu (F8)" show-debug-ui))
|
|
||||||
|
|
||||||
(when (pxl8.world_is_loaded world)
|
(when (pxl8.world_is_loaded world)
|
||||||
(let [forward-x (- (math.sin cam-yaw))
|
(let [forward-x (- (math.sin cam-yaw))
|
||||||
forward-z (- (math.cos cam-yaw))
|
forward-z (- (math.cos cam-yaw))
|
||||||
|
|
@ -166,22 +147,12 @@
|
||||||
|
|
||||||
(pxl8.set_model (pxl8.mat4_identity))
|
(pxl8.set_model (pxl8.mat4_identity))
|
||||||
|
|
||||||
(pxl8.set_affine_textures affine)
|
|
||||||
(pxl8.world_render world [cam-x eye-y cam-z])
|
(pxl8.world_render world [cam-x eye-y cam-z])
|
||||||
|
|
||||||
(pxl8.text (.. "Pos: " (string.format "%.0f" cam-x) ","
|
(pxl8.text (.. "Pos: " (string.format "%.0f" cam-x) ","
|
||||||
(string.format "%.0f" cam-y) ","
|
(string.format "%.0f" cam-y) ","
|
||||||
(string.format "%.0f" cam-z)) 10 25 12)
|
(string.format "%.0f" cam-z)) 10 25 12)
|
||||||
|
(pxl8.text (.. "FPS: " (string.format "%.1f" (pxl8.get_fps))) 10 40 12))))
|
||||||
(let [new-state (debug-ui.render {:show-debug-ui show-debug-ui
|
|
||||||
:fps fps
|
|
||||||
:wireframe false
|
|
||||||
:auto-rotate false
|
|
||||||
:orthographic false
|
|
||||||
:use-texture true
|
|
||||||
:affine affine})]
|
|
||||||
(when (not= new-state.show-debug-ui nil) (set show-debug-ui new-state.show-debug-ui))
|
|
||||||
(when (not= new-state.affine nil) (set affine new-state.affine))))))
|
|
||||||
|
|
||||||
{:init init
|
{:init init
|
||||||
:update update
|
:update update
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
local ffi = require("ffi")
|
local ffi = require("ffi")
|
||||||
local C = ffi.C
|
local C = ffi.C
|
||||||
|
local game = _pxl8_game
|
||||||
local gfx = _pxl8_gfx
|
local gfx = _pxl8_gfx
|
||||||
local input = _pxl8_input
|
local input = _pxl8_input
|
||||||
local ui = _pxl8_ui
|
local ui = _pxl8_ui
|
||||||
|
|
@ -46,6 +47,10 @@ function pxl8.sprite(id, x, y, w, h, flip_x, flip_y)
|
||||||
C.pxl8_sprite(gfx, id or 0, x or 0, y or 0, w or 16, h or 16, flip_x or false, flip_y or false)
|
C.pxl8_sprite(gfx, id or 0, x or 0, y or 0, w or 16, h or 16, flip_x or false, flip_y or false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function pxl8.get_fps()
|
||||||
|
return C.pxl8_game_get_fps(game)
|
||||||
|
end
|
||||||
|
|
||||||
function pxl8.get_width()
|
function pxl8.get_width()
|
||||||
return C.pxl8_gfx_get_width(gfx)
|
return C.pxl8_gfx_get_width(gfx)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@ 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_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);
|
||||||
|
|
@ -307,3 +308,7 @@ void pxl8_quit(pxl8_game* game) {
|
||||||
pxl8_script_destroy(game->script);
|
pxl8_script_destroy(game->script);
|
||||||
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) {
|
||||||
|
return game ? game->fps : 0.0f;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,3 +52,4 @@ pxl8_game_result pxl8_init(pxl8_game* game, i32 argc, char* argv[]);
|
||||||
pxl8_game_result pxl8_update(pxl8_game* game);
|
pxl8_game_result pxl8_update(pxl8_game* game);
|
||||||
pxl8_game_result pxl8_frame(pxl8_game* game);
|
pxl8_game_result pxl8_frame(pxl8_game* game);
|
||||||
void pxl8_quit(pxl8_game* game);
|
void pxl8_quit(pxl8_game* game);
|
||||||
|
f32 pxl8_game_get_fps(const pxl8_game* game);
|
||||||
|
|
|
||||||
|
|
@ -79,9 +79,12 @@ static const char* pxl8_ffi_cdefs =
|
||||||
"typedef float f32;\n"
|
"typedef float f32;\n"
|
||||||
"typedef double f64;\n"
|
"typedef double f64;\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"
|
||||||
|
"\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"
|
||||||
"void pxl8_circle(pxl8_gfx* ctx, i32 x, i32 y, i32 r, u32 color);\n"
|
"void pxl8_circle(pxl8_gfx* ctx, i32 x, i32 y, i32 r, u32 color);\n"
|
||||||
|
|
@ -408,6 +411,14 @@ void pxl8_script_set_ui(pxl8_script* script, pxl8_ui* ui) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pxl8_script_set_game(pxl8_script* script, void* game) {
|
||||||
|
if (!script) return;
|
||||||
|
if (script->L && game) {
|
||||||
|
lua_pushlightuserdata(script->L, game);
|
||||||
|
lua_setglobal(script->L, "_pxl8_game");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static pxl8_result pxl8_script_prepare_path(pxl8_script* script, const char* filename, char* out_basename, size_t basename_size) {
|
static pxl8_result pxl8_script_prepare_path(pxl8_script* script, const char* filename, char* out_basename, size_t basename_size) {
|
||||||
char filename_copy[PATH_MAX];
|
char filename_copy[PATH_MAX];
|
||||||
strncpy(filename_copy, filename, sizeof(filename_copy) - 1);
|
strncpy(filename_copy, filename, sizeof(filename_copy) - 1);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ void pxl8_script_set_cart_path(pxl8_script* script, const char* cart_path, const
|
||||||
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_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);
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,6 @@ static void* sdl3_create(pxl8_color_mode mode, pxl8_resolution resolution,
|
||||||
pxl8_error("Failed to set vsync: %s", SDL_GetError());
|
pxl8_error("Failed to set vsync: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SetRenderLogicalPresentation(ctx->renderer, fb_w, fb_h,
|
|
||||||
SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
|
|
||||||
|
|
||||||
ctx->framebuffer_texture = SDL_CreateTexture(ctx->renderer,
|
ctx->framebuffer_texture = SDL_CreateTexture(ctx->renderer,
|
||||||
SDL_PIXELFORMAT_RGBA32,
|
SDL_PIXELFORMAT_RGBA32,
|
||||||
SDL_TEXTUREACCESS_STREAMING,
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
-- pxl8 tile properties editor
|
-- pxl8 tile properties dialog menu
|
||||||
-- provides a ui for editing custom properties of tilemap tiles
|
-- provides a ui for editing custom properties on tilemap tiles
|
||||||
|
|
||||||
local DEBUG = false
|
local DEBUG = false
|
||||||
|
|
||||||
|
|
@ -140,13 +140,11 @@ local function showPropertyEditor(existingProps)
|
||||||
option = prop.type,
|
option = prop.type,
|
||||||
options = { "boolean", "number", "string" },
|
options = { "boolean", "number", "string" },
|
||||||
onchange = function()
|
onchange = function()
|
||||||
-- Save all current field values and apply type conversions
|
|
||||||
for j = 1, #properties do
|
for j = 1, #properties do
|
||||||
properties[j].key = dlg.data["key_" .. j] or properties[j].key
|
properties[j].key = dlg.data["key_" .. j] or properties[j].key
|
||||||
local newType = dlg.data["type_" .. j] or properties[j].type
|
local newType = dlg.data["type_" .. j] or properties[j].type
|
||||||
local oldType = properties[j].type
|
local oldType = properties[j].type
|
||||||
|
|
||||||
-- Apply default values when type changes
|
|
||||||
if newType ~= oldType then
|
if newType ~= oldType then
|
||||||
if newType == "boolean" then
|
if newType == "boolean" then
|
||||||
properties[j].value = false
|
properties[j].value = false
|
||||||
|
|
@ -191,7 +189,6 @@ local function showPropertyEditor(existingProps)
|
||||||
id = "delete_" .. i,
|
id = "delete_" .. i,
|
||||||
text = "Delete",
|
text = "Delete",
|
||||||
onclick = function()
|
onclick = function()
|
||||||
-- Save current field values before deleting
|
|
||||||
for j = 1, #properties do
|
for j = 1, #properties do
|
||||||
properties[j].key = dlg.data["key_" .. j] or properties[j].key
|
properties[j].key = dlg.data["key_" .. j] or properties[j].key
|
||||||
properties[j].type = dlg.data["type_" .. j] or properties[j].type
|
properties[j].type = dlg.data["type_" .. j] or properties[j].type
|
||||||
|
|
@ -208,7 +205,6 @@ local function showPropertyEditor(existingProps)
|
||||||
dlg:button{
|
dlg:button{
|
||||||
text = "Add Property",
|
text = "Add Property",
|
||||||
onclick = function()
|
onclick = function()
|
||||||
-- Save current field values before adding new property
|
|
||||||
for i = 1, #properties do
|
for i = 1, #properties do
|
||||||
properties[i].key = dlg.data["key_" .. i] or properties[i].key
|
properties[i].key = dlg.data["key_" .. i] or properties[i].key
|
||||||
properties[i].type = dlg.data["type_" .. i] or properties[i].type
|
properties[i].type = dlg.data["type_" .. i] or properties[i].type
|
||||||
|
|
@ -254,14 +250,12 @@ local function showPropertyEditor(existingProps)
|
||||||
end
|
end
|
||||||
|
|
||||||
function init(plugin)
|
function init(plugin)
|
||||||
log("=== PLUGIN INIT START ===")
|
|
||||||
|
|
||||||
if not plugin then
|
if not plugin then
|
||||||
print("[tile-properties] ERROR: plugin is nil!")
|
print("[tile-properties] ERROR: plugin is nil!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Register in Sprite menu
|
-- register in sprite menu
|
||||||
plugin:newCommand{
|
plugin:newCommand{
|
||||||
id = "TilePropertiesEditor",
|
id = "TilePropertiesEditor",
|
||||||
title = "Tile Properties",
|
title = "Tile Properties",
|
||||||
|
|
@ -272,12 +266,7 @@ function init(plugin)
|
||||||
end,
|
end,
|
||||||
onclick = showPropertyEditor
|
onclick = showPropertyEditor
|
||||||
}
|
}
|
||||||
|
|
||||||
log("Command registered in Sprite menu")
|
|
||||||
|
|
||||||
log("=== PLUGIN INIT COMPLETE ===")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function exit(plugin)
|
function exit(plugin)
|
||||||
log("=== PLUGIN EXIT ===")
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue