From 8699ea78450abbccf39c3a3f4a7ac94af6d5c88c Mon Sep 17 00:00:00 2001 From: jracek Date: Fri, 11 Apr 2025 23:56:13 +0200 Subject: [PATCH] It is now possible to move gameobjects with Lua --- Makefile | 2 +- output.bin | Bin 408104 -> 408144 bytes src/lua.cpp | 110 +++++++++++++++++++++------------------------------ src/main.cpp | 5 ++- 4 files changed, 51 insertions(+), 66 deletions(-) diff --git a/Makefile b/Makefile index ef9f58a..9b02e59 100644 --- a/Makefile +++ b/Makefile @@ -11,8 +11,8 @@ src/navmesh.cpp \ src/lua.cpp \ output.o -include third_party/nugget/psyqo/psyqo.mk include third_party/nugget/psyqo-lua/psyqo-lua.mk +include third_party/nugget/psyqo/psyqo.mk %.o: %.bin $(PREFIX)-objcopy -I binary --set-section-alignment .data=4 --rename-section .data=.rodata,alloc,load,readonly,data,contents -O $(FORMAT) -B mips $< $@ diff --git a/output.bin b/output.bin index e7ac2058e4866f8a869d30fd98756a6702e50760..75894ebe5eec855962857e9bdbca2dc41a99d090 100644 GIT binary patch delta 5898 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 delta 5839 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 diff --git a/src/lua.cpp b/src/lua.cpp index ddcc1f0..d0b9574 100644 --- a/src/lua.cpp +++ b/src/lua.cpp @@ -6,26 +6,21 @@ #include "psyqo-lua/lua.hh" constexpr const char METATABLE_SCRIPT[] = R"( - print("test") metatableForAllGameObjects = { __index = function(self, key) if key == "position" then local pos = rawget(self, key) if pos == nil then pos = get_position(self.__cpp_ptr) - rawset(self, key, pos) end return pos end - return rawget(self, key) + return nil end, __newindex = function(self, key, value) if key == "position" then - -- Option 1: Directly update C++ set_position(self.__cpp_ptr, value) - -- Option 2: Also update local cache: - rawset(self, key, value) return end rawset(self, key, value) @@ -35,63 +30,45 @@ constexpr const char METATABLE_SCRIPT[] = R"( // Lua helpers -int luaPrint(psyqo::Lua L) { - int n = L.getTop(); // Get the number of arguments - - for (int i = 1; i <= n; i++) { - if (i > 1) { - printf("\t"); // Tab between arguments - } - - // Check the type of the argument - if (L.isString(i)) { - printf("%s", L.toString(i)); // If it's a string, print it - } else if (L.isNumber(i)) { - printf("%g", L.toNumber(i)); // If it's a number, print it - } else { - // For other types, just print their type (you can expand this if needed) - printf("[%s]", L.typeName(i)); - } - } - printf("\n"); - - return 0; // No return value -} - -static int gameobjectSetPosition(lua_State* L) { - psxsplash::GameObject* go = (psxsplash::GameObject*)lua_touserdata(L, 1); - lua_newtable(L); - lua_pushnumber(L, go->position.x.raw()); - lua_setfield(L, -2, "x"); - lua_pushnumber(L, go->position.y.raw()); - lua_setfield(L, -2, "y"); - lua_pushnumber(L, go->position.z.raw()); - lua_setfield(L, -2, "z"); +int traceback(lua_State *L) { + const char *msg = lua_tostring(L, 1); + if (msg) + luaL_traceback(L, L, msg, 1); + else + lua_pushliteral(L, "(no error message)"); return 1; } -static int gameobjectGetPosition(lua_State* L) { - psxsplash::GameObject* go = (psxsplash::GameObject*)lua_touserdata(L, 1); - - lua_getfield(L, 2, "x"); - psyqo::FixedPoint<> x(lua_tonumber(L, -1), psyqo::FixedPoint<>::RAW); +static int gameobjectSetPosition(psyqo::Lua L) { + auto go = L.toUserdata(1); + L.getField(2, "x"); + psyqo::FixedPoint<> x(L.toNumber(3), psyqo::FixedPoint<>::RAW); go->position.x = x; - lua_pop(L, 1); - lua_getfield(L, 2, "y"); - psyqo::FixedPoint<> y(lua_tonumber(L, -1), psyqo::FixedPoint<>::RAW); - go->position.x = x; - lua_pop(L, 1); - lua_getfield(L, 2, "z"); - psyqo::FixedPoint<> z(lua_tonumber(L, -1), psyqo::FixedPoint<>::RAW); - go->position.x = x; - lua_pop(L, 1); - + L.pop(); + psyqo::FixedPoint<> y(L.toNumber(3), psyqo::FixedPoint<>::RAW); + go->position.y = y; + L.pop(); + psyqo::FixedPoint<> z(L.toNumber(3), psyqo::FixedPoint<>::RAW); + go->position.z = z; + L.pop(); return 0; } +static int gameobjectGetPosition(psyqo::Lua L) { + auto go = L.toUserdata(1); + L.newTable(); + L.pushNumber(go->position.x.raw()); + L.setField(2, "x"); + L.pushNumber(go->position.y.raw()); + L.setField(2, "y"); + L.pushNumber(go->position.z.raw()); + L.setField(2, "z"); + return 1; +} + void psxsplash::Lua::Init() { - L.push(luaPrint); - L.setGlobal("print"); +// L.push(luaPrint); +// L.setGlobal("print"); L.push(gameobjectGetPosition); L.setGlobal("get_position"); @@ -137,33 +114,38 @@ void psxsplash::Lua::LoadLuaFile(const char* code, size_t len) { } void psxsplash::Lua::RegisterGameObject(GameObject* go) { + L.push(go); // (1) = GameObject* // Create a new Lua table for the GameObject - L.newTable(); + L.newTable(); // (1) = GameObject*, (2) = {} // Set the __cpp_ptr field to store the C++ pointer - L.push(go); - L.setField(-2, "__cpp_ptr"); + L.push(go); // (1) = GameObject*, (2) = {}, (3) = GameObject* + L.setField(-2, "__cpp_ptr"); + // (1) = GameObject*, (2) = { __cpp_ptr = GameObject* } // Set the metatable for the table L.getGlobal("metatableForAllGameObjects"); + // (1) = GameObject*, (2) = { __cpp_ptr = GameObject* }, (3) = metatableForAllGameObjects if (L.isTable(-1)) { L.setMetatable(-2); // Set the metatable for the table } else { printf("Warning: metatableForAllGameObjects not found\n"); L.pop(); // Pop the invalid metatable } + // (1) = GameObject*, (2) = { __cpp_ptr = GameObject* + metatable } - L.push(go); - L.push(-2); - L.rawSet(LUA_REGISTRYINDEX); + L.rawSet(LUA_REGISTRYINDEX); + + // stack empty // Debugging: Confirm the GameObject was registered printf("GameObject registered in Lua registry: %p\n", go); - - L.pop(); } void psxsplash::Lua::CallOnCollide(GameObject* self, GameObject* other) { + L.push(traceback); + int errfunc = L.getTop(); // Save the error function index + L.getGlobal("onCollision"); if (!L.isFunction(-1)) { printf("Lua function 'onCollide' not found\n"); @@ -174,7 +156,7 @@ void psxsplash::Lua::CallOnCollide(GameObject* self, GameObject* other) { PushGameObject(self); PushGameObject(other); - if (L.pcall(2, 0)) { + if (L.pcall(2, 0, errfunc) != LUA_OK) { printf("Lua error: %s\n", L.toString(-1)); L.pop(); } diff --git a/src/main.cpp b/src/main.cpp index 58769e7..a4b1c7c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -89,7 +89,6 @@ void PSXSplash::createScene() { void MainScene::start(StartReason reason) { app.m_loader.LoadSplashpack(_binary_output_bin_start, app.m_lua); - app.m_lua.CallOnCollide(app.m_loader.gameObjects[0], app.m_loader.gameObjects[1]); psxsplash::Renderer::GetInstance().SetCamera(m_mainCamera); m_mainCamera.SetPosition(static_cast>(app.m_loader.playerStartPos.x), @@ -117,6 +116,10 @@ void MainScene::start(StartReason reason) { } void MainScene::frame() { + + app.m_lua.CallOnCollide(app.m_loader.gameObjects[0], app.m_loader.gameObjects[1]); + + uint32_t beginFrame = gpu().now(); auto currentFrameCounter = gpu().getFrameCount(); auto deltaTime = currentFrameCounter - mainScene.m_lastFrameCounter;