From b16dbaceec2cb80f66cddaba08dfe2815c2fbc98 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Thu, 25 Dec 2025 08:02:11 +1000 Subject: [PATCH] Modules --- assets/script/CMakeLists.txt | 4 +- assets/script/init.lua | 43 ++++++++++-- assets/script/scene/CMakeLists.txt | 4 -- src/CMakeLists.txt | 4 ++ src/engine/engine.c | 7 +- src/engine/engine.h | 2 - src/input/input.c | 68 +++++++++---------- src/input/inputaction.c | 17 ++--- src/input/inputaction.h | 20 +++--- src/rpg/item/inventory.h | 13 ++++ src/scene/scenemanager.c | 23 +++---- src/scene/scenemanager.h | 3 +- src/script/CMakeLists.txt | 1 + src/script/func/scriptfunccamera.h | 14 ---- src/script/func/scriptfuncscene.h | 39 ----------- src/script/module/moduleinput.h | 65 ++++++++++++++++++ src/script/module/moduleplatform.h | 21 ++++++ src/script/module/modulescene.h | 42 ++++++++++++ .../modulesystem.h} | 60 +++++++++++++--- .../{func => module}/scriptfuncentity.h | 0 src/script/scriptcontext.c | 22 +++--- src/script/scriptmodule.c | 32 +++++++++ src/script/scriptmodule.h | 24 +++++++ 23 files changed, 370 insertions(+), 158 deletions(-) delete mode 100644 assets/script/scene/CMakeLists.txt create mode 100644 src/rpg/item/inventory.h delete mode 100644 src/script/func/scriptfunccamera.h delete mode 100644 src/script/func/scriptfuncscene.h create mode 100644 src/script/module/moduleinput.h create mode 100644 src/script/module/moduleplatform.h create mode 100644 src/script/module/modulescene.h rename src/script/{func/scriptfuncsystem.h => module/modulesystem.h} (55%) rename src/script/{func => module}/scriptfuncentity.h (100%) create mode 100644 src/script/scriptmodule.c create mode 100644 src/script/scriptmodule.h diff --git a/assets/script/CMakeLists.txt b/assets/script/CMakeLists.txt index bfdf852..6042a69 100644 --- a/assets/script/CMakeLists.txt +++ b/assets/script/CMakeLists.txt @@ -3,6 +3,4 @@ # This software is released under the MIT License. # https://opensource.org/licenses/MIT -add_asset(SCRIPT test.lua) - -add_subdirectory(scene) \ No newline at end of file +add_asset(SCRIPT init.lua) \ No newline at end of file diff --git a/assets/script/init.lua b/assets/script/init.lua index 85f42b3..537b165 100644 --- a/assets/script/init.lua +++ b/assets/script/init.lua @@ -1,5 +1,40 @@ -print('Init') +module('platform') +module('input') +module('scene') --- Load map scene -setScene('map') -setMap() \ No newline at end of file +-- Default Input bindings. +if PLATFORM == "psp" then + inputBind("up", "up") + inputBind("down", "down") + inputBind("left", "left") + inputBind("right", "right") + inputBind("circle", "cancel") + inputBind("cross", "accept") + inputBind("select", "ragequit") + inputBind("lstick_up", "up") + inputBind("lstick_down", "down") + inputBind("lstick_left", "left") + inputBind("lstick_right", "right") +else + if INPUT_KEYBOARD then + inputBind("w", "up") + inputBind("s", "down") + inputBind("a", "left") + inputBind("d", "right") + + inputBind("left", "left") + inputBind("right", "right") + inputBind("up", "up") + inputBind("down", "down") + + inputBind("enter", "accept") + inputBind("e", "accept" ) + + inputBind("escape", "cancel") + inputBind("q", "cancel") + + inputBind("z", "ragequit") + end +end + +sceneSet('map') \ No newline at end of file diff --git a/assets/script/scene/CMakeLists.txt b/assets/script/scene/CMakeLists.txt deleted file mode 100644 index e681ce4..0000000 --- a/assets/script/scene/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright (c) 2025 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47de100..07a48d5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,6 +41,10 @@ target_sources(${DUSK_TARGET_NAME} # Defs add_defs(duskdefs.env duskdefs.h) +target_compile_definitions(${DUSK_TARGET_NAME} + PRIVATE + DUSK_TARGET_SYSTEM="${DUSK_TARGET_SYSTEM}" +) # Subdirs add_subdirectory(assert) diff --git a/src/engine/engine.c b/src/engine/engine.c index aaba748..46e4659 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -39,9 +39,10 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { errorChain(sceneManagerInit()); // Run the initial script. - errorChain(scriptContextInit(&ENGINE.mainScriptContext)); - errorChain(scriptContextExecFile(&ENGINE.mainScriptContext, "script/test.dsf")); - scriptContextDispose(&ENGINE.mainScriptContext); + scriptcontext_t ctx; + errorChain(scriptContextInit(&ctx)); + errorChain(scriptContextExecFile(&ctx, "script/init.dsf")); + scriptContextDispose(&ctx); errorOk(); } diff --git a/src/engine/engine.h b/src/engine/engine.h index 4acf63e..b75d350 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -8,13 +8,11 @@ #pragma once #include "display/display.h"// Important to be included first. #include "error/error.h" -#include "script/scriptcontext.h" typedef struct { bool_t running; int32_t argc; const char_t **argv; - scriptcontext_t mainScriptContext; } engine_t; extern engine_t ENGINE; diff --git a/src/input/input.c b/src/input/input.c index 73c4ff4..bd34425 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -26,42 +26,42 @@ void inputInit(void) { INPUT.deadzone = 0.2f; // Setup Default Binds - #if INPUT_SDL2 == 1 - #if INPUT_KEYBOARD == 1 - inputBind(inputButtonGetByName("up"), INPUT_ACTION_UP); - inputBind(inputButtonGetByName("down"), INPUT_ACTION_DOWN); - inputBind(inputButtonGetByName("left"), INPUT_ACTION_LEFT); - inputBind(inputButtonGetByName("right"), INPUT_ACTION_RIGHT); - inputBind(inputButtonGetByName("w"), INPUT_ACTION_UP); - inputBind(inputButtonGetByName("s"), INPUT_ACTION_DOWN); - inputBind(inputButtonGetByName("a"), INPUT_ACTION_LEFT); - inputBind(inputButtonGetByName("d"), INPUT_ACTION_RIGHT); - inputBind(inputButtonGetByName("enter"), INPUT_ACTION_ACCEPT); - inputBind(inputButtonGetByName("escape"), INPUT_ACTION_RAGEQUIT); - inputBind(inputButtonGetByName("space"), INPUT_ACTION_ACCEPT); - inputBind(inputButtonGetByName("backspace"), INPUT_ACTION_CANCEL); - inputBind(inputButtonGetByName("e"), INPUT_ACTION_ACCEPT); - inputBind(inputButtonGetByName("q"), INPUT_ACTION_CANCEL); - #endif + // #if INPUT_SDL2 == 1 + // #if INPUT_KEYBOARD == 1 + // inputBind(inputButtonGetByName("up"), INPUT_ACTION_UP); + // inputBind(inputButtonGetByName("down"), INPUT_ACTION_DOWN); + // inputBind(inputButtonGetByName("left"), INPUT_ACTION_LEFT); + // inputBind(inputButtonGetByName("right"), INPUT_ACTION_RIGHT); + // inputBind(inputButtonGetByName("w"), INPUT_ACTION_UP); + // inputBind(inputButtonGetByName("s"), INPUT_ACTION_DOWN); + // inputBind(inputButtonGetByName("a"), INPUT_ACTION_LEFT); + // inputBind(inputButtonGetByName("d"), INPUT_ACTION_RIGHT); + // inputBind(inputButtonGetByName("enter"), INPUT_ACTION_ACCEPT); + // inputBind(inputButtonGetByName("escape"), INPUT_ACTION_RAGEQUIT); + // inputBind(inputButtonGetByName("space"), INPUT_ACTION_ACCEPT); + // inputBind(inputButtonGetByName("backspace"), INPUT_ACTION_CANCEL); + // inputBind(inputButtonGetByName("e"), INPUT_ACTION_ACCEPT); + // inputBind(inputButtonGetByName("q"), INPUT_ACTION_CANCEL); + // #endif - #if INPUT_GAMEPAD == 1 - #if PSP - INPUT.deadzone = 0.2890625f;// Taken from the PSP firmware + // #if INPUT_GAMEPAD == 1 + // #if PSP + // INPUT.deadzone = 0.2890625f;// Taken from the PSP firmware - inputBind(inputButtonGetByName("up"), INPUT_ACTION_UP); - inputBind(inputButtonGetByName("down"), INPUT_ACTION_DOWN); - inputBind(inputButtonGetByName("left"), INPUT_ACTION_LEFT); - inputBind(inputButtonGetByName("right"), INPUT_ACTION_RIGHT); - inputBind(inputButtonGetByName("circle"), INPUT_ACTION_CANCEL); - inputBind(inputButtonGetByName("cross"), INPUT_ACTION_ACCEPT); - inputBind(inputButtonGetByName("lstick_negative_y"), INPUT_ACTION_UP); - inputBind(inputButtonGetByName("lstick_positive_y"), INPUT_ACTION_DOWN); - inputBind(inputButtonGetByName("lstick_negative_x"), INPUT_ACTION_LEFT); - inputBind(inputButtonGetByName("lstick_positive_x"), INPUT_ACTION_RIGHT); - inputBind(inputButtonGetByName("select"), INPUT_ACTION_RAGEQUIT); - #endif - #endif - #endif + // inputBind(inputButtonGetByName("up"), INPUT_ACTION_UP); + // inputBind(inputButtonGetByName("down"), INPUT_ACTION_DOWN); + // inputBind(inputButtonGetByName("left"), INPUT_ACTION_LEFT); + // inputBind(inputButtonGetByName("right"), INPUT_ACTION_RIGHT); + // inputBind(inputButtonGetByName("circle"), INPUT_ACTION_CANCEL); + // inputBind(inputButtonGetByName("cross"), INPUT_ACTION_ACCEPT); + // inputBind(inputButtonGetByName("lstick_negative_y"), INPUT_ACTION_UP); + // inputBind(inputButtonGetByName("lstick_positive_y"), INPUT_ACTION_DOWN); + // inputBind(inputButtonGetByName("lstick_negative_x"), INPUT_ACTION_LEFT); + // inputBind(inputButtonGetByName("lstick_positive_x"), INPUT_ACTION_RIGHT); + // inputBind(inputButtonGetByName("select"), INPUT_ACTION_RAGEQUIT); + // #endif + // #endif + // #endif } void inputUpdate(void) { diff --git a/src/input/inputaction.c b/src/input/inputaction.c index db84312..fc71cc2 100644 --- a/src/input/inputaction.c +++ b/src/input/inputaction.c @@ -9,13 +9,14 @@ #include "assert/assert.h" #include "util/string.h" -// inputaction_t inputActionGetByName(const char_t *name) { -// assertNotNull(name, "name must not be NULL"); +inputaction_t inputActionGetByName(const char_t *name) { + assertNotNull(name, "name must not be NULL"); -// for(inputaction_t i = 0; i < INPUT_ACTION_COUNT; i++) { -// if(stringCompareInsensitive(INPUT_ACTION_NAMES[i], name) != 0) continue; -// return i; -// } + for(inputaction_t i = 0; i < INPUT_ACTION_COUNT; i++) { + if(INPUT_ACTION_NAMES[i] == NULL) continue; + if(stringCompareInsensitive(INPUT_ACTION_NAMES[i], name) != 0) continue; + return i; + } -// return INPUT_ACTION_COUNT; -// } \ No newline at end of file + return INPUT_ACTION_COUNT; +} \ No newline at end of file diff --git a/src/input/inputaction.h b/src/input/inputaction.h index 6937bb4..55f61fe 100644 --- a/src/input/inputaction.h +++ b/src/input/inputaction.h @@ -32,15 +32,15 @@ typedef struct { #endif } inputactiondata_t; -// static const char_t* INPUT_ACTION_NAMES[INPUT_ACTION_COUNT] = { -// [INPUT_ACTION_UP] = "UP", -// [INPUT_ACTION_DOWN] = "DOWN", -// [INPUT_ACTION_LEFT] = "LEFT", -// [INPUT_ACTION_RIGHT] = "RIGHT", -// [INPUT_ACTION_ACCEPT] = "ACCEPT", -// [INPUT_ACTION_CANCEL] = "CANCEL", -// [INPUT_ACTION_RAGEQUIT] = "RAGEQUIT", -// }; +static const char_t* INPUT_ACTION_NAMES[INPUT_ACTION_COUNT] = { + [INPUT_ACTION_UP] = "UP", + [INPUT_ACTION_DOWN] = "DOWN", + [INPUT_ACTION_LEFT] = "LEFT", + [INPUT_ACTION_RIGHT] = "RIGHT", + [INPUT_ACTION_ACCEPT] = "ACCEPT", + [INPUT_ACTION_CANCEL] = "CANCEL", + [INPUT_ACTION_RAGEQUIT] = "RAGEQUIT", +}; /** * Gets an input action by its name. @@ -48,4 +48,4 @@ typedef struct { * @param name The name of the input action. * @return The input action, or INPUT_ACTION_COUNT if not found. */ -// inputaction_t inputActionGetByName(const char_t *name); \ No newline at end of file +inputaction_t inputActionGetByName(const char_t *name); \ No newline at end of file diff --git a/src/rpg/item/inventory.h b/src/rpg/item/inventory.h new file mode 100644 index 0000000..8cdff10 --- /dev/null +++ b/src/rpg/item/inventory.h @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" + +typedef struct { + void *nothing; +} inventory_t; \ No newline at end of file diff --git a/src/scene/scenemanager.c b/src/scene/scenemanager.c index 584860c..bc011c0 100644 --- a/src/scene/scenemanager.c +++ b/src/scene/scenemanager.c @@ -47,14 +47,11 @@ void sceneManagerRegisterScene(scene_t *scene) { SCENE_MANAGER.scenes[SCENE_MANAGER.sceneCount++] = scene; } -void sceneManagerSetScene(scene_t *scene) { - if(SCENE_MANAGER.current) { - // TODO: Should dispose? - assertTrue( - SCENE_MANAGER.current->flags & SCENE_FLAG_INITIALIZED, - "Current scene not initialized" - ); - +errorret_t sceneManagerSetScene(scene_t *scene) { + if( + SCENE_MANAGER.current && + (SCENE_MANAGER.current->flags & SCENE_FLAG_INITIALIZED) != 0 + ) { SCENE_MANAGER.current->flags &= ~SCENE_FLAG_INITIALIZED; if(SCENE_MANAGER.current->dispose) { SCENE_MANAGER.current->dispose(&SCENE_MANAGER.sceneData); @@ -63,12 +60,12 @@ void sceneManagerSetScene(scene_t *scene) { SCENE_MANAGER.current = scene; - if(scene) { - assertTrue( - (scene->flags & SCENE_FLAG_INITIALIZED) == 0, - "Scene should not yet be initialized" - ); + if(scene && scene->init) { + scene->flags |= SCENE_FLAG_INITIALIZED; + errorChain(scene->init(&SCENE_MANAGER.sceneData)); } + + errorOk(); } void sceneManagerUpdate(void) { diff --git a/src/scene/scenemanager.h b/src/scene/scenemanager.h index 1edf04f..9919144 100644 --- a/src/scene/scenemanager.h +++ b/src/scene/scenemanager.h @@ -44,8 +44,9 @@ void sceneManagerRegisterScene(scene_t *scene); * Sets the current active scene. * * @param scene The scene to set as current. + * @return An error code indicating success or failure. */ -void sceneManagerSetScene(scene_t *scene); +errorret_t sceneManagerSetScene(scene_t *scene); /** * Updates all active scenes. diff --git a/src/script/CMakeLists.txt b/src/script/CMakeLists.txt index 1e60d85..39d737b 100644 --- a/src/script/CMakeLists.txt +++ b/src/script/CMakeLists.txt @@ -8,4 +8,5 @@ target_sources(${DUSK_TARGET_NAME} PRIVATE scriptmanager.c scriptcontext.c + scriptmodule.c ) \ No newline at end of file diff --git a/src/script/func/scriptfunccamera.h b/src/script/func/scriptfunccamera.h deleted file mode 100644 index 021d01b..0000000 --- a/src/script/func/scriptfunccamera.h +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "script/scriptcontext.h" -#include "assert/assert.h" - -void scriptFuncCamera(scriptcontext_t *context) { - assertNotNull(context, "Script context cannot be NULL"); -} \ No newline at end of file diff --git a/src/script/func/scriptfuncscene.h b/src/script/func/scriptfuncscene.h deleted file mode 100644 index 185e50c..0000000 --- a/src/script/func/scriptfuncscene.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "script/scriptcontext.h" -#include "scene/scenemanager.h" -#include "debug/debug.h" -#include "assert/assert.h" -#include "error/error.h" - -int32_t scriptFuncSetScene(lua_State *L) { - assertNotNull(L, "Lua state cannot be NULL"); - assertTrue(lua_isstring(L, 1), "First argument must be a string"); - - const char_t *sceneName = lua_tostring(L, 1); - scene_t *scene = sceneManagerGetSceneByName(sceneName); - assertNotNull(scene, "Scene with given name does not exist"); - - sceneManagerSetScene(scene); - - if(scene->init) { - errorret_t err = scene->init(&SCENE_MANAGER.sceneData); - assertTrue(err.code == ERROR_OK, "Scene initialization failed"); - } - scene->flags |= SCENE_FLAG_INITIALIZED; - - return 0; -} - - -void scriptFuncScene(scriptcontext_t *context) { - assertNotNull(context, "Script context cannot be NULL"); - - scriptContextRegFunc(context, "setScene", scriptFuncSetScene); -} \ No newline at end of file diff --git a/src/script/module/moduleinput.h b/src/script/module/moduleinput.h new file mode 100644 index 0000000..b53aba5 --- /dev/null +++ b/src/script/module/moduleinput.h @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "script/scriptcontext.h" +#include "input/input.h" + +int32_t moduleInputBind(lua_State *L) { + assertNotNull(L, "Lua state cannot be NULL"); + + // Requires action and button. + if(!lua_isstring(L, 1)) { + luaL_error(L, "inputBind: Expected button name as first argument"); + return 0; + } + + if(!lua_isstring(L, 2)) { + luaL_error(L, "inputBind: Expected action name as second argument"); + return 0; + } + + const char_t *strBtn = lua_tostring(L, 1); + const char_t *strAct = lua_tostring(L, 2); + + // Get button by name + inputbutton_t btn = inputButtonGetByName(strBtn); + if(btn.type == INPUT_BUTTON_TYPE_NONE) { + printf("inputBind: Unknown button name '%s'\n", strBtn); + return 0; + } + + // Get action by name + inputaction_t act = inputActionGetByName(strAct); + if(act == INPUT_ACTION_COUNT) { + printf("inputBind: Unknown action name '%s'\n", strAct); + return 0; + } + + inputBind(btn, act); + return 0; +} + +void moduleInput(scriptcontext_t *context) { + assertNotNull(context, "Script context cannot be NULL"); + + // Input values. + scriptContextExec(context, + #if INPUT_KEYBOARD == 1 + "INPUT_KEYBOARD = true\n" + #endif + #if INPUT_GAMEPAD == 1 + "INPUT_GAMEPAD = true\n" + #endif + #if INPUT_SDL2 == 1 + "INPUT_SDL2 = true\n" + #endif + ); + + // Bind methods + scriptContextRegFunc(context, "inputBind", moduleInputBind); +} \ No newline at end of file diff --git a/src/script/module/moduleplatform.h b/src/script/module/moduleplatform.h new file mode 100644 index 0000000..f50cf04 --- /dev/null +++ b/src/script/module/moduleplatform.h @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "script/scriptcontext.h" + +#ifndef DUSK_TARGET_SYSTEM + #error "DUSK_TARGET_SYSTEM must be defined" +#endif + +#define PLATFORM_VALUE "PLATFORM = '" DUSK_TARGET_SYSTEM "'" + +void modulePlatform(scriptcontext_t *ctx) { + assertNotNull(ctx, "Script context cannot be NULL"); + + scriptContextExec(ctx, PLATFORM_VALUE); +} \ No newline at end of file diff --git a/src/script/module/modulescene.h b/src/script/module/modulescene.h new file mode 100644 index 0000000..aabc2d5 --- /dev/null +++ b/src/script/module/modulescene.h @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "script/scriptcontext.h" +#include "scene/scenemanager.h" + +int32_t moduleSceneSetScene(lua_State *L) { + assertNotNull(L, "Lua state cannot be NULL"); + + assertTrue(lua_isstring(L, 1), "Expected string scene name"); + + const char *sceneName = luaL_checkstring(L, 1); + if(sceneName == NULL || sceneName[0] == '\0') { + luaL_error(L, "Scene name cannot be NULL"); + return 0; + } + + scene_t *scene = sceneManagerGetSceneByName(sceneName); + if(scene == NULL) { + luaL_error(L, "Scene '%s' not found", sceneName); + return 0; + } + + errorret_t err = sceneManagerSetScene(scene); + if(err.code != ERROR_OK) { + + luaL_error(L, "Failed to set scene '%s'", sceneName); + return 0; + } + return 0; +} + +void moduleScene(scriptcontext_t *ctx) { + assertNotNull(ctx, "Script context cannot be NULL"); + + scriptContextRegFunc(ctx, "sceneSet", moduleSceneSetScene); +} \ No newline at end of file diff --git a/src/script/func/scriptfuncsystem.h b/src/script/module/modulesystem.h similarity index 55% rename from src/script/func/scriptfuncsystem.h rename to src/script/module/modulesystem.h index 59fe7d8..1de2f0a 100644 --- a/src/script/func/scriptfuncsystem.h +++ b/src/script/module/modulesystem.h @@ -10,8 +10,9 @@ #include "debug/debug.h" #include "assert/assert.h" #include "util/string.h" +#include "script/scriptmodule.h" -int32_t scriptFuncPrint(lua_State *L) { +int32_t moduleSysPrint(lua_State *L) { assertNotNull(L, "Lua state cannot be NULL"); int n = lua_gettop(L); @@ -32,16 +33,25 @@ int32_t scriptFuncPrint(lua_State *L) { return 0; // no values returned to Lua } -int32_t scriptFuncInclude(lua_State *L) { +int32_t moduleSysInclude(lua_State *L) { assertNotNull(L, "Lua state cannot be NULL"); - assertTrue(lua_isstring(L, 1), "Expected string filename"); + + if(!lua_isstring(L, 1)) { + luaL_error(L, "Expected string filename"); + return 0; + } scriptcontext_t* ctx = *(scriptcontext_t**)lua_getextraspace(L); - assertNotNull(ctx, "Script context cannot be NULL"); + if(ctx == NULL) { + luaL_error(L, "Script context is NULL"); + return 0; + } const char_t *filename = luaL_checkstring(L, 1); - assertNotNull(filename, "Filename cannot be NULL"); - assertStrLenMin(filename, 1, "Filename cannot be empty"); + if(filename == NULL || filename[0] == '\0') { + luaL_error(L, "Filename cannot be NULL"); + return 0; + } // Copy out filename to mutable buffer char_t buffer[1024]; @@ -72,9 +82,41 @@ int32_t scriptFuncInclude(lua_State *L) { return 0; } -void scriptFuncSystem(scriptcontext_t *context) { +int32_t moduleSysModule(lua_State *L) { + assertNotNull(L, "Lua state cannot be NULL"); + + if(!lua_isstring(L, 1)) { + luaL_error(L, "Expected string module name"); + return 0; + } + + const char_t *moduleName = luaL_checkstring(L, 1); + if(moduleName == NULL) { + luaL_error(L, "Module name cannot be NULL"); + return 0; + } + + const scriptmodule_t *module = scriptModuleGetByName(moduleName); + if(module == NULL) { + luaL_error(L, "Module '%s' not found", moduleName); + return 0; + } + + scriptcontext_t* ctx = *(scriptcontext_t**)lua_getextraspace(L); + if(ctx == NULL) { + luaL_error(L, "Script context is NULL"); + return 0; + } + + module->callback(ctx); + + return 0; +} + +void moduleSystem(scriptcontext_t *context) { assertNotNull(context, "Script context cannot be NULL"); - scriptContextRegFunc(context, "print", scriptFuncPrint); - scriptContextRegFunc(context, "include", scriptFuncInclude); + scriptContextRegFunc(context, "print", moduleSysPrint); + scriptContextRegFunc(context, "include", moduleSysInclude); + scriptContextRegFunc(context, "module", moduleSysModule); } \ No newline at end of file diff --git a/src/script/func/scriptfuncentity.h b/src/script/module/scriptfuncentity.h similarity index 100% rename from src/script/func/scriptfuncentity.h rename to src/script/module/scriptfuncentity.h diff --git a/src/script/scriptcontext.c b/src/script/scriptcontext.c index 3d160d3..85346d1 100644 --- a/src/script/scriptcontext.c +++ b/src/script/scriptcontext.c @@ -10,11 +10,7 @@ #include "asset/asset.h" #include "util/memory.h" #include "debug/debug.h" - -#include "script/func/scriptfunccamera.h" -#include "script/func/scriptfuncentity.h" -#include "script/func/scriptfuncsystem.h" -#include "script/func/scriptfuncscene.h" +#include "script/scriptmodule.h" errorret_t scriptContextInit(scriptcontext_t *context) { assertNotNull(context, "Script context cannot be NULL"); @@ -30,15 +26,13 @@ errorret_t scriptContextInit(scriptcontext_t *context) { // Store context in Lua extraspace *(scriptcontext_t**)lua_getextraspace(context->luaState) = context; - - // Register variables - // scriptContextExec(context, "PLATFORM = 'DESKTOP'"); - - // Register functions - scriptFuncSystem(context); - scriptFuncEntity(context); - scriptFuncCamera(context); - scriptFuncScene(context); + + // All scripts get the system module + const scriptmodule_t *sysModule = scriptModuleGetByName("system"); + if(sysModule == NULL) { + errorThrow("Failed to find system script module"); + } + sysModule->callback(context); errorOk(); } diff --git a/src/script/scriptmodule.c b/src/script/scriptmodule.c new file mode 100644 index 0000000..3ff670f --- /dev/null +++ b/src/script/scriptmodule.c @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "scriptmodule.h" +#include "script/module/modulesystem.h" +#include "script/module/moduleinput.h" +#include "script/module/moduleplatform.h" +#include "script/module/modulescene.h" + +const scriptmodule_t SCRIPT_MODULE_LIST[] = { + { .name = "system", .callback = moduleSystem }, + { .name = "input", .callback = moduleInput }, + { .name = "platform", .callback = modulePlatform }, + { .name = "scene", .callback = moduleScene }, +}; + +#define SCRIPT_MODULE_COUNT ( \ + sizeof(SCRIPT_MODULE_LIST) / sizeof(scriptmodule_t) \ +) + +const scriptmodule_t * scriptModuleGetByName(const char_t *name) { + for(uint_fast8_t i = 0; i < SCRIPT_MODULE_COUNT; i++) { + if(stringCompare(SCRIPT_MODULE_LIST[i].name, name) != 0) continue; + return &SCRIPT_MODULE_LIST[i]; + } + + return NULL; +} \ No newline at end of file diff --git a/src/script/scriptmodule.h b/src/script/scriptmodule.h new file mode 100644 index 0000000..da9cf8e --- /dev/null +++ b/src/script/scriptmodule.h @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "scriptcontext.h" + +typedef struct scriptmodule_s { + const char_t *name; + void (*callback)(scriptcontext_t *ctx); +} scriptmodule_t; + +extern const scriptmodule_t SCRIPT_MODULE_LIST[]; + +/** + * Retrieves a script module by its name. + * + * @param name The name of the script module. + * @return Pointer to the script module, or NULL if not found. + */ +const scriptmodule_t * scriptModuleGetByName(const char_t *name); \ No newline at end of file