Text
Some checks failed
Build Dusk / run-tests (push) Failing after 1m47s
Build Dusk / build-linux (push) Failing after 1m47s
Build Dusk / build-psp (push) Failing after 1m53s

This commit is contained in:
2026-02-03 10:22:39 -06:00
parent fed819e9b2
commit c862071126
24 changed files with 420 additions and 336 deletions

View File

@@ -1,11 +1,12 @@
module('spritebatch')
module('camera')
module('color')
module('ui')
-- module('ui')
module('text')
module('screen')
module('time')
camera = cameraCreate(CAMERA_PROJECTION_TYPE_PERSPECTIVE)
uiPush('ui/test.dsf')
camera = cameraCreate(CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC)
function sceneDispose()
end
@@ -13,16 +14,22 @@ end
function sceneUpdate()
end
text = "Hello World"
function sceneRender()
cameraPushMatrix(camera)
spriteBatchPush(
nil,
0, 0,
1, 2,
colorBlue()
)
spriteBatchFlush()
camera.bottom = screenGetHeight()
camera.right = screenGetWidth()
width, height = textMeasure(text)
x = (screenGetWidth() - width)
x = math.sin(TIME.time * 2) * (x / 2) + (x / 2)
y = (screenGetHeight() - height) / 2
y = math.cos(TIME.time * 3) * (y) + (y)
textDraw(x, y, text)
cameraPopMatrix()
end

View File

@@ -3,5 +3,4 @@
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
add_asset(TILESET minogram.png type=PALETTIZED tileWidth=6 tileHeight=10 columns=16 rows=6)# Fixes PSP rendering
add_asset(SCRIPT test.lua)
add_asset(TILESET minogram.png type=PALETTIZED tileWidth=6 tileHeight=10 columns=16 rows=6)# Fixes PSP rendering

View File

@@ -1,9 +0,0 @@
module('spritebatch')
function uiElementRender(x, y, w, h)
spriteBatchPush(
nil,
x, y,
w, h
)
end

View File

@@ -11,6 +11,7 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
screen.c
texture.c
spritebatch.c
text.c
)
# Subdirectories

View File

