From 32b41c98e1df51a5d679db8eb98881e1d225d8bc Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 28 Jan 2026 11:01:07 -0600 Subject: [PATCH] Rendering a moving square entirely from lua. --- assets/scene/initial.lua | 29 +++++- src/scene/scene.c | 14 +++ src/script/module/CMakeLists.txt | 1 + src/script/module/display/CMakeLists.txt | 10 ++ src/script/module/display/modulespritebatch.c | 99 +++++++++++++++++++ src/script/module/display/modulespritebatch.h | 40 ++++++++ src/script/scriptmodule.c | 2 + 7 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 src/script/module/display/CMakeLists.txt create mode 100644 src/script/module/display/modulespritebatch.c create mode 100644 src/script/module/display/modulespritebatch.h diff --git a/assets/scene/initial.lua b/assets/scene/initial.lua index 8893b65..edee85d 100644 --- a/assets/scene/initial.lua +++ b/assets/scene/initial.lua @@ -1 +1,28 @@ -print('Initial scene') \ No newline at end of file +module('spritebatch') +module('time') + +x = 0.0 +y = 0.0 + +function sceneDispose() + -- print('Disposing initial scene') +end + +function sceneUpdate() + -- print('Updating initial scene') + x = x + TIME.delta * 10.0 + y = y + TIME.delta * 10.0 +end + +function sceneRender() + -- print('Rendering initial scene') + x1 = x + 32 + y1 = y + 32 + spriteBatchPush( + nil, + x, y, + x1, y1, + nil + ) + spriteBatchFlush() +end \ No newline at end of file diff --git a/src/scene/scene.c b/src/scene/scene.c index 9b98311..2b49b83 100644 --- a/src/scene/scene.c +++ b/src/scene/scene.c @@ -7,11 +7,18 @@ #include "assert/assert.h" #include "util/memory.h" +#include "display/camera.h" +#include "display/screen.h" + scene_t SCENE; +camera_t cam; + errorret_t sceneInit(void) { memoryZero(&SCENE, sizeof(scene_t)); + cameraInitOrthographic(&cam); + errorChain(scriptContextInit(&SCENE.scriptContext)); errorOk(); } @@ -32,9 +39,16 @@ void sceneRender(void) { return; } + cam.orthographic.right = SCREEN.width; + cam.orthographic.bottom = SCREEN.height; + cam.orthographic.left = 0.0f; + cam.orthographic.top = 0.0f; + cameraPushMatrix(&cam); + errorret_t err = scriptContextCallFunc( &SCENE.scriptContext, "sceneRender", NULL, 0, NULL ); + cameraPopMatrix(); errorCatch(errorPrint(err)); } diff --git a/src/script/module/CMakeLists.txt b/src/script/module/CMakeLists.txt index da274a2..2923dc0 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(display) add_subdirectory(event) add_subdirectory(input) add_subdirectory(item) diff --git a/src/script/module/display/CMakeLists.txt b/src/script/module/display/CMakeLists.txt new file mode 100644 index 0000000..5bdb936 --- /dev/null +++ b/src/script/module/display/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 + modulespritebatch.c +) \ No newline at end of file diff --git a/src/script/module/display/modulespritebatch.c b/src/script/module/display/modulespritebatch.c new file mode 100644 index 0000000..4925edd --- /dev/null +++ b/src/script/module/display/modulespritebatch.c @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "modulespritebatch.h" +#include "display/spritebatch.h" +#include "assert/assert.h" + +void moduleSpriteBatch(scriptcontext_t *context) { + scriptContextRegFunc(context, "spriteBatchFlush", moduleSpriteBatchFlush); + scriptContextRegFunc(context, "spriteBatchClear", moduleSpriteBatchClear); + scriptContextRegFunc(context, "spriteBatchPush", moduleSpriteBatchPush); +} + +int moduleSpriteBatchFlush(lua_State *L) { + assertNotNull(L, "Lua state is null"); + + spriteBatchFlush(); + return 0; +} + +int moduleSpriteBatchClear(lua_State *L) { + assertNotNull(L, "Lua state is null"); + + spriteBatchClear(); + return 0; +} + +int moduleSpriteBatchPush(lua_State *L) { + assertNotNull(L, "Lua state is null"); + + // Texture ID must be Nil for now + if(!lua_isnil(L, 1)) { + return luaL_error(L, "Texture parameter must be nil"); + } + + // MinX, MinY, MaxX, MaxY + if( + !lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4) || + !lua_isnumber(L, 5) + ) { + return luaL_error(L, "Sprite coordinates must be numbers"); + } + + // Color (struct), must be Nil for now + if(!lua_isnil(L, 6)) { + return luaL_error(L, "Color parameter must be nil"); + } + // if(!lua_istable(L, 6)) { + // return luaL_error(L, "Color parameter must be a color struct"); + // } + + // Optional UV min and maxes, defaults to 0,0 -> 1,1 + float_t u0 = 0.0f; + float_t v0 = 0.0f; + float_t u1 = 1.0f; + float_t v1 = 1.0f; + + if(lua_gettop(L) >= 8) { + if(!lua_isnumber(L, 7) || !lua_isnumber(L, 8)) { + return luaL_error(L, "Sprite UV min coordinates must be numbers"); + } + + u0 = (float_t)lua_tonumber(L, 7); + v0 = (float_t)lua_tonumber(L, 8); + } + + if(lua_gettop(L) >= 10) { + if(!lua_isnumber(L, 9) || !lua_isnumber(L, 10)) { + return luaL_error(L, "Sprite UV max coordinates must be numbers"); + } + + u1 = (float_t)lua_tonumber(L, 9); + v1 = (float_t)lua_tonumber(L, 10); + } + + float_t minX = (float_t)lua_tonumber(L, 2); + float_t minY = (float_t)lua_tonumber(L, 3); + float_t maxX = (float_t)lua_tonumber(L, 4); + float_t maxY = (float_t)lua_tonumber(L, 5); + + spriteBatchPush( + NULL, + minX, + minY, + maxX, + maxY, + COLOR_MAGENTA, + u0, + v0, + u1, + v1 + ); + + return 0; +} \ No newline at end of file diff --git a/src/script/module/display/modulespritebatch.h b/src/script/module/display/modulespritebatch.h new file mode 100644 index 0000000..85c6d28 --- /dev/null +++ b/src/script/module/display/modulespritebatch.h @@ -0,0 +1,40 @@ +/** + * 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 sprite batch functions to the given script context. + * + * @param context The script context to register sprite batch functions to. + */ +void moduleSpriteBatch(scriptcontext_t *context); + +/** + * Script binding for flushing the sprite batch. + * + * @param L The Lua state. + * @return Number of return values on the Lua stack. + */ +int moduleSpriteBatchFlush(lua_State *L); + +/** + * Script binding for clearing the sprite batch. + * + * @param L The Lua state. + * @return Number of return values on the Lua stack. + */ +int moduleSpriteBatchClear(lua_State *L); + +/** + * Script binding for pushing a sprite to the sprite batch. + * + * @param L The Lua state. + * @return Number of return values on the Lua stack. + */ +int moduleSpriteBatchPush(lua_State *L); \ No newline at end of file diff --git a/src/script/scriptmodule.c b/src/script/scriptmodule.c index 3bdf733..03e8ab9 100644 --- a/src/script/scriptmodule.c +++ b/src/script/scriptmodule.c @@ -14,6 +14,7 @@ #include "script/module/locale/modulelocale.h" #include "script/module/time/moduletime.h" #include "script/module/event/moduleevent.h" +#include "script/module/display/modulespritebatch.h" #include "util/string.h" const scriptmodule_t SCRIPT_MODULE_LIST[] = { @@ -25,6 +26,7 @@ const scriptmodule_t SCRIPT_MODULE_LIST[] = { { .name = "locale", .callback = moduleLocale }, { .name = "time", .callback = moduleTime }, { .name = "event", .callback = moduleEvent }, + { .name = "spritebatch", .callback = moduleSpriteBatch }, }; #define SCRIPT_MODULE_COUNT ( \