Refactored and simplified lua stuff a lot.
This commit is contained in:
1 parent
78e1ae885a
commit
053778a502
53 files changed
+627
-793
No files matched your search
+1
-1
@@ -45,5 +45,5 @@ int moduleMapLoad(lua_State *L) {
|
||||
void moduleMapSystem(scriptcontext_t *context) {
|
||||
assertNotNull(context, "Script context cannot be NULL");
|
||||
|
||||
scriptContextRegFunc(context, "mapLoad", moduleMapLoad);
|
||||
lua_register(context->luaState, "mapLoad", moduleMapLoad);
|
||||
}
|
||||
@@ -128,8 +128,8 @@ int scriptFuncEntitySetZ(lua_State *L) {
|
||||
void scriptFuncEntity(scriptcontext_t *context) {
|
||||
assertNotNull(context, "Script context cannot be NULL");
|
||||
|
||||
scriptContextRegFunc(context, "entityAdd", scriptFuncEntityAdd);
|
||||
scriptContextRegFunc(context, "entitySetX", scriptFuncEntitySetX);
|
||||
scriptContextRegFunc(context, "entitySetY", scriptFuncEntitySetY);
|
||||
scriptContextRegFunc(context, "entitySetZ", scriptFuncEntitySetZ);
|
||||
lua_register(context->luaState, "entityAdd", scriptFuncEntityAdd);
|
||||
lua_register(context->luaState, "entitySetX", scriptFuncEntitySetX);
|
||||
lua_register(context->luaState, "entitySetY", scriptFuncEntitySetY);
|
||||
lua_register(context->luaState, "entitySetZ", scriptFuncEntitySetZ);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
# Copyright (c) 2025 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
@@ -6,5 +6,12 @@
|
||||
# Sources
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
scriptstruct.c
|
||||
ui.c
|
||||
uitext.c
|
||||
uidebug.c
|
||||
uiframe.c
|
||||
uitextbox.c
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(element)
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "ui.h"
|
||||
#include "assert/assert.h"
|
||||
#include "ui/uidebug.h"
|
||||
#include "util/memory.h"
|
||||
#include "display/tileset/tileset_minogram.h"
|
||||
#include "display/screen.h"
|
||||
// #include "ui/uitextbox.h"
|
||||
|
||||
ui_t UI;
|
||||
|
||||
errorret_t uiInit(void) {
|
||||
memoryZero(&UI, sizeof(ui_t));
|
||||
|
||||
cameraInitOrthographic(&UI.camera);
|
||||
|
||||
// Initialize UI components here
|
||||
uiSetFont(&TILESET_MINOGRAM);
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void uiUpdate(void) {
|
||||
// Update UI state here
|
||||
UI.camera.orthographic.left = 0;
|
||||
UI.camera.orthographic.right = SCREEN.width;
|
||||
UI.camera.orthographic.top = 0;
|
||||
UI.camera.orthographic.bottom = SCREEN.height;
|
||||
|
||||
// uiTextboxUpdate();
|
||||
}
|
||||
|
||||
void uiRender(void) {
|
||||
cameraPushMatrix(&UI.camera);
|
||||
|
||||
// Render UI elements here
|
||||
if(UI.fontTexture.width > 0) {
|
||||
uiDebugRender(UI.fontTileset, &UI.fontTexture);
|
||||
}
|
||||
cameraPopMatrix();
|
||||
}
|
||||
|
||||
errorret_t uiSetFont(const tileset_t *fontTileset) {
|
||||
if(UI.fontTexture.width > 0) {
|
||||
textureDispose(&UI.fontTexture);
|
||||
UI.fontTexture.width = -1;
|
||||
}
|
||||
|
||||
assertNotNull(fontTileset, "Font tileset cannot be NULL.");
|
||||
|
||||
UI.fontTileset = fontTileset;
|
||||
errorChain(assetLoad(UI.fontTileset->image, &UI.fontTexture));
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void uiDispose(void) {
|
||||
if(UI.fontTexture.width > 0) {
|
||||
textureDispose(&UI.fontTexture);
|
||||
UI.fontTexture.width = -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2025 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/camera/camera.h"
|
||||
|
||||
typedef struct {
|
||||
camera_t camera;
|
||||
texture_t fontTexture;
|
||||
const tileset_t *fontTileset;
|
||||
} ui_t;
|
||||
|
||||
extern ui_t UI;
|
||||
|
||||
/**
|
||||
* Initializes the UI system, loading necessary resources.
|
||||
*
|
||||
* @return An errorret_t indicating success or failure.
|
||||
*/
|
||||
errorret_t uiInit(void);
|
||||
|
||||
/**
|
||||
* Updates the UI state, handling user interactions and animations.
|
||||
*/
|
||||
void uiUpdate(void);
|
||||
|
||||
/**
|
||||
* Renders the UI elements to the screen.
|
||||
*/
|
||||
void uiRender(void);
|
||||
|
||||
/**
|
||||
* Sets the font tileset for UI text rendering.
|
||||
*
|
||||
* @param fontTileset Pointer to the tileset to use for UI fonts.
|
||||
*
|
||||
* @return An errorret_t indicating success or failure.
|
||||
*/
|
||||
errorret_t uiSetFont(const tileset_t *fontTileset);
|
||||
|
||||
/**
|
||||
* Cleans up and frees all UI resources.
|
||||
*/
|
||||
void uiDispose(void);
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,21 +1,17 @@
|
||||
module('spritebatch')
|
||||
module('time')
|
||||
-- module('time')
|
||||
module('camera')
|
||||
module('glm')
|
||||
-- module('glm')
|
||||
module('color')
|
||||
|
||||
camera = cameraCreate(CAMERA_PROJECTION_TYPE_PERSPECTIVE)
|
||||
|
||||
color = colorBlue()
|
||||
|
||||
function sceneDispose()
|
||||
-- print('Disposing initial scene')
|
||||
end
|
||||
|
||||
function sceneUpdate()
|
||||
color.r = 255 * (math.sin(TIME.time) + 1) * 0.5
|
||||
color.g = 255 * (math.sin(TIME.time + 2) + 1) * 0.5
|
||||
color.b = 255 * (math.sin(TIME.time + 4) + 1) * 0.5
|
||||
|
||||
end
|
||||
|
||||
function sceneRender()
|
||||
@@ -25,7 +21,7 @@ function sceneRender()
|
||||
nil,
|
||||
0, 0,
|
||||
1, 2,
|
||||
color
|
||||
colorBlue()
|
||||
)
|
||||
spriteBatchFlush()
|
||||
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
# 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)
|
||||
+7
-4
@@ -1,6 +1,9 @@
|
||||
module('ui')
|
||||
module('color')
|
||||
module('spritebatch')
|
||||
|
||||
function draw(x, y)
|
||||
uiDrawRect(COLOR_WHITE, x, y, 32, 32)
|
||||
function render(x, y, w, h)
|
||||
spriteBatchPush(
|
||||
nil,
|
||||
x, y,
|
||||
w, h
|
||||
)
|
||||
end
|
||||
@@ -65,5 +65,4 @@ add_subdirectory(script)
|
||||
add_subdirectory(thread)
|
||||
add_subdirectory(time)
|
||||
add_subdirectory(ui)
|
||||
add_subdirectory(ui2)
|
||||
add_subdirectory(util)
|
||||
@@ -23,8 +23,6 @@ typedef enum {
|
||||
} cameraviewtype_t;
|
||||
|
||||
typedef struct {
|
||||
cameraprojectiontype_t projType;
|
||||
cameraviewtype_t viewType;
|
||||
|
||||
union {
|
||||
mat4 view;
|
||||
@@ -63,6 +61,9 @@ typedef struct {
|
||||
|
||||
float_t nearClip;
|
||||
float_t farClip;
|
||||
|
||||
cameraprojectiontype_t projType;
|
||||
cameraviewtype_t viewType;
|
||||
} camera_t;
|
||||
|
||||
/**
|
||||
|
||||
+5
-5
@@ -8,7 +8,6 @@
|
||||
#include "event.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
#include "script/struct/scriptstruct.h"
|
||||
|
||||
void eventInit(
|
||||
event_t *event,
|
||||
@@ -228,10 +227,11 @@ void eventInvoke(
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, listener->user.script.luaFunctionRef);
|
||||
|
||||
if(eventParams != NULL && metatableName != NULL) {
|
||||
scriptStructPushMetatable(
|
||||
listener->user.script.context,
|
||||
metatableName,
|
||||
(void *)eventParams
|
||||
lua_getmetatable(L, -1);
|
||||
luaL_getmetatable(L, metatableName);
|
||||
assertTrue(
|
||||
lua_rawequal(L, -1, -2),
|
||||
"Event parameter metatable does not match expected type"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,4 +13,3 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
|
||||
# Subdirectories
|
||||
add_subdirectory(module)
|
||||
add_subdirectory(struct)
|
||||
@@ -9,19 +9,20 @@
|
||||
#include "assert/assert.h"
|
||||
#include "display/camera/camera.h"
|
||||
#include "util/memory.h"
|
||||
#include "script/struct/scriptstruct.h"
|
||||
#include "util/string.h"
|
||||
|
||||
void moduleCamera(scriptcontext_t *context) {
|
||||
assertNotNull(context, "Context cannot be NULL.");
|
||||
|
||||
// Structure
|
||||
scriptStructRegister(
|
||||
context,
|
||||
"camera_mt",
|
||||
moduleCameraGetter,
|
||||
moduleCameraSetter
|
||||
);
|
||||
// Create metatable for camera structure.
|
||||
if(luaL_newmetatable(context->luaState, "camera_mt")) {
|
||||
// Metatable methods
|
||||
lua_pushcfunction(context->luaState, moduleCameraIndex);
|
||||
lua_setfield(context->luaState, -2, "__index");
|
||||
lua_pushcfunction(context->luaState, moduleCameraNewIndex);
|
||||
lua_setfield(context->luaState, -2, "__newindex");
|
||||
lua_pop(context->luaState, 1);
|
||||
}
|
||||
|
||||
// Definitions
|
||||
#define MODULE_CAMERA_SCRIPT_LEN 64
|
||||
@@ -67,9 +68,9 @@ void moduleCamera(scriptcontext_t *context) {
|
||||
);
|
||||
|
||||
// Methods
|
||||
scriptContextRegFunc(context, "cameraCreate", moduleCameraCreate);
|
||||
scriptContextRegFunc(context, "cameraPushMatrix", moduleCameraPushMatrix);
|
||||
scriptContextRegFunc(context, "cameraPopMatrix", moduleCameraPopMatrix);
|
||||
lua_register(context->luaState, "cameraCreate", moduleCameraCreate);
|
||||
lua_register(context->luaState, "cameraPushMatrix", moduleCameraPushMatrix);
|
||||
lua_register(context->luaState, "cameraPopMatrix", moduleCameraPopMatrix);
|
||||
}
|
||||
|
||||
int moduleCameraCreate(lua_State *L) {
|
||||
@@ -84,12 +85,13 @@ int moduleCameraCreate(lua_State *L) {
|
||||
projType = (cameraprojectiontype_t)luaL_checkinteger(L, 1);
|
||||
}
|
||||
|
||||
// Create camera.
|
||||
// Create camera that Lua will own
|
||||
camera_t *cam = (camera_t *)lua_newuserdata(L, sizeof(camera_t));
|
||||
memoryZero(cam, sizeof(camera_t));
|
||||
|
||||
// Push metatable.
|
||||
scriptStructPushMetatable(context, "camera_mt", cam);
|
||||
// Set metatable
|
||||
luaL_getmetatable(L, "camera_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
// Init camera
|
||||
switch(projType) {
|
||||
@@ -114,9 +116,11 @@ int moduleCameraCreate(lua_State *L) {
|
||||
|
||||
int moduleCameraPushMatrix(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL.");
|
||||
assertTrue(lua_gettop(L) >= 1, "cameraPushMatrix requires 1 arg.");
|
||||
assertTrue(lua_isuserdata(L, 1), "cameraPushMatrix arg must be userdata.");
|
||||
|
||||
// Camera should be provided (pointer to camera_t).
|
||||
camera_t *cam = *(camera_t **)lua_touserdata(L, 1);
|
||||
camera_t *cam = (camera_t *)luaL_checkudata(L, 1, "camera_mt");
|
||||
assertNotNull(cam, "Camera pointer cannot be NULL.");
|
||||
|
||||
cameraPushMatrix(cam);
|
||||
@@ -129,64 +133,51 @@ int moduleCameraPopMatrix(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void moduleCameraGetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
const void *structPtr,
|
||||
scriptvalue_t *outValue
|
||||
) {
|
||||
assertNotNull(context, "Script context cannot be NULL.");
|
||||
assertNotNull(key, "Key cannot be NULL.");
|
||||
assertNotNull(structPtr, "Structure pointer cannot be NULL.");
|
||||
assertNotNull(outValue, "Output value cannot be NULL.");
|
||||
int moduleCameraIndex(lua_State *l) {
|
||||
assertNotNull(l, "Lua state cannot be NULL.");
|
||||
|
||||
camera_t *cam = (camera_t *)structPtr;
|
||||
const char_t *key = luaL_checkstring(l, 2);
|
||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
||||
|
||||
camera_t *cam = (camera_t *)luaL_checkudata(l, 1, "camera_mt");
|
||||
assertNotNull(cam, "Camera pointer cannot be NULL.");
|
||||
|
||||
if(stringCompare(key, "near") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = cam->nearClip;
|
||||
return;
|
||||
lua_pushnumber(l, cam->nearClip);
|
||||
return 1;
|
||||
} else if(stringCompare(key, "far") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = cam->farClip;
|
||||
return;
|
||||
lua_pushnumber(l, cam->farClip);
|
||||
return 1;
|
||||
} else if(stringCompare(key, "nearClip") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = cam->nearClip;
|
||||
return;
|
||||
lua_pushnumber(l, cam->nearClip);
|
||||
return 1;
|
||||
} else if(stringCompare(key, "farClip") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = cam->farClip;
|
||||
return;
|
||||
lua_pushnumber(l, cam->farClip);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Perspective relative values
|
||||
if(cam->projType == CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) {
|
||||
if(stringCompare(key, "left") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = cam->orthographic.left;
|
||||
return;
|
||||
lua_pushnumber(l, cam->orthographic.left);
|
||||
return 1;
|
||||
} else if(stringCompare(key, "right") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = cam->orthographic.right;
|
||||
return;
|
||||
lua_pushnumber(l, cam->orthographic.right);
|
||||
return 1;
|
||||
} else if(stringCompare(key, "top") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = cam->orthographic.top;
|
||||
return;
|
||||
lua_pushnumber(l, cam->orthographic.top);
|
||||
return 1;
|
||||
} else if(stringCompare(key, "bottom") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = cam->orthographic.bottom;
|
||||
return;
|
||||
lua_pushnumber(l, cam->orthographic.bottom);
|
||||
return 1;
|
||||
}
|
||||
} else if(
|
||||
cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE ||
|
||||
cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED
|
||||
) {
|
||||
if(stringCompare(key, "fov") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = cam->perspective.fov;
|
||||
return;
|
||||
lua_pushnumber(l, cam->perspective.fov);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,107 +185,92 @@ void moduleCameraGetter(
|
||||
if(cam->viewType == CAMERA_VIEW_TYPE_MATRIX) {
|
||||
|
||||
} else if(cam->viewType == CAMERA_VIEW_TYPE_LOOKAT) {
|
||||
if(stringCompare(key, "position") == 0) {
|
||||
scriptStructPushMetatable(
|
||||
context,
|
||||
"vec3_mt",
|
||||
(void*)&cam->lookat.position
|
||||
);
|
||||
outValue->type = SCRIPT_VALUE_TYPE_USERDATA;
|
||||
return;
|
||||
}
|
||||
// TODO: Push vec3
|
||||
} else if(cam->viewType == CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT) {
|
||||
|
||||
} else if(cam->viewType == CAMERA_VIEW_TYPE_2D) {
|
||||
|
||||
}
|
||||
|
||||
lua_pushnil(l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void moduleCameraSetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
void *structPtr,
|
||||
const scriptvalue_t *inValue
|
||||
) {
|
||||
assertNotNull(context, "Script context cannot be NULL.");
|
||||
assertNotNull(key, "Key cannot be NULL.");
|
||||
assertNotNull(structPtr, "Structure pointer cannot be NULL.");
|
||||
assertNotNull(inValue, "Input value cannot be NULL.");
|
||||
int moduleCameraNewIndex(lua_State *l) {
|
||||
assertNotNull(l, "Lua state cannot be NULL.");
|
||||
|
||||
camera_t *cam = (camera_t *)structPtr;
|
||||
const char_t *key = luaL_checkstring(l, 2);
|
||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
||||
|
||||
if(stringCompare(key, "near") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
cam->nearClip = inValue->value.floatValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
cam->nearClip = (float_t)inValue->value.intValue;
|
||||
camera_t *cam = (camera_t *)luaL_checkudata(l, 1, "camera_mt");
|
||||
assertNotNull(cam, "Camera pointer cannot be NULL.");
|
||||
|
||||
if(stringCompare(key, "near") == 0 || stringCompare(key, "nearClip") == 0) {
|
||||
if(!lua_isnumber(l, 3)) {
|
||||
luaL_error(l, "Camera near clip must be a number.");
|
||||
}
|
||||
return;
|
||||
} else if(stringCompare(key, "far") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
cam->farClip = inValue->value.floatValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
cam->farClip = (float_t)inValue->value.intValue;
|
||||
cam->nearClip = (float_t)lua_tonumber(l, 3);
|
||||
return 0;
|
||||
}
|
||||
return;
|
||||
} else if(stringCompare(key, "nearClip") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
cam->nearClip = inValue->value.floatValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
cam->nearClip = (float_t)inValue->value.intValue;
|
||||
|
||||
if(stringCompare(key, "far") == 0 || stringCompare(key, "farClip") == 0) {
|
||||
if(!lua_isnumber(l, 3)) {
|
||||
luaL_error(l, "Camera far clip must be a number.");
|
||||
}
|
||||
return;
|
||||
} else if(stringCompare(key, "farClip") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
cam->farClip = inValue->value.floatValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
cam->farClip = (float_t)inValue->value.intValue;
|
||||
}
|
||||
return;
|
||||
cam->farClip = (float_t)lua_tonumber(l, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Perspective relative values
|
||||
if(cam->projType == CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) {
|
||||
if(stringCompare(key, "left") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
cam->orthographic.left = inValue->value.floatValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
cam->orthographic.left = (float_t)inValue->value.intValue;
|
||||
if(!lua_isnumber(l, 3)) {
|
||||
luaL_error(l, "Camera orthographic left must be a number.");
|
||||
}
|
||||
return;
|
||||
} else if(stringCompare(key, "right") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
cam->orthographic.right = inValue->value.floatValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
cam->orthographic.right = (float_t)inValue->value.intValue;
|
||||
cam->orthographic.left = (float_t)lua_tonumber(l, 3);
|
||||
return 0;
|
||||
}
|
||||
return;
|
||||
} else if(stringCompare(key, "top") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
cam->orthographic.top = inValue->value.floatValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
cam->orthographic.top = (float_t)inValue->value.intValue;
|
||||
|
||||
if(stringCompare(key, "right") == 0) {
|
||||
if(!lua_isnumber(l, 3)) {
|
||||
luaL_error(l, "Camera orthographic right must be a number.");
|
||||
}
|
||||
return;
|
||||
} else if(stringCompare(key, "bottom") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
cam->orthographic.bottom = inValue->value.floatValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
cam->orthographic.bottom = (float_t)inValue->value.intValue;
|
||||
cam->orthographic.right = (float_t)lua_tonumber(l, 3);
|
||||
return 0;
|
||||
}
|
||||
return;
|
||||
|
||||
if(stringCompare(key, "top") == 0) {
|
||||
if(!lua_isnumber(l, 3)) {
|
||||
luaL_error(l, "Camera orthographic top must be a number.");
|
||||
}
|
||||
cam->orthographic.top = (float_t)lua_tonumber(l, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(stringCompare(key, "bottom") == 0) {
|
||||
if(!lua_isnumber(l, 3)) {
|
||||
luaL_error(l, "Camera orthographic bottom must be a number.");
|
||||
}
|
||||
cam->orthographic.bottom = (float_t)lua_tonumber(l, 3);
|
||||
return 0;
|
||||
}
|
||||
} else if(
|
||||
cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE ||
|
||||
cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED
|
||||
) {
|
||||
if(stringCompare(key, "fov") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
cam->perspective.fov = inValue->value.floatValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
cam->perspective.fov = (float_t)inValue->value.intValue;
|
||||
if(!lua_isnumber(l, 3)) {
|
||||
luaL_error(l, "Camera perspective FOV must be a number.");
|
||||
}
|
||||
return;
|
||||
cam->perspective.fov = (float_t)lua_tonumber(l, 3);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
luaL_error(
|
||||
l,
|
||||
"Attempted to set unknown or read-only camera field '%s'.",
|
||||
key
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
@@ -42,29 +42,13 @@ int moduleCameraPopMatrix(lua_State *L);
|
||||
/**
|
||||
* Getter for camera structure fields.
|
||||
*
|
||||
* @param context The script context.
|
||||
* @param key The field key.
|
||||
* @param structPtr Pointer to the camera structure.
|
||||
* @param outValue Output script value.
|
||||
* @param l The Lua state.
|
||||
*/
|
||||
void moduleCameraGetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
const void *structPtr,
|
||||
scriptvalue_t *outValue
|
||||
);
|
||||
int moduleCameraIndex(lua_State *l);
|
||||
|
||||
/**
|
||||
* Setter for camera structure fields.
|
||||
*
|
||||
* @param context The script context.
|
||||
* @param key The field key.
|
||||
* @param structPtr Pointer to the camera structure.
|
||||
* @param inValue Input script value.
|
||||
* @param l The Lua state.
|
||||
*/
|
||||
void moduleCameraSetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
void *structPtr,
|
||||
const scriptvalue_t *inValue
|
||||
);
|
||||
int moduleCameraNewIndex(lua_State *l);
|
||||
@@ -8,17 +8,25 @@
|
||||
#include "modulecolor.h"
|
||||
#include "display/color.h"
|
||||
#include "assert/assert.h"
|
||||
#include "script/struct/scriptstruct.h"
|
||||
#include "util/string.h"
|
||||
|
||||
void moduleColor(scriptcontext_t *context) {
|
||||
assertNotNull(context, "Context cannot be NULL.");
|
||||
|
||||
scriptStructRegister(
|
||||
context, "color_mt", moduleColorGetter, moduleColorSetter
|
||||
);
|
||||
if(luaL_newmetatable(context->luaState, "color_mt")) {
|
||||
// Metatable is new, set __index and __newindex
|
||||
lua_pushstring(context->luaState, "__index");
|
||||
lua_pushcfunction(context->luaState, moduleColorIndex);
|
||||
lua_settable(context->luaState, -3);
|
||||
|
||||
scriptContextRegFunc(context, "color", moduleColorFuncColor);
|
||||
lua_pushstring(context->luaState, "__newindex");
|
||||
lua_pushcfunction(context->luaState, moduleColorNewIndex);
|
||||
lua_settable(context->luaState, -3);
|
||||
|
||||
lua_pop(context->luaState, 1);
|
||||
}
|
||||
|
||||
lua_register(context->luaState, "color", moduleColorFuncColor);
|
||||
|
||||
scriptContextExec(context, COLOR_SCRIPT);
|
||||
}
|
||||
@@ -42,92 +50,85 @@ int moduleColorFuncColor(lua_State *L) {
|
||||
colorchannel8_t b = (colorchannel8_t)lua_tonumber(L, 3);
|
||||
colorchannel8_t a = (colorchannel8_t)lua_tonumber(L, 4);
|
||||
|
||||
// Create color_t as lua memory
|
||||
color_t *color = (color_t*)lua_newuserdata(L, sizeof(color_t));
|
||||
// Create color_t as lua memory, and push metatable
|
||||
color_t *color = (color_t *)lua_newuserdata(L, sizeof(color_t));
|
||||
luaL_getmetatable(L, "color_mt");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
// Initial values.
|
||||
color->r = r;
|
||||
color->g = g;
|
||||
color->b = b;
|
||||
color->a = a;
|
||||
|
||||
// Push color struct
|
||||
scriptStructPushMetatable(context, "color_mt", color);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void moduleColorGetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
const void *structPtr,
|
||||
scriptvalue_t *outValue
|
||||
) {
|
||||
const color_t *color = (color_t*)structPtr;
|
||||
int moduleColorIndex(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL.");
|
||||
|
||||
const char_t *key = lua_tostring(L, 2);
|
||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
||||
|
||||
const color_t *color = (const color_t*)luaL_checkudata(L, 1, "color_mt");
|
||||
assertNotNull(color, "Color struct cannot be NULL.");
|
||||
|
||||
if(stringCompare(key, "r") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_INT;
|
||||
outValue->value.intValue = color->r;
|
||||
return;
|
||||
lua_pushinteger(L, color->r);
|
||||
return 1;
|
||||
}
|
||||
if(stringCompare(key, "g") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_INT;
|
||||
outValue->value.intValue = color->g;
|
||||
return;
|
||||
lua_pushinteger(L, color->g);
|
||||
return 1;
|
||||
}
|
||||
if(stringCompare(key, "b") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_INT;
|
||||
outValue->value.intValue = color->b;
|
||||
return;
|
||||
lua_pushinteger(L, color->b);
|
||||
return 1;
|
||||
}
|
||||
if(stringCompare(key, "a") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_INT;
|
||||
outValue->value.intValue = color->a;
|
||||
return;
|
||||
lua_pushinteger(L, color->a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void moduleColorSetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
void *structPtr,
|
||||
const scriptvalue_t *inValue
|
||||
) {
|
||||
color_t *color = (color_t*)structPtr;
|
||||
int moduleColorNewIndex(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL.");
|
||||
|
||||
const char_t *key = lua_tostring(L, 2);
|
||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
||||
|
||||
color_t *color = (color_t*)luaL_checkudata(L, 1, "color_mt");
|
||||
assertNotNull(color, "Color struct cannot be NULL.");
|
||||
|
||||
if(stringCompare(key, "r") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
color->r = (colorchannel8_t)inValue->value.intValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
color->r = (colorchannel8_t)(inValue->value.floatValue);
|
||||
} else {
|
||||
assertUnreachable("Invalid type for color channel r");
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
return luaL_error(L, "color channel r must be a number.");
|
||||
}
|
||||
return;
|
||||
color->r = (colorchannel8_t)lua_tonumber(L, 3);
|
||||
return 0;
|
||||
} else if(stringCompare(key, "g") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
color->g = (colorchannel8_t)inValue->value.intValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
color->g = (colorchannel8_t)(inValue->value.floatValue);
|
||||
} else {
|
||||
assertUnreachable("Invalid type for color channel g");
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
return luaL_error(L, "color channel g must be a number.");
|
||||
}
|
||||
return;
|
||||
color->g = (colorchannel8_t)lua_tonumber(L, 3);
|
||||
return 0;
|
||||
} else if(stringCompare(key, "b") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
color->b = (colorchannel8_t)inValue->value.intValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
color->b = (colorchannel8_t)(inValue->value.floatValue);
|
||||
} else {
|
||||
assertUnreachable("Invalid type for color channel b");
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
return luaL_error(L, "color channel b must be a number.");
|
||||
}
|
||||
return;
|
||||
color->b = (colorchannel8_t)lua_tonumber(L, 3);
|
||||
return 0;
|
||||
} else if(stringCompare(key, "a") == 0) {
|
||||
if(inValue->type == SCRIPT_VALUE_TYPE_INT) {
|
||||
color->a = (colorchannel8_t)inValue->value.intValue;
|
||||
} else if(inValue->type == SCRIPT_VALUE_TYPE_FLOAT) {
|
||||
color->a = (colorchannel8_t)(inValue->value.floatValue);
|
||||
} else {
|
||||
assertUnreachable("Invalid type for color channel a");
|
||||
if(!lua_isnumber(L, 3)) {
|
||||
return luaL_error(L, "color channel a must be a number.");
|
||||
}
|
||||
return;
|
||||
color->a = (colorchannel8_t)lua_tonumber(L, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
luaL_error(L, "Invalid color channel key.");
|
||||
return 0;
|
||||
}
|
||||
@@ -24,31 +24,16 @@ void moduleColor(scriptcontext_t *context);
|
||||
int moduleColorFuncColor(lua_State *L);
|
||||
|
||||
/**
|
||||
* Getter function for the color structure.
|
||||
*
|
||||
* @param context The script context.
|
||||
* @param key The key to get.
|
||||
* @param structPtr Pointer to the color structure.
|
||||
* @param outValue Output value.
|
||||
* Index function for the color structure.
|
||||
* @param L The Lua state.
|
||||
* @return Number of return values.
|
||||
*/
|
||||
void moduleColorGetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
const void *structPtr,
|
||||
scriptvalue_t *outValue
|
||||
);
|
||||
int moduleColorIndex(lua_State *L);
|
||||
|
||||
/**
|
||||
* Setter function for the color structure.
|
||||
* New index function for the color structure.
|
||||
*
|
||||
* @param context The script context.
|
||||
* @param key The key to set.
|
||||
* @param structPtr Pointer to the color structure.
|
||||
* @param inValue Input value.
|
||||
* @param L The Lua state.
|
||||
* @return Number of return values.
|
||||
*/
|
||||
void moduleColorSetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
void *structPtr,
|
||||
const scriptvalue_t *inValue
|
||||
);
|
||||
int moduleColorNewIndex(lua_State *L);
|
||||
@@ -7,46 +7,45 @@
|
||||
|
||||
#include "moduleglm.h"
|
||||
#include "assert/assert.h"
|
||||
#include "script/struct/scriptstruct.h"
|
||||
#include "util/string.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
void moduleGLM(scriptcontext_t *context) {
|
||||
assertNotNull(context, "Context cannot be NULL.");
|
||||
|
||||
scriptStructRegister(
|
||||
context,
|
||||
"vec3_mt",
|
||||
moduleGLMVec3Getter,
|
||||
NULL
|
||||
);
|
||||
// scriptStructRegister(
|
||||
// context,
|
||||
// "vec3_mt",
|
||||
// moduleGLMVec3Getter,
|
||||
// NULL
|
||||
// );
|
||||
}
|
||||
|
||||
void moduleGLMVec3Getter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
const void *structPtr,
|
||||
scriptvalue_t *outValue
|
||||
) {
|
||||
assertNotNull(context, "Script context cannot be NULL.");
|
||||
assertNotNull(key, "Key cannot be NULL.");
|
||||
assertNotNull(structPtr, "Structure pointer cannot be NULL.");
|
||||
assertNotNull(outValue, "Output value cannot be NULL.");
|
||||
// void moduleGLMVec3Getter(
|
||||
// const scriptcontext_t *context,
|
||||
// const char_t *key,
|
||||
// const void *structPtr,
|
||||
// scriptvalue_t *outValue
|
||||
// ) {
|
||||
// assertNotNull(context, "Script context cannot be NULL.");
|
||||
// assertNotNull(key, "Key cannot be NULL.");
|
||||
// assertNotNull(structPtr, "Structure pointer cannot be NULL.");
|
||||
// assertNotNull(outValue, "Output value cannot be NULL.");
|
||||
|
||||
printf("Getting vec3 field %s\n", key);
|
||||
// printf("Getting vec3 field %s\n", key);
|
||||
|
||||
vec3 *v = (vec3 *)structPtr;
|
||||
if(stringCompare(key, "x") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = (*v)[0];
|
||||
return;
|
||||
} else if(stringCompare(key, "y") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = (*v)[1];
|
||||
return;
|
||||
} else if(stringCompare(key, "z") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = (*v)[2];
|
||||
return;
|
||||
}
|
||||
}
|
||||
// vec3 *v = (vec3 *)structPtr;
|
||||
// if(stringCompare(key, "x") == 0) {
|
||||
// outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
// outValue->value.floatValue = (*v)[0];
|
||||
// return;
|
||||
// } else if(stringCompare(key, "y") == 0) {
|
||||
// outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
// outValue->value.floatValue = (*v)[1];
|
||||
// return;
|
||||
// } else if(stringCompare(key, "z") == 0) {
|
||||
// outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
// outValue->value.floatValue = (*v)[2];
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
@@ -10,9 +10,9 @@
|
||||
#include "assert/assert.h"
|
||||
|
||||
void moduleSpriteBatch(scriptcontext_t *context) {
|
||||
scriptContextRegFunc(context, "spriteBatchFlush", moduleSpriteBatchFlush);
|
||||
scriptContextRegFunc(context, "spriteBatchClear", moduleSpriteBatchClear);
|
||||
scriptContextRegFunc(context, "spriteBatchPush", moduleSpriteBatchPush);
|
||||
lua_register(context->luaState, "spriteBatchFlush", moduleSpriteBatchFlush);
|
||||
lua_register(context->luaState, "spriteBatchClear", moduleSpriteBatchClear);
|
||||
lua_register(context->luaState, "spriteBatchPush", moduleSpriteBatchPush);
|
||||
}
|
||||
|
||||
int moduleSpriteBatchFlush(lua_State *L) {
|
||||
@@ -47,11 +47,10 @@ int moduleSpriteBatchPush(lua_State *L) {
|
||||
|
||||
// Color (struct) or nil for white
|
||||
color_t *color = NULL;
|
||||
if(lua_isuserdata(L, 6)) {
|
||||
color = *(color_t**)lua_touserdata(L, 6);
|
||||
assertNotNull(color, "Color struct cannot be NULL");
|
||||
} else if(lua_isnil(L, 6)) {
|
||||
// Extrapolate later.
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -41,5 +41,5 @@ int moduleEventSubscribe(lua_State *L) {
|
||||
|
||||
void moduleEvent(scriptcontext_t *context) {
|
||||
// Reg functions
|
||||
scriptContextRegFunc(context, "eventSubscribe", moduleEventSubscribe);
|
||||
lua_register(context->luaState, "eventSubscribe", moduleEventSubscribe);
|
||||
}
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "input/input.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/string.h"
|
||||
#include "script/struct/scriptstruct.h"
|
||||
|
||||
void moduleInput(scriptcontext_t *context) {
|
||||
assertNotNull(context, "Script context cannot be NULL");
|
||||
@@ -37,27 +36,39 @@ void moduleInput(scriptcontext_t *context) {
|
||||
);
|
||||
|
||||
// Script structure
|
||||
scriptStructRegister(context, "input_mt", &moduleInputEventGetter, NULL);
|
||||
if(luaL_newmetatable(context->luaState, "input_mt")) {
|
||||
// Metatable methods
|
||||
lua_pushcfunction(context->luaState, moduleInputIndex);
|
||||
lua_setfield(context->luaState, -2, "__index");
|
||||
}
|
||||
|
||||
|
||||
// Events
|
||||
scriptContextRegPointer(context,"INPUT_EVENT_PRESSED",&INPUT.eventPressed);
|
||||
scriptContextRegPointer(context,"INPUT_EVENT_RELEASED",&INPUT.eventReleased);
|
||||
lua_pushlightuserdata(context->luaState, &INPUT.eventPressed);
|
||||
lua_setglobal(context->luaState, "INPUT_EVENT_PRESSED");
|
||||
|
||||
lua_pushlightuserdata(context->luaState, &INPUT.eventReleased);
|
||||
lua_setglobal(context->luaState, "INPUT_EVENT_RELEASED");
|
||||
|
||||
// Bind methods
|
||||
scriptContextRegFunc(context, "inputBind", moduleInputBind);
|
||||
lua_register(context->luaState, "inputBind", moduleInputBind);
|
||||
}
|
||||
|
||||
void moduleInputEventGetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
const void *structPtr,
|
||||
scriptvalue_t *outValue
|
||||
) {
|
||||
int moduleInputIndex(lua_State *l) {
|
||||
assertNotNull(l, "Lua state cannot be NULL");
|
||||
|
||||
const char_t *key = luaL_checkstring(l, 2);
|
||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
||||
|
||||
if(stringCompare(key, "action") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_INT;
|
||||
outValue->value.intValue = ((const inputevent_t*)structPtr)->action;
|
||||
return;
|
||||
lua_pushinteger(
|
||||
l,
|
||||
((const inputevent_t*)lua_touserdata(l, 1))->action
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moduleInputBind(lua_State *L) {
|
||||
|
||||
@@ -16,19 +16,11 @@
|
||||
void moduleInput(scriptcontext_t *context);
|
||||
|
||||
/**
|
||||
* Script event getter for input events.
|
||||
* Getter for input structure fields.
|
||||
*
|
||||
* @param context The script context.
|
||||
* @param key The key to get.
|
||||
* @param structPtr Pointer to the input event struct.
|
||||
* @param outValue Output script value.
|
||||
* @param l The Lua state.
|
||||
*/
|
||||
void moduleInputEventGetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
const void *structPtr,
|
||||
scriptvalue_t *outValue
|
||||
);
|
||||
int moduleInputIndex(lua_State *l);
|
||||
|
||||
/**
|
||||
* Script binding for binding an input button to an action.
|
||||
|
||||
@@ -17,19 +17,20 @@ void moduleItem(scriptcontext_t *context) {
|
||||
scriptContextExec(context, ITEM_SCRIPT);
|
||||
|
||||
// Bind BACKPACK const pointer
|
||||
scriptContextRegPointer(context, "BACKPACK", (void *)&BACKPACK);
|
||||
lua_pushlightuserdata(context->luaState, &BACKPACK);
|
||||
lua_setglobal(context->luaState, "BACKPACK");
|
||||
|
||||
// Bind Methods
|
||||
scriptContextRegFunc(
|
||||
context, "inventoryItemExists", moduleInventoryItemExists
|
||||
lua_register(
|
||||
context->luaState, "inventoryItemExists", moduleInventoryItemExists
|
||||
);
|
||||
scriptContextRegFunc(context, "inventoryAdd", moduleInventoryAdd);
|
||||
scriptContextRegFunc(context, "inventorySet", moduleInventorySet);
|
||||
scriptContextRegFunc(context, "inventoryRemove", moduleInventoryRemove);
|
||||
scriptContextRegFunc(context, "inventoryGetCount", moduleInventoryGetCount);
|
||||
scriptContextRegFunc(context, "inventoryIsFull", moduleInventoryIsFull);
|
||||
scriptContextRegFunc(context, "inventoryItemFull", moduleInventoryItemFull);
|
||||
scriptContextRegFunc(context, "inventorySort", moduleInventorySort);
|
||||
lua_register(context->luaState, "inventoryAdd", moduleInventoryAdd);
|
||||
lua_register(context->luaState, "inventorySet", moduleInventorySet);
|
||||
lua_register(context->luaState, "inventoryRemove", moduleInventoryRemove);
|
||||
lua_register(context->luaState, "inventoryGetCount", moduleInventoryGetCount);
|
||||
lua_register(context->luaState, "inventoryIsFull", moduleInventoryIsFull);
|
||||
lua_register(context->luaState, "inventoryItemFull", moduleInventoryItemFull);
|
||||
lua_register(context->luaState, "inventorySort", moduleInventorySort);
|
||||
}
|
||||
|
||||
int moduleInventoryItemExists(lua_State *L) {
|
||||
|
||||
@@ -15,9 +15,9 @@ void moduleLocale(scriptcontext_t *context) {
|
||||
// Execute the locale script definitions.
|
||||
scriptContextExec(context, LOCALE_SCRIPT);
|
||||
|
||||
scriptContextRegFunc(context, "localeGet", moduleLocaleGet);
|
||||
scriptContextRegFunc(context, "localeSet", moduleLocaleSet);
|
||||
scriptContextRegFunc(context, "localeGetName", moduleLocaleGetName);
|
||||
lua_register(context->luaState, "localeGet", moduleLocaleGet);
|
||||
lua_register(context->luaState, "localeSet", moduleLocaleSet);
|
||||
lua_register(context->luaState, "localeGetName", moduleLocaleGetName);
|
||||
}
|
||||
|
||||
int moduleLocaleGet(lua_State *L) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
void moduleScene(scriptcontext_t *ctx) {
|
||||
assertNotNull(ctx, "Script context cannot be NULL");
|
||||
|
||||
scriptContextRegFunc(ctx, "sceneSet", moduleSceneSet);
|
||||
lua_register(ctx->luaState, "sceneSet", moduleSceneSet);
|
||||
}
|
||||
|
||||
int moduleSceneSet(lua_State *L) {
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
void moduleSystem(scriptcontext_t *context) {
|
||||
assertNotNull(context, "Script context cannot be NULL");
|
||||
|
||||
scriptContextRegFunc(context, "print", moduleSysPrint);
|
||||
scriptContextRegFunc(context, "include", moduleSysInclude);
|
||||
scriptContextRegFunc(context, "module", moduleSysModule);
|
||||
lua_register(context->luaState, "print", moduleSysPrint);
|
||||
lua_register(context->luaState, "include", moduleSysInclude);
|
||||
lua_register(context->luaState, "module", moduleSysModule);
|
||||
}
|
||||
|
||||
int moduleSysPrint(lua_State *L) {
|
||||
|
||||
@@ -7,31 +7,30 @@
|
||||
|
||||
#include "moduletime.h"
|
||||
#include "assert/assert.h"
|
||||
#include "script/struct/scriptstruct.h"
|
||||
|
||||
void moduleTime(scriptcontext_t *ctx) {
|
||||
assertNotNull(ctx, "Script context cannot be NULL");
|
||||
|
||||
// Script structure
|
||||
scriptStructRegister(ctx, "time_mt", moduleTimeGetter, NULL);
|
||||
if(luaL_newmetatable(ctx->luaState, "time_mt")) {
|
||||
// Metatable is new, set __index
|
||||
lua_pushstring(ctx->luaState, "__index");
|
||||
lua_pushcfunction(ctx->luaState, moduleTimeIndex);
|
||||
lua_settable(ctx->luaState, -3);
|
||||
}
|
||||
}
|
||||
|
||||
int moduleTimeIndex(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL.");
|
||||
|
||||
// Register struct
|
||||
scriptStructPush(ctx, "time_mt", "TIME", &TIME);
|
||||
}
|
||||
const char_t *key = lua_tostring(L, 2);
|
||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
||||
|
||||
void moduleTimeGetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
const void *structPtr,
|
||||
scriptvalue_t *outValue
|
||||
) {
|
||||
if(stringCompare(key, "delta") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = TIME.delta;
|
||||
return;
|
||||
lua_pushnumber(L, TIME.delta);
|
||||
return 1;
|
||||
} else if(stringCompare(key, "time") == 0) {
|
||||
outValue->type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
outValue->value.floatValue = TIME.time;
|
||||
return;
|
||||
lua_pushnumber(L, TIME.time);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -18,16 +18,8 @@
|
||||
void moduleTime(scriptcontext_t *ctx);
|
||||
|
||||
/**
|
||||
* Getter function for the TIME struct in scripts.
|
||||
*
|
||||
* @param context The script context.
|
||||
* @param key The key being accessed.
|
||||
* @param structPtr Pointer to the struct instance.
|
||||
* @param outValue Output parameter to store the retrieved value.
|
||||
* Index function for the time structure.
|
||||
* @param L The Lua state.
|
||||
* @return Number of return values.
|
||||
*/
|
||||
void moduleTimeGetter(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
const void *structPtr,
|
||||
scriptvalue_t *outValue
|
||||
);
|
||||
int moduleTimeIndex(lua_State *L);
|
||||
@@ -7,9 +7,30 @@
|
||||
|
||||
#include "moduleui.h"
|
||||
#include "assert/assert.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -14,3 +14,13 @@
|
||||
* @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);
|
||||
@@ -38,31 +38,6 @@ errorret_t scriptContextInit(scriptcontext_t *context) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void scriptContextRegFunc(
|
||||
scriptcontext_t *context,
|
||||
const char_t *fnName,
|
||||
lua_CFunction function
|
||||
) {
|
||||
assertNotNull(context, "Script context cannot be NULL");
|
||||
assertNotNull(fnName, "Function name cannot be NULL");
|
||||
assertNotNull(function, "Function cannot be NULL");
|
||||
|
||||
lua_register(context->luaState, fnName, function);
|
||||
}
|
||||
|
||||
void scriptContextRegPointer(
|
||||
scriptcontext_t *context,
|
||||
const char_t *name,
|
||||
void *pointer
|
||||
) {
|
||||
assertNotNull(context, "Script context cannot be NULL");
|
||||
assertNotNull(name, "Name cannot be NULL");
|
||||
assertNotNull(pointer, "Pointer cannot be NULL");
|
||||
|
||||
lua_pushlightuserdata(context->luaState, pointer);
|
||||
lua_setglobal(context->luaState, name);
|
||||
}
|
||||
|
||||
errorret_t scriptContextCallFunc(
|
||||
scriptcontext_t *context,
|
||||
const char_t *fnName,
|
||||
|
||||
@@ -29,32 +29,6 @@ typedef struct scriptcontext_s {
|
||||
*/
|
||||
errorret_t scriptContextInit(scriptcontext_t *context);
|
||||
|
||||
/**
|
||||
* Register a C function within a script context.
|
||||
*
|
||||
* @param context The script context to use.
|
||||
* @param fnName The name of the function in Lua.
|
||||
* @param function The C function to register.
|
||||
*/
|
||||
void scriptContextRegFunc(
|
||||
scriptcontext_t *context,
|
||||
const char_t *fnName,
|
||||
lua_CFunction function
|
||||
);
|
||||
|
||||
/**
|
||||
* Register a pointer within a script context.
|
||||
*
|
||||
* @param context The script context to use.
|
||||
* @param name The name of the pointer in Lua.
|
||||
* @param pointer The pointer to register.
|
||||
*/
|
||||
void scriptContextRegPointer(
|
||||
scriptcontext_t *context,
|
||||
const char_t *name,
|
||||
void *pointer
|
||||
);
|
||||
|
||||
/**
|
||||
* Call a Lua function within a script context.
|
||||
*
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "scriptstruct.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
void scriptStructRegister(
|
||||
scriptcontext_t *context,
|
||||
const char_t *metatableName,
|
||||
const scriptstructgetter_t getter,
|
||||
const scriptstructsetter_t setter
|
||||
) {
|
||||
assertNotNull(context, "Script context cannot be NULL");
|
||||
assertNotNull(metatableName, "Metatable name cannot be NULL");
|
||||
|
||||
// Create metatable
|
||||
if(!luaL_newmetatable(context->luaState, metatableName)) return;
|
||||
|
||||
// Create a Lua owned structure for holding the metatable context.
|
||||
structmetatablecontext_t *metaContext = lua_newuserdata(
|
||||
context->luaState,
|
||||
sizeof(structmetatablecontext_t)
|
||||
);
|
||||
|
||||
metaContext->context = context;
|
||||
metaContext->getter = getter;
|
||||
metaContext->setter = setter;
|
||||
|
||||
// Store in the metatable.
|
||||
lua_setfield(context->luaState, -2, "__structmetatablecontext");
|
||||
|
||||
// Set __index and __newindex metamethods for Lua.
|
||||
lua_pushcfunction(context->luaState, scriptStructIndex);
|
||||
lua_setfield(context->luaState, -2, "__index");
|
||||
|
||||
lua_pushcfunction(context->luaState, scriptStructNewIndex);
|
||||
lua_setfield(context->luaState, -2, "__newindex");
|
||||
}
|
||||
|
||||
int scriptStructIndex(lua_State *l) {
|
||||
structmetatablecontext_t *ctx = scriptStructGetMetatableContext(l);
|
||||
if(!ctx->getter) {
|
||||
luaL_error(l, "Attempt to read from write-only structure field");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char_t *key = lua_tostring(l, 2);
|
||||
|
||||
void *structPtr = *(void **)lua_touserdata(l, 1);
|
||||
assertNotNull(structPtr, "Structure pointer cannot be NULL");
|
||||
|
||||
scriptvalue_t outValue = { .type = SCRIPT_VALUE_TYPE_NIL };
|
||||
ctx->getter(ctx->context, key, structPtr, &outValue);
|
||||
|
||||
switch(outValue.type) {
|
||||
case SCRIPT_VALUE_TYPE_INT:
|
||||
lua_pushinteger(l, outValue.value.intValue);
|
||||
break;
|
||||
|
||||
case SCRIPT_VALUE_TYPE_FLOAT:
|
||||
lua_pushnumber(l, outValue.value.floatValue);
|
||||
break;
|
||||
|
||||
case SCRIPT_VALUE_TYPE_STRING:
|
||||
assertNotNull(outValue.value.strValue, "String value cannot be NULL");
|
||||
lua_pushstring(l, outValue.value.strValue);
|
||||
memoryFree((void *)outValue.value.strValue);
|
||||
break;
|
||||
|
||||
case SCRIPT_VALUE_TYPE_BOOL:
|
||||
lua_pushboolean(l, outValue.value.boolValue);
|
||||
break;
|
||||
|
||||
case SCRIPT_VALUE_TYPE_NIL:
|
||||
lua_pushnil(l);
|
||||
break;
|
||||
|
||||
case SCRIPT_VALUE_TYPE_USERDATA:
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported value type for struct field retrieval");
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int scriptStructNewIndex(lua_State *l) {
|
||||
structmetatablecontext_t *ctx = scriptStructGetMetatableContext(l);
|
||||
if(ctx->setter == NULL) {
|
||||
luaL_error(l, "Attempt to set read-only structure field");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char_t *key = lua_tostring(l, 2);
|
||||
|
||||
void *structPtr = *(void **)lua_touserdata(l, 1);
|
||||
assertNotNull(structPtr, "Structure pointer cannot be NULL");
|
||||
|
||||
scriptvalue_t inValue;
|
||||
int t = lua_type(l, 3);
|
||||
switch(t) {
|
||||
case LUA_TNUMBER:
|
||||
if(lua_isinteger(l, 3)) {
|
||||
inValue.type = SCRIPT_VALUE_TYPE_INT;
|
||||
inValue.value.intValue = (int32_t)lua_tointeger(l, 3);
|
||||
} else {
|
||||
inValue.type = SCRIPT_VALUE_TYPE_FLOAT;
|
||||
inValue.value.floatValue = (float)lua_tonumber(l, 3);
|
||||
}
|
||||
break;
|
||||
|
||||
case LUA_TSTRING:
|
||||
inValue.type = SCRIPT_VALUE_TYPE_STRING;
|
||||
inValue.value.strValue = lua_tostring(l, 3);
|
||||
break;
|
||||
|
||||
case LUA_TBOOLEAN:
|
||||
inValue.type = SCRIPT_VALUE_TYPE_BOOL;
|
||||
inValue.value.boolValue = lua_toboolean(l, 3);
|
||||
break;
|
||||
|
||||
case LUA_TNIL:
|
||||
inValue.type = SCRIPT_VALUE_TYPE_NIL;
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported value type for struct field assignment");
|
||||
break;
|
||||
}
|
||||
|
||||
ctx->setter(ctx->context, key, structPtr, &inValue);
|
||||
|
||||
lua_pushnil(l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
structmetatablecontext_t * scriptStructGetMetatableContext(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_getmetatable(L, 1)) {
|
||||
assertUnreachable("Expected metatable on structure");
|
||||
}
|
||||
|
||||
lua_getfield(L, -1, "__structmetatablecontext");
|
||||
structmetatablecontext_t *metaContext = (
|
||||
(structmetatablecontext_t *)lua_touserdata(L, -1)
|
||||
);
|
||||
assertNotNull(metaContext, "Metatable context userdata cannot be NULL");
|
||||
lua_pop(L, 2);
|
||||
return metaContext;
|
||||
}
|
||||
|
||||
void scriptStructPushMetatable(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *metatableName,
|
||||
void *structPtr
|
||||
) {
|
||||
assertNotNull(context, "Script context cannot be NULL");
|
||||
assertNotNull(metatableName, "Metatable name cannot be NULL");
|
||||
assertNotNull(structPtr, "Structure pointer cannot be NULL");
|
||||
|
||||
// Create userdata
|
||||
void **ud = (void **)lua_newuserdata(context->luaState, sizeof(void *));
|
||||
*ud = structPtr;
|
||||
|
||||
// Set metatable
|
||||
luaL_getmetatable(context->luaState, metatableName);
|
||||
lua_setmetatable(context->luaState, -2);
|
||||
}
|
||||
|
||||
void scriptStructPush(
|
||||
scriptcontext_t *context,
|
||||
const char_t *metatableName,
|
||||
const char_t *variableName,
|
||||
void *structPtr
|
||||
) {
|
||||
assertNotNull(context, "Script context cannot be NULL");
|
||||
assertNotNull(metatableName, "Metatable name cannot be NULL");
|
||||
assertNotNull(variableName, "Variable name cannot be NULL");
|
||||
assertNotNull(structPtr, "Structure pointer cannot be NULL");
|
||||
|
||||
scriptStructPushMetatable(context, metatableName, structPtr);
|
||||
lua_setglobal(context->luaState, variableName);
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "scriptstructgetter.h"
|
||||
#include "scriptstructsetter.h"
|
||||
|
||||
typedef struct {
|
||||
scriptcontext_t *context;
|
||||
scriptstructgetter_t getter;
|
||||
scriptstructsetter_t setter;
|
||||
} structmetatablecontext_t;
|
||||
|
||||
/**
|
||||
* Registers a script structure to allow a script to access its fields. You will
|
||||
* be creating a new metatable in Lua with the given name, so Ideally use a name
|
||||
* like Ideally struct_mt e.g. player_t or entity_t.
|
||||
*
|
||||
* @param context The script context.
|
||||
* @param metatableName The name of the metatable to register
|
||||
* @param getter The getter function for retrieving field values.
|
||||
* @param setter The setter function for setting field values.
|
||||
*/
|
||||
void scriptStructRegister(
|
||||
scriptcontext_t *context,
|
||||
const char_t *metatableName,
|
||||
const scriptstructgetter_t getter,
|
||||
const scriptstructsetter_t setter
|
||||
);
|
||||
|
||||
/**
|
||||
* Callback received from Lua to index (get) a structure field.
|
||||
*
|
||||
* @param l The Lua state.
|
||||
* @return The number of return values.
|
||||
*/
|
||||
int scriptStructIndex(lua_State *l);
|
||||
|
||||
/**
|
||||
* Callback received from Lua to newindex (set) a structure field.
|
||||
*
|
||||
* @param l The Lua state.
|
||||
* @return The number of return values.
|
||||
*/
|
||||
int scriptStructNewIndex(lua_State *l);
|
||||
|
||||
/**
|
||||
* Pops the metatable context from the given Lua state. This is only valid from
|
||||
* within the index or newindex methods.
|
||||
*
|
||||
* @param l The Lua state.
|
||||
* @return The metatable context.
|
||||
*/
|
||||
structmetatablecontext_t *scriptStructGetMetatableContext(lua_State *l);
|
||||
|
||||
/**
|
||||
* Pushes a structure metatable onto the Lua stack.
|
||||
*
|
||||
* @param context The script context.
|
||||
* @param metatableName The name of the metatable to associate with.
|
||||
* @param structPtr Pointer to the structure to push.
|
||||
*/
|
||||
void scriptStructPushMetatable(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *metatableName,
|
||||
void *structPtr
|
||||
);
|
||||
|
||||
/**
|
||||
* Pushes a structure onto the Lua stack and assigns it to a global variable.
|
||||
*
|
||||
* @param context The script context.
|
||||
* @param metatableName The name of the metatable to associate with.
|
||||
* @param variableName The name of the global variable to assign to.
|
||||
* @param structPtr Pointer to the structure to push.
|
||||
*/
|
||||
void scriptStructPush(
|
||||
scriptcontext_t *context,
|
||||
const char_t *metatableName,
|
||||
const char_t *variableName,
|
||||
void *structPtr
|
||||
);
|
||||
@@ -1,16 +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"
|
||||
|
||||
typedef void (*scriptstructgetter_t)(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
const void *structPtr,
|
||||
scriptvalue_t *outValue
|
||||
);
|
||||
@@ -1,16 +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"
|
||||
|
||||
typedef void (*scriptstructsetter_t)(
|
||||
const scriptcontext_t *context,
|
||||
const char_t *key,
|
||||
void *structPtr,
|
||||
const scriptvalue_t *inValue
|
||||
);
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2025 Dominic Masters
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
@@ -7,11 +7,5 @@
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
ui.c
|
||||
uitext.c
|
||||
uidebug.c
|
||||
uiframe.c
|
||||
uitextbox.c
|
||||
uielement.c
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(element)
|
||||
+35
-34
@@ -1,67 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "ui.h"
|
||||
#include "assert/assert.h"
|
||||
#include "ui/uidebug.h"
|
||||
#include "util/memory.h"
|
||||
#include "display/tileset/tileset_minogram.h"
|
||||
#include "display/screen.h"
|
||||
// #include "ui/uitextbox.h"
|
||||
#include "assert/assert.h"
|
||||
#include "display/spritebatch.h"
|
||||
|
||||
ui_t UI;
|
||||
|
||||
errorret_t uiInit(void) {
|
||||
memoryZero(&UI, sizeof(ui_t));
|
||||
|
||||
cameraInitOrthographic(&UI.camera);
|
||||
|
||||
// Initialize UI components here
|
||||
uiSetFont(&TILESET_MINOGRAM);
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void uiUpdate(void) {
|
||||
// Update UI state here
|
||||
UI.camera.orthographic.left = 0;
|
||||
UI.camera.orthographic.right = SCREEN.width;
|
||||
UI.camera.orthographic.top = 0;
|
||||
UI.camera.orthographic.bottom = SCREEN.height;
|
||||
|
||||
// uiTextboxUpdate();
|
||||
uint_fast8_t i = 0;
|
||||
while(i < UI.stackSize) {
|
||||
errorCatch(errorPrint(uiElementUpdate(&UI.stack[i])));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void uiRender(void) {
|
||||
cameraPushMatrix(&UI.camera);
|
||||
spriteBatchClear();
|
||||
|
||||
// Render UI elements here
|
||||
if(UI.fontTexture.width > 0) {
|
||||
uiDebugRender(UI.fontTileset, &UI.fontTexture);
|
||||
uint_fast8_t i = 0;
|
||||
while(i < UI.stackSize) {
|
||||
errorCatch(errorPrint(uiElementRender(&UI.stack[i])));
|
||||
i++;
|
||||
}
|
||||
|
||||
// spriteBatchPush(
|
||||
// NULL,
|
||||
// 0, 0, 32, 32, COLOR_RED, 0, 0, 1, 1
|
||||
// );
|
||||
|
||||
spriteBatchFlush();
|
||||
cameraPopMatrix();
|
||||
}
|
||||
|
||||
errorret_t uiSetFont(const tileset_t *fontTileset) {
|
||||
if(UI.fontTexture.width > 0) {
|
||||
textureDispose(&UI.fontTexture);
|
||||
UI.fontTexture.width = -1;
|
||||
}
|
||||
|
||||
assertNotNull(fontTileset, "Font tileset cannot be NULL.");
|
||||
|
||||
UI.fontTileset = fontTileset;
|
||||
errorChain(assetLoad(UI.fontTileset->image, &UI.fontTexture));
|
||||
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) {
|
||||
if(UI.fontTexture.width > 0) {
|
||||
textureDispose(&UI.fontTexture);
|
||||
UI.fontTexture.width = -1;
|
||||
while(UI.stackSize > 0) {
|
||||
uiPop();
|
||||
}
|
||||
}
|
||||
+19
-17
@@ -1,51 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
* 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/camera/camera.h"
|
||||
#include "ui/uielement.h"
|
||||
|
||||
#define UI_STACK_SIZE 64
|
||||
|
||||
typedef struct {
|
||||
camera_t camera;
|
||||
texture_t fontTexture;
|
||||
const tileset_t *fontTileset;
|
||||
|
||||
uielement_t stack[UI_STACK_SIZE];
|
||||
uint_fast8_t stackSize;
|
||||
} ui_t;
|
||||
|
||||
extern ui_t UI;
|
||||
|
||||
/**
|
||||
* Initializes the UI system, loading necessary resources.
|
||||
*
|
||||
* @return An errorret_t indicating success or failure.
|
||||
* Initializes the UI system.
|
||||
*/
|
||||
errorret_t uiInit(void);
|
||||
|
||||
/**
|
||||
* Updates the UI state, handling user interactions and animations.
|
||||
* Updates the UI system.
|
||||
*/
|
||||
void uiUpdate(void);
|
||||
|
||||
/**
|
||||
* Renders the UI elements to the screen.
|
||||
* Renders the UI system.
|
||||
*/
|
||||
void uiRender(void);
|
||||
|
||||
/**
|
||||
* Sets the font tileset for UI text rendering.
|
||||
* Pushes a new UI element onto the UI stack from a script file.
|
||||
*
|
||||
* @param fontTileset Pointer to the tileset to use for UI fonts.
|
||||
*
|
||||
* @return An errorret_t indicating success or failure.
|
||||
* @param path Path to the UI script file.
|
||||
*/
|
||||
errorret_t uiSetFont(const tileset_t *fontTileset);
|
||||
errorret_t uiPushScript(const char_t *path);
|
||||
|
||||
/**
|
||||
* Cleans up and frees all UI resources.
|
||||
* Pops the top UI element from the UI stack.
|
||||
*/
|
||||
void uiPop(void);
|
||||
|
||||
/**
|
||||
* Disposes of the UI system.
|
||||
*/
|
||||
void uiDispose(void);
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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"
|
||||
|
||||
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) {
|
||||
if(!scriptContextHasFunc(&element->ctx, "update")) errorOk();
|
||||
|
||||
errorChain(scriptContextCallFunc(
|
||||
&element->ctx,
|
||||
"update",
|
||||
NULL,
|
||||
0,
|
||||
NULL
|
||||
));
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t uiElementRender(uielement_t *element) {
|
||||
if(!scriptContextHasFunc(&element->ctx, "render")) errorOk();
|
||||
|
||||
// scriptvalue_t args[4] = {
|
||||
// { .type = SCRIPT_VALUE_TYPE_FLOAT, .value.floatValue = 0.0f },
|
||||
// { .type = SCRIPT_VALUE_TYPE_FLOAT, .value.floatValue = 0.0f },
|
||||
// { .type = SCRIPT_VALUE_TYPE_FLOAT, .value.floatValue = SCREEN.width },
|
||||
// { .type = SCRIPT_VALUE_TYPE_FLOAT, .value.floatValue = SCREEN.height },
|
||||
// };
|
||||
|
||||
// errorChain(scriptContextCallFunc(
|
||||
// &element->ctx,
|
||||
// "render",
|
||||
// args,
|
||||
// 4,
|
||||
// NULL
|
||||
// ));
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void uiElementDispose(uielement_t *element) {
|
||||
scriptContextDispose(&element->ctx);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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);
|
||||
Reference in new issue
Block a user