@@ -34,9 +34,9 @@ void cameraInitOrthographic(camera_t *camera) {
camera->projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC;
camera->orthographic.left = 0.0f;
camera->orthographic.right = (float_t)frameBufferGetWidth(FRAMEBUFFER_BOUND);
camera->orthographic.bottom = 0.0f;
camera->orthographic.top = (float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND);
camera->orthographic.right = SCREEN.width;
camera->orthographic.top = 0.0f;
camera->orthographic.bottom = SCREEN.height;
camera->nearClip = -1.0f;
camera->farClip = 1.0f;

View File

@@ -1,113 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef float_t colorchannelf_t;
typedef uint8_t colorchannelb_t;
typedef struct {
colorchannelf_t r;
colorchannelf_t g;
colorchannelf_t b;
} color3f_t;
typedef struct {
colorchannelf_t r;
colorchannelf_t g;
colorchannelf_t b;
colorchannelf_t a;
} color4f_t;
typedef struct {
colorchannelb_t r;
colorchannelb_t g;
colorchannelb_t b;
} color3b_t;
typedef struct {
colorchannelb_t r;
colorchannelb_t g;
colorchannelb_t b;
colorchannelb_t a;
} color4b_t;
typedef color4b_t color_t;
#define color3f(r, g, b) ((color3f_t){r, g, b})
#define color4f(r, g, b, a) ((color4f_t){r, g, b, a})
#define color3b(r, g, b) ((color3b_t){r, g, b})
#define color4b(r, g, b, a) ((color4b_t){r, g, b, a})
#define color(r, g, b, a) ((color_t){r, g, b, a})
#define colorHex(hex) color( \
((hex >> 24) & 0xFF), \
((hex >> 16) & 0xFF), \
((hex >> 8) & 0xFF), \
(hex & 0xFF) \
)
#define COLOR_WHITE_3F color3f(1.0f, 1.0f, 1.0f)
#define COLOR_WHITE_4F color4f(1.0f, 1.0f, 1.0f, 1.0f)
#define COLOR_WHITE_3B color3b(255, 255, 255)
#define COLOR_WHITE_4B color4b(255, 255, 255, 255)
#define COLOR_WHITE color(255, 255, 255, 255)
#define COLOR_BLACK_3F color3f(0.0f, 0.0f, 0.0f)
#define COLOR_BLACK_4F color4f(0.0f, 0.0f, 0.0f, 1.0f)
#define COLOR_BLACK_3B color3b(0, 0, 0)
#define COLOR_BLACK_4B color4b(0, 0, 0, 255)
#define COLOR_BLACK color(0, 0, 0, 255)
#define COLOR_RED_3F color3f(1.0f, 0.0f, 0.0f)
#define COLOR_RED_4F color4f(1.0f, 0.0f, 0.0f, 1.0f)
#define COLOR_RED_3B color3b(255, 0, 0)
#define COLOR_RED_4B color4b(255, 0, 0, 255)
#define COLOR_RED color(255, 0, 0, 255)
#define COLOR_GREEN_3F color3f(0.0f, 1.0f, 0.0f)
#define COLOR_GREEN_4F color4f(0.0f, 1.0f, 0.0f, 1.0f)
#define COLOR_GREEN_3B color3b(0, 255, 0)
#define COLOR_GREEN_4B color4b(0, 255, 0, 255)
#define COLOR_GREEN color(0, 255, 0, 255)
#define COLOR_BLUE_3F color3f(0.0f, 0.0f, 1.0f)
#define COLOR_BLUE_4F color4f(0.0f, 0.0f, 1.0f, 1.0f)
#define COLOR_BLUE_3B color3b(0, 0, 255)
#define COLOR_BLUE_4B color4b(0, 0, 255, 255)
#define COLOR_BLUE color(0, 0, 255, 255)
#define COLOR_YELLOW_3F color3f(1.0f, 1.0f, 0.0f)
#define COLOR_YELLOW_4F color4f(1.0f, 1.0f, 0.0f, 1.0f)
#define COLOR_YELLOW_3B color3b(255, 255, 0)
#define COLOR_YELLOW_4B color4b(255, 255, 0, 255)
#define COLOR_YELLOW color(255, 255, 0, 255)
#define COLOR_CYAN_3F color3f(0.0f, 1.0f, 1.0f)
#define COLOR_CYAN_4F color4f(0.0f, 1.0f, 1.0f, 1.0f)
#define COLOR_CYAN_3B color3b(0, 255, 255)
#define COLOR_CYAN_4B color4b(0, 255, 255, 255)
#define COLOR_CYAN color(0, 255, 255, 255)
#define COLOR_MAGENTA_3F color3f(1.0f, 0.0f, 1.0f)
#define COLOR_MAGENTA_4F color4f(1.0f, 0.0f, 1.0f, 1.0f)
#define COLOR_MAGENTA_3B color3b(255, 0, 255)
#define COLOR_MAGENTA_4B color4b(255, 0, 255, 255)
#define COLOR_MAGENTA color(255, 0, 255, 255)
#define COLOR_TRANSPARENT_3F color3f(0.0f, 0.0f, 0.0f)
#define COLOR_TRANSPARENT_4F color4f(0.0f, 0.0f, 0.0f, 0.0f)
#define COLOR_TRANSPARENT_3B color3b(0, 0, 0)
#define COLOR_TRANSPARENT_4B color4b(0, 0, 0, 0)
#define COLOR_TRANSPARENT color(0, 0, 0, 0)
#define COLOR_CORNFLOWER_BLUE_3F color3f(0.39f, 0.58f, 0.93f)
#define COLOR_CORNFLOWER_BLUE_4F color4f(0.39f, 0.58f, 0.93f, 1.0f)
#define COLOR_CORNFLOWER_BLUE_3B color3b(100, 149, 237)
#define COLOR_CORNFLOWER_BLUE_4B color4b(100, 149, 237, 255)
#define COLOR_CORNFLOWER_BLUE color(100, 149, 237, 255)

View File

@@ -14,6 +14,7 @@
#include "display/screen.h"
#include "ui/ui.h"
#include "debug/debug.h"
#include "display/text.h"
display_t DISPLAY;
@@ -73,6 +74,7 @@ errorret_t displayInit(void) {
quadInit();
frameBufferInitBackbuffer();
spriteBatchInit();
errorChain(textInit());
screenInit();
errorOk();
@@ -145,6 +147,7 @@ errorret_t displayUpdate(void) {
errorret_t displayDispose(void) {
spriteBatchDispose();
screenDispose();
textDispose();
#if DISPLAY_SDL2
if(DISPLAY.glContext) {

124
src/display/text.c Normal file
View File

@@ -0,0 +1,124 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "text.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "display/spritebatch.h"
#include "asset/asset.h"
texture_t DEFAULT_FONT_TEXTURE;
errorret_t textInit(void) {
errorChain(assetLoad(DEFAULT_FONT_TILESET.image, &DEFAULT_FONT_TEXTURE));
errorOk();
}
void textDispose(void) {
textureDispose(&DEFAULT_FONT_TEXTURE);
}
void textDrawChar(
const float_t x,
const float_t y,
const char_t c,
const color_t color,
const tileset_t *tileset,
texture_t *texture
) {
int32_t tileIndex = (int32_t)(c) - TEXT_CHAR_START;
if(tileIndex < 0 || tileIndex >= tileset->tileCount) {
tileIndex = ((int32_t)'@') - TEXT_CHAR_START;
}
assertTrue(
tileIndex >= 0 && tileIndex <= tileset->tileCount,
"Character is out of bounds for font tiles"
);
vec4 uv;
tilesetTileGetUV(tileset, tileIndex, uv);
spriteBatchPush(
texture,
x, y,
x + tileset->tileWidth,
y + tileset->tileHeight,
color,
uv[0], uv[1], uv[2], uv[3]
);
}
void textDraw(
const float_t x,
const float_t y,
const char_t *text,
const color_t color,
const tileset_t *tileset,
texture_t *texture
) {
assertNotNull(text, "Text cannot be NULL");
float_t posX = x;
float_t posY = y;
char_t c;
int32_t i = 0;
while((c = text[i++]) != '\0') {
if(c == '\n') {
posX = x;
posY += tileset->tileHeight;
continue;
}
if(c == ' ') {
posX += tileset->tileWidth;
continue;
}
textDrawChar(posX, posY, c, color, tileset, texture);
posX += tileset->tileWidth;
}
}
void textMeasure(
const char_t *text,
const tileset_t *tileset,
int32_t *outWidth,
int32_t *outHeight
) {
assertNotNull(text, "Text cannot be NULL");
assertNotNull(outWidth, "Output width pointer cannot be NULL");
assertNotNull(outHeight, "Output height pointer cannot be NULL");
int32_t width = 0;
int32_t height = tileset->tileHeight;
int32_t lineWidth = 0;
char_t c;
int32_t i = 0;
while((c = text[i++]) != '\0') {
if(c == '\n') {
if(lineWidth > width) {
width = lineWidth;
}
lineWidth = 0;
height += tileset->tileHeight;
continue;
}
lineWidth += tileset->tileWidth;
}
if(lineWidth > width) {
width = lineWidth;
}
*outWidth = width;
*outHeight = height;
}

80
src/display/text.h Normal file
View File

@@ -0,0 +1,80 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/asset.h"
#include "display/texture.h"
#include "display/tileset/tileset.h"
#include "display/tileset/tileset_minogram.h"
#define TEXT_CHAR_START '!'
extern texture_t DEFAULT_FONT_TEXTURE;
#define DEFAULT_FONT_TILESET TILESET_MINOGRAM
/**
* Initializes the text system.
*/
errorret_t textInit(void);
/**
* Disposes of the text system.
*/
void textDispose(void);
/**
* Draws a single character at the specified position.
*
* @param x The x-coordinate to draw the character at.
* @param y The y-coordinate to draw the character at.
* @param c The character to draw.
* @param color The color to draw the character in.
* @param tileset Font tileset to use for rendering.
* @param texture Texture containing the font tileset image.
*/
void textDrawChar(
const float_t x,
const float_t y,
const char_t c,
const color_t color,
const tileset_t *tileset,
texture_t *texture
);
/**
* Draws a string of text at the specified position.
*
* @param x The x-coordinate to draw the text at.
* @param y The y-coordinate to draw the text at.
* @param text The null-terminated string of text to draw.
* @param color The color to draw the text in.
* @param tileset Font tileset to use for rendering.
* @param texture Texture containing the font tileset image.
*/
void textDraw(
const float_t x,
const float_t y,
const char_t *text,
const color_t color,
const tileset_t *tileset,
texture_t *texture
);
/**
* Measures the width and height of the given text string when rendered.
*
* @param text The null-terminated string of text to measure.
* @param tileset Font tileset to use for measurement.
* @param outWidth Pointer to store the measured width in pixels.
* @param outHeight Pointer to store the measured height in pixels.
*/
void textMeasure(
const char_t *text,
const tileset_t *tileset,
int32_t *outWidth,
int32_t *outHeight
);

View File

@@ -11,4 +11,6 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
modulespritebatch.c
moduleglm.c
modulecolor.c
moduletext.c
modulescreen.c
)

View File

@@ -0,0 +1,29 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "modulescreen.h"
#include "assert/assert.h"
#include "display/screen.h"
void moduleScreen(scriptcontext_t *context) {
assertNotNull(context, "Context cannot be NULL.");
lua_register(context->luaState, "screenGetWidth", moduleScreenGetWidth);
lua_register(context->luaState, "screenGetHeight", moduleScreenGetHeight);
}
int moduleScreenGetWidth(lua_State *L) {
assertNotNull(L, "Lua state is null");
lua_pushinteger(L, SCREEN.width);
return 1;
}
int moduleScreenGetHeight(lua_State *L) {
assertNotNull(L, "Lua state is null");
lua_pushinteger(L, SCREEN.height);
return 1;
}

View File

@@ -0,0 +1,32 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/scriptcontext.h"
/**
* Registers the Screen module with the given script context.
*
* @param context The script context to register the module with.
*/
void moduleScreen(scriptcontext_t *context);
/**
* Gets the current screen width.
*
* @param L The Lua state.
* @return Count of return values.
*/
int moduleScreenGetWidth(lua_State *L);
/**
* Gets the current screen height.
*
* @param L The Lua state.
* @return Count of return values.
*/
int moduleScreenGetHeight(lua_State *L);

View File

@@ -55,7 +55,6 @@ int moduleSpriteBatchPush(lua_State *L) {
return luaL_error(L, "Sprite color must be a color struct or nil");
}
// Optional UV min and maxes, defaults to 0,0 -> 1,1
float_t u0 = 0.0f;
float_t v0 = 0.0f;

View File

@@ -0,0 +1,83 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "moduletext.h"
#include "assert/assert.h"
#include "display/text.h"
#include "display/spritebatch.h"
void moduleText(scriptcontext_t *context) {
assertNotNull(context, "Script context is null");
lua_register(context->luaState, "textDraw", moduleTextDraw);
lua_register(context->luaState, "textMeasure", moduleTextMeasure);
}
int moduleTextDraw(lua_State *L) {
assertNotNull(L, "Lua state is null");
// Position.
if(!lua_isnumber(L, 1)) {
return luaL_error(L, "X position must be a number");
}
if(!lua_isnumber(L, 2)) {
return luaL_error(L, "Y position must be a number");
}
const float_t x = (float_t)lua_tonumber(L, 1);
const float_t y = (float_t)lua_tonumber(L, 2);
// String
if(!lua_isstring(L, 3)) {
return luaL_error(L, "Text to draw must be a string");
}
const char_t *text = (const char_t*)lua_tostring(L, 3);
// Optional color
color_t *color = NULL;
if(lua_gettop(L) < 6 || lua_isnil(L, 6)) {
// Allow NULL
} else if(lua_isuserdata(L, 6)) {
color = (color_t*)luaL_checkudata(L, 6, "color_mt");
} else {
return luaL_error(L, "Sprite color must be a color struct or nil");
}
// For now, use the default font tileset and texture.
textDraw(
x,
y,
text,
color == NULL ? COLOR_WHITE : *color,
&DEFAULT_FONT_TILESET,
&DEFAULT_FONT_TEXTURE
);
spriteBatchFlush();
}
int moduleTextMeasure(lua_State *L) {
assertNotNull(L, "Lua state is null");
// String
if(!lua_isstring(L, 1)) {
return luaL_error(L, "Text to measure must be a string");
}
const char_t *text = (const char_t*)lua_tostring(L, 1);
int32_t width = 0;
int32_t height = 0;
textMeasure(
text,
&DEFAULT_FONT_TILESET,
&width,
&height
);
lua_pushinteger(L, width);
lua_pushinteger(L, height);
return 2;
}

View File

@@ -0,0 +1,32 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/scriptcontext.h"
/**
* Register text rendering functions to the given script context.
*
* @param context The script context to register text functions to.
*/
void moduleText(scriptcontext_t *context);
/**
* Script binding for drawing text.
*
* @param L The Lua state.
* @return Number of return values on the Lua stack.
*/
int moduleTextDraw(lua_State *L);
/**
* Script binding for measuring text dimensions.
*
* @param L The Lua state.
* @return Number of return values on the Lua stack.
*/
int moduleTextMeasure(lua_State *L);

View File

@@ -18,6 +18,11 @@ void moduleTime(scriptcontext_t *ctx) {
lua_pushcfunction(ctx->luaState, moduleTimeIndex);
lua_settable(ctx->luaState, -3);
}
// Global time struct
lua_pushlightuserdata(ctx->luaState, &TIME);
luaL_setmetatable(ctx->luaState, "time_mt");
lua_setglobal(ctx->luaState, "TIME");
}
int moduleTimeIndex(lua_State *L) {

View File

@@ -12,25 +12,4 @@
void moduleUi(scriptcontext_t *ctx) {
assertNotNull(ctx, "Script context cannot be NULL");
lua_register(ctx->luaState, "uiPush", moduleUiPush);
}
int moduleUiPush(lua_State *L) {
assertNotNull(L, "Lua state cannot be NULL");
// Expect path string. TODO Support non scripted ui elements.
if(!lua_isstring(L, 1)) {
return luaL_error(L, "uiPush expects a string path as the first argument");
}
const char_t *path = lua_tostring(L, 1);
printf("Pushing UI from script: %s\n", path);
errorret_t err = uiPushScript(path);
if(err.code != ERROR_OK) {
errorCatch(errorPrint(err));
return luaL_error(L, "uiPush failed for path: %s", path);
}
return 0;
}

View File

@@ -7,20 +7,11 @@
#pragma once
#include "script/scriptcontext.h"
#include "error/error.h"
/**
* Registers the ui module within the given script context.
*
* @param ctx The script context to register the module in.
*/
void moduleUi(scriptcontext_t *ctx);
/**
* Lua binding for uiPush function.
*
* Expects a string path to the UI script as the first argument.
*
* @param L The Lua state.
* @return Number of return values on the Lua stack.
*/
int moduleUiPush(lua_State *L);
void moduleUi(scriptcontext_t *ctx);

View File

@@ -19,6 +19,8 @@
#include "script/module/display/modulecamera.h"
#include "script/module/display/moduleglm.h"
#include "script/module/ui/moduleui.h"
#include "script/module/display/moduletext.h"
#include "script/module/display/modulescreen.h"
#include "util/string.h"
const scriptmodule_t SCRIPT_MODULE_LIST[] = {
@@ -35,6 +37,8 @@ const scriptmodule_t SCRIPT_MODULE_LIST[] = {
{ .name = "camera", .callback = moduleCamera },
{ .name = "glm", .callback = moduleGLM },
{ .name = "ui", .callback = moduleUi },
{ .name = "text", .callback = moduleText },
{ .name = "screen", .callback = moduleScreen },
};
#define SCRIPT_MODULE_COUNT ( \

View File

@@ -7,5 +7,4 @@
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
ui.c
uielement.c
)

View File

@@ -24,11 +24,6 @@ errorret_t uiInit(void) {
}
void uiUpdate(void) {
uint_fast8_t i = 0;
while(i < UI.stackSize) {
errorCatch(errorPrint(uiElementUpdate(&UI.stack[i])));
i++;
}
}
void uiRender(void) {
@@ -38,34 +33,9 @@ void uiRender(void) {
cameraPushMatrix(&UI.camera);
spriteBatchClear();
uint_fast8_t i = 0;
while(i < UI.stackSize) {
errorCatch(errorPrint(uiElementRender(&UI.stack[i])));
i++;
}
spriteBatchFlush();
cameraPopMatrix();
}
errorret_t uiPushScript(const char_t *path) {
assertTrue(UI.stackSize < UI_STACK_SIZE, "UI stack overflow");
uielement_t *element = &UI.stack[UI.stackSize];
errorChain(uiElementInitScript(element, path));
UI.stackSize++;
// Ret Id or something?
errorOk();
}
void uiPop(void) {
assertTrue(UI.stackSize > 0, "UI stack underflow");
UI.stackSize--;
uielement_t *element = &UI.stack[UI.stackSize];
uiElementDispose(element);
}
void uiDispose(void) {
while(UI.stackSize > 0) {
uiPop();
}
}

View File

@@ -7,15 +7,10 @@
#pragma once
#include "display/camera/camera.h"
#include "ui/uielement.h"
#define UI_STACK_SIZE 64
#include "error/error.h"
typedef struct {
camera_t camera;
uielement_t stack[UI_STACK_SIZE];
uint_fast8_t stackSize;
} ui_t;
extern ui_t UI;
@@ -35,18 +30,6 @@ void uiUpdate(void);
*/
void uiRender(void);
/**
* Pushes a new UI element onto the UI stack from a script file.
*
* @param path Path to the UI script file.
*/
errorret_t uiPushScript(const char_t *path);
/**
* Pops the top UI element from the UI stack.
*/
void uiPop(void);
/**
* Disposes of the UI system.
*/

View File

@@ -1,70 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "uielement.h"
#include "display/screen.h"
#include "debug/debug.h"
errorret_t uiElementInitScript(
uielement_t *element,
const char_t *path
) {
errorChain(scriptContextInit(&element->ctx));
errorChain(scriptContextExecFile(&element->ctx, path));
errorOk();
}
errorret_t uiElementUpdate(uielement_t *element) {
lua_getglobal(element->ctx.luaState, "uiElementUpdate");
if(lua_isfunction(element->ctx.luaState, -1)) {
if(lua_pcall(element->ctx.luaState, 0, 0, 0) != LUA_OK) {
const char_t *strErr = lua_tostring(element->ctx.luaState, -1);
lua_pop(element->ctx.luaState, 1);
errorThrow("Failed to call UI element uiElementUpdate: %s", strErr);
}
} else {
lua_pop(element->ctx.luaState, 1);
}
errorOk();
}
errorret_t uiElementRender(uielement_t *element) {
lua_getglobal(element->ctx.luaState, "uiElementRender");
if(lua_isfunction(element->ctx.luaState, -1)) {
// Push parameters: x, y, w, h
lua_pushnumber(element->ctx.luaState, 0);
lua_pushnumber(element->ctx.luaState, 0);
lua_pushnumber(element->ctx.luaState, SCREEN.width);
lua_pushnumber(element->ctx.luaState, SCREEN.height);
if(lua_pcall(element->ctx.luaState, 4, 0, 0) != LUA_OK) {
const char_t *strErr = lua_tostring(element->ctx.luaState, -1);
lua_pop(element->ctx.luaState, 1);
errorThrow("Failed to call UI element uiElementRender: %s", strErr);
}
} else {
lua_pop(element->ctx.luaState, 1);
}
errorOk();
}
void uiElementDispose(uielement_t *element) {
lua_getglobal(element->ctx.luaState, "uiElementDispose");
if(lua_isfunction(element->ctx.luaState, -1)) {
if(lua_pcall(element->ctx.luaState, 0, 0, 0) != LUA_OK) {
const char_t *strErr = lua_tostring(element->ctx.luaState, -1);
lua_pop(element->ctx.luaState, 1);
debugPrint("Failed to call UI element uiElementDispose: %s\n", strErr);
}
} else {
lua_pop(element->ctx.luaState, 1);
}
scriptContextDispose(&element->ctx);
}

View File

@@ -1,46 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/scriptcontext.h"
// TODO: Support both scripted and native UI elements.
typedef struct {
scriptcontext_t ctx;
} uielement_t;
/**
* Initializes a scripted UI Element.
*
* @param element The UI element to initialize.
* @param path Path to the UI script file.
*/
errorret_t uiElementInitScript(
uielement_t *element,
const char_t *path
);
/**
* Updates/ticks a UI element's logic.
*
* @param element The UI element to tick.
*/
errorret_t uiElementUpdate(uielement_t *element);
/**
* Renders a UI element.
*
* @param element The UI element to render.
*/
errorret_t uiElementRender(uielement_t *element);
/**
* Disposes of a UI element.
*
* @param element The UI element to dispose of.
*/
void uiElementDispose(uielement_t *element);