Modules
Some checks failed
Build Dusk / build-linux (push) Successful in 1m13s
Build Dusk / build-psp (push) Failing after 1m27s

This commit is contained in:
2025-12-25 08:02:11 +10:00
parent f39b2060a8
commit b16dbaceec
23 changed files with 370 additions and 158 deletions

View File

@@ -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)
add_asset(SCRIPT init.lua)

View File

@@ -1,5 +1,40 @@
print('Init')
module('platform')
module('input')
module('scene')
-- Load map scene
setScene('map')
setMap()
-- 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')

View File

@@ -1,4 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT

View File

@@ -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)

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;
// }
return INPUT_ACTION_COUNT;
}

View File

@@ -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);
inputaction_t inputActionGetByName(const char_t *name);

13
src/rpg/item/inventory.h Normal file
View File

@@ -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;

View File

@@ -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) {

View File

@@ -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.

View File

@@ -8,4 +8,5 @@ target_sources(${DUSK_TARGET_NAME}
PRIVATE
scriptmanager.c
scriptcontext.c
scriptmodule.c
)

View File

@@ -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");
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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();
}

32
src/script/scriptmodule.c Normal file
View File

@@ -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;
}

24
src/script/scriptmodule.h Normal file
View File

@@ -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);