diff --git a/assets/init.lua b/assets/init.lua index bb83a01..4e14b46 100644 --- a/assets/init.lua +++ b/assets/init.lua @@ -51,5 +51,5 @@ else end end --- localeSet(DUSK_LOCALE_EN_US) +localeSet(DUSK_LOCALE_EN_US) sceneSet('scene/initial.dsf') \ No newline at end of file diff --git a/assets/scene/initial.lua b/assets/scene/initial.lua index fe17caa..d029c63 100644 --- a/assets/scene/initial.lua +++ b/assets/scene/initial.lua @@ -1,15 +1,12 @@ module('spritebatch') module('camera') module('color') --- module('ui') module('text') module('screen') module('time') --- module('map') module('glm') screenSetBackground(colorBlack()) --- mapLoad('map/testmap/testmap.dmf') camera = cameraCreate(CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) text = "Hello World" @@ -21,11 +18,6 @@ function sceneUpdate() end function sceneRender() - -- Map Test - -- cameraPushMatrix(mapCamera) - -- mapRender() - -- cameraPopMatrix() - -- UI Test cameraPushMatrix(camera) camera.bottom = screenGetHeight() @@ -36,7 +28,16 @@ function sceneRender() x = math.sin(TIME.time * 2) * (x / 2) + (x / 2) y = (screenGetHeight() - height) / 2 y = math.cos(TIME.time * 3) * (y) + (y) - textDraw(x, y, text, colorMagenta()) + + -- For each letter + for i = 1, #text do + letter = text:sub(i, i) + letterWidth, _ = textMeasure(letter) + + -- Draw letter with rainbow color + textDraw(x, y, letter, colorRainbow((i - 1) * 0.1, 8)) + x = x + letterWidth + end cameraPopMatrix() end \ No newline at end of file diff --git a/src/asset/asset.c b/src/asset/asset.c index 14eee7a..aa03e7a 100644 --- a/src/asset/asset.c +++ b/src/asset/asset.c @@ -151,8 +151,7 @@ errorret_t assetInit(void) { fclose(ASSET.pbpFile); errorThrow("Failed to read PBP header", pbpPath); } - - if(memoryCompare( + if(memoryCompare( ASSET.pbpHeader.signature, ASSET_PBP_SIGNATURE, sizeof(ASSET_PBP_SIGNATURE) diff --git a/src/script/module/CMakeLists.txt b/src/script/module/CMakeLists.txt index f3086ae..412bb8f 100644 --- a/src/script/module/CMakeLists.txt +++ b/src/script/module/CMakeLists.txt @@ -4,6 +4,7 @@ # https://opensource.org/licenses/MIT # Subdirectories +add_subdirectory(asset) add_subdirectory(display) add_subdirectory(event) add_subdirectory(input) diff --git a/src/script/module/asset/CMakeLists.txt b/src/script/module/asset/CMakeLists.txt new file mode 100644 index 0000000..811d366 --- /dev/null +++ b/src/script/module/asset/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2026 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DUSK_LIBRARY_TARGET_NAME} + PUBLIC + moduleasset.c +) \ No newline at end of file diff --git a/src/script/module/asset/moduleasset.c b/src/script/module/asset/moduleasset.c new file mode 100644 index 0000000..1ab0f52 --- /dev/null +++ b/src/script/module/asset/moduleasset.c @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "moduleasset.h" +#include "asset/asset.h" +#include "display/texture.h" +#include "assert/assert.h" +#include "util/memory.h" + +void moduleAsset(scriptcontext_t *context) { + assertNotNull(context, "Script context cannot be null"); + + lua_State *l = context->luaState; + assertNotNull(l, "Lua state cannot be null"); + + // Create metatable for texture structure. + + lua_register(context->luaState, "assetTextureLoad", moduleAssetTextureLoad); + lua_register(context->luaState, "assetTextureDispose", moduleAssetTextureDispose); +} + +int moduleAssetTextureLoad(lua_State *l) { + assertNotNull(l, "Lua state cannot be NULL."); + + const char_t *filename = luaL_checkstring(l, 2); + assertStrLenMin(filename, 1, "Filename cannot be empty."); + + // Create texture owned to lua + texture_t *tex = (texture_t *)lua_newuserdata(l, sizeof(texture_t)); + memoryZero(tex, sizeof(texture_t)); + + errorret_t ret = assetLoad(filename, tex); + if(ret.code != ERROR_OK) { + errorCatch(errorPrint(ret)); + luaL_error(l, "Failed to load texture asset: %s", filename); + return 0; + } + + // Set metatable + luaL_getmetatable(l, "texture_mt"); + lua_setmetatable(l, -2); + + // Return the texture + return 1; +} + +int moduleAssetTextureDispose(lua_State *l) { + assertNotNull(l, "Lua state cannot be NULL."); + + texture_t *tex = (texture_t *)luaL_checkudata(l, 1, "texture_mt"); + assertNotNull(tex, "Texture pointer cannot be NULL."); + + textureDispose(tex); + return 0; +} \ No newline at end of file diff --git a/src/script/module/asset/moduleasset.h b/src/script/module/asset/moduleasset.h new file mode 100644 index 0000000..13bf8b0 --- /dev/null +++ b/src/script/module/asset/moduleasset.h @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "script/scriptcontext.h" + +/** + * Register asset functions to the given script context. + * + * @param context The script context to register asset functions to. + */ +void moduleAsset(scriptcontext_t *context); + +int moduleAssetTextureLoad(lua_State *l); + +int moduleAssetTextureDispose(lua_State *l); \ No newline at end of file diff --git a/src/script/module/display/modulecolor.c b/src/script/module/display/modulecolor.c index 9d0970d..9063a27 100644 --- a/src/script/module/display/modulecolor.c +++ b/src/script/module/display/modulecolor.c @@ -9,6 +9,7 @@ #include "display/color.h" #include "assert/assert.h" #include "util/string.h" +#include "time/time.h" void moduleColor(scriptcontext_t *context) { assertNotNull(context, "Context cannot be NULL."); @@ -31,6 +32,7 @@ void moduleColor(scriptcontext_t *context) { } lua_register(context->luaState, "color", moduleColorFuncColor); + lua_register(context->luaState, "colorRainbow", moduleColorRainbow); scriptContextExec(context, COLOR_SCRIPT); } @@ -147,5 +149,39 @@ int moduleColorToString(lua_State *L) { color->r, color->g, color->b, color->a ); + return 1; +} + +int moduleColorRainbow(lua_State *L) { + assertNotNull(L, "Lua state cannot be NULL."); + + // Allow time offset + float_t t = TIME.time; + if(lua_gettop(L) >= 1) { + if(!lua_isnumber(L, 1)) { + return luaL_error(L, "Rainbow time offset must be a number."); + } + t += (float_t)lua_tonumber(L, 1); + } + + // Allow speed multiplier + if(lua_gettop(L) >= 2) { + if(!lua_isnumber(L, 2)) { + return luaL_error(L, "Rainbow speed multiplier must be a number."); + } + t *= (float_t)lua_tonumber(L, 2); + } + + // Generate rainbow based on time. + color_t *color = (color_t *)lua_newuserdata(L, sizeof(color_t)); + color->r = (colorchannel8_t)((sinf(t) + 1.0f) * 0.5f * 255.0f); + color->g = (colorchannel8_t)((sinf(t + 2.0f) + 1.0f) * 0.5f * 255.0f); + color->b = (colorchannel8_t)((sinf(t + 4.0f) + 1.0f) * 0.5f * 255.0f); + color->a = 255; + + // Set metatable + luaL_getmetatable(L, "color_mt"); + lua_setmetatable(L, -2); + return 1; } \ No newline at end of file diff --git a/src/script/module/display/modulecolor.h b/src/script/module/display/modulecolor.h index f2c5076..950be54 100644 --- a/src/script/module/display/modulecolor.h +++ b/src/script/module/display/modulecolor.h @@ -44,4 +44,12 @@ int moduleColorNewIndex(lua_State *L); * @param L The Lua state. * @return Number of return values. */ -int moduleColorToString(lua_State *L); \ No newline at end of file +int moduleColorToString(lua_State *L); + +/** + * Lua function to create a rainbow color based on time. + * + * @param L The Lua state. + * @return Number of return values. + */ +int moduleColorRainbow(lua_State *L); \ No newline at end of file diff --git a/src/script/module/scene/modulescene.c b/src/script/module/scene/modulescene.c index 94b425d..acc56a3 100644 --- a/src/script/module/scene/modulescene.c +++ b/src/script/module/scene/modulescene.c @@ -28,8 +28,8 @@ int moduleSceneSet(lua_State *L) { errorret_t err = sceneSet(script); if(err.code != ERROR_OK) { - luaL_error(L, "Failed to set scene"); errorCatch(errorPrint(err)); + luaL_error(L, "Failed to set scene"); return 0; } diff --git a/src/script/scriptmodule.c b/src/script/scriptmodule.c index 74e5395..dd4fd2f 100644 --- a/src/script/scriptmodule.c +++ b/src/script/scriptmodule.c @@ -23,6 +23,7 @@ #include "script/module/display/modulescreen.h" #include "script/module/story/modulestoryflag.h" #include "script/module/map/modulemap.h" +#include "script/module/asset/moduleasset.h" #include "util/string.h" const scriptmodule_t SCRIPT_MODULE_LIST[] = { @@ -43,6 +44,7 @@ const scriptmodule_t SCRIPT_MODULE_LIST[] = { { .name = "screen", .callback = moduleScreen }, { .name = "storyflag", .callback = moduleStoryFlag }, { .name = "map", .callback = moduleMap }, + { .name = "asset", .callback = moduleAsset }, }; #define SCRIPT_MODULE_COUNT ( \