It is now possible to move gameobjects with Lua

This commit is contained in:
2025-04-11 23:56:13 +02:00
parent 441acbb6c9
commit 8699ea7845
4 changed files with 51 additions and 66 deletions

View File

@@ -11,8 +11,8 @@ src/navmesh.cpp \
src/lua.cpp \ src/lua.cpp \
output.o output.o
include third_party/nugget/psyqo/psyqo.mk
include third_party/nugget/psyqo-lua/psyqo-lua.mk include third_party/nugget/psyqo-lua/psyqo-lua.mk
include third_party/nugget/psyqo/psyqo.mk
%.o: %.bin %.o: %.bin
$(PREFIX)-objcopy -I binary --set-section-alignment .data=4 --rename-section .data=.rodata,alloc,load,readonly,data,contents -O $(FORMAT) -B mips $< $@ $(PREFIX)-objcopy -I binary --set-section-alignment .data=4 --rename-section .data=.rodata,alloc,load,readonly,data,contents -O $(FORMAT) -B mips $< $@

Binary file not shown.

View File

@@ -6,26 +6,21 @@
#include "psyqo-lua/lua.hh" #include "psyqo-lua/lua.hh"
constexpr const char METATABLE_SCRIPT[] = R"( constexpr const char METATABLE_SCRIPT[] = R"(
print("test")
metatableForAllGameObjects = { metatableForAllGameObjects = {
__index = function(self, key) __index = function(self, key)
if key == "position" then if key == "position" then
local pos = rawget(self, key) local pos = rawget(self, key)
if pos == nil then if pos == nil then
pos = get_position(self.__cpp_ptr) pos = get_position(self.__cpp_ptr)
rawset(self, key, pos)
end end
return pos return pos
end end
return rawget(self, key) return nil
end, end,
__newindex = function(self, key, value) __newindex = function(self, key, value)
if key == "position" then if key == "position" then
-- Option 1: Directly update C++
set_position(self.__cpp_ptr, value) set_position(self.__cpp_ptr, value)
-- Option 2: Also update local cache:
rawset(self, key, value)
return return
end end
rawset(self, key, value) rawset(self, key, value)
@@ -35,63 +30,45 @@ constexpr const char METATABLE_SCRIPT[] = R"(
// Lua helpers // Lua helpers
int luaPrint(psyqo::Lua L) { int traceback(lua_State *L) {
int n = L.getTop(); // Get the number of arguments const char *msg = lua_tostring(L, 1);
if (msg)
for (int i = 1; i <= n; i++) { luaL_traceback(L, L, msg, 1);
if (i > 1) { else
printf("\t"); // Tab between arguments lua_pushliteral(L, "(no error message)");
}
// 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");
return 1; return 1;
} }
static int gameobjectGetPosition(lua_State* L) { static int gameobjectSetPosition(psyqo::Lua L) {
psxsplash::GameObject* go = (psxsplash::GameObject*)lua_touserdata(L, 1); auto go = L.toUserdata<psxsplash::GameObject>(1);
L.getField(2, "x");
lua_getfield(L, 2, "x"); psyqo::FixedPoint<> x(L.toNumber(3), psyqo::FixedPoint<>::RAW);
psyqo::FixedPoint<> x(lua_tonumber(L, -1), psyqo::FixedPoint<>::RAW);
go->position.x = x; go->position.x = x;
lua_pop(L, 1); L.pop();
lua_getfield(L, 2, "y"); psyqo::FixedPoint<> y(L.toNumber(3), psyqo::FixedPoint<>::RAW);
psyqo::FixedPoint<> y(lua_tonumber(L, -1), psyqo::FixedPoint<>::RAW); go->position.y = y;
go->position.x = x; L.pop();
lua_pop(L, 1); psyqo::FixedPoint<> z(L.toNumber(3), psyqo::FixedPoint<>::RAW);
lua_getfield(L, 2, "z"); go->position.z = z;
psyqo::FixedPoint<> z(lua_tonumber(L, -1), psyqo::FixedPoint<>::RAW); L.pop();
go->position.x = x;
lua_pop(L, 1);
return 0; return 0;
} }
static int gameobjectGetPosition(psyqo::Lua L) {
auto go = L.toUserdata<psxsplash::GameObject>(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() { void psxsplash::Lua::Init() {
L.push(luaPrint); // L.push(luaPrint);
L.setGlobal("print"); // L.setGlobal("print");
L.push(gameobjectGetPosition); L.push(gameobjectGetPosition);
L.setGlobal("get_position"); L.setGlobal("get_position");
@@ -137,33 +114,38 @@ void psxsplash::Lua::LoadLuaFile(const char* code, size_t len) {
} }
void psxsplash::Lua::RegisterGameObject(GameObject* go) { void psxsplash::Lua::RegisterGameObject(GameObject* go) {
L.push(go); // (1) = GameObject*
// Create a new Lua table for the 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 // Set the __cpp_ptr field to store the C++ pointer
L.push(go); L.push(go); // (1) = GameObject*, (2) = {}, (3) = GameObject*
L.setField(-2, "__cpp_ptr"); L.setField(-2, "__cpp_ptr");
// (1) = GameObject*, (2) = { __cpp_ptr = GameObject* }
// Set the metatable for the table // Set the metatable for the table
L.getGlobal("metatableForAllGameObjects"); L.getGlobal("metatableForAllGameObjects");
// (1) = GameObject*, (2) = { __cpp_ptr = GameObject* }, (3) = metatableForAllGameObjects
if (L.isTable(-1)) { if (L.isTable(-1)) {
L.setMetatable(-2); // Set the metatable for the table L.setMetatable(-2); // Set the metatable for the table
} else { } else {
printf("Warning: metatableForAllGameObjects not found\n"); printf("Warning: metatableForAllGameObjects not found\n");
L.pop(); // Pop the invalid metatable 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 // Debugging: Confirm the GameObject was registered
printf("GameObject registered in Lua registry: %p\n", go); printf("GameObject registered in Lua registry: %p\n", go);
L.pop();
} }
void psxsplash::Lua::CallOnCollide(GameObject* self, GameObject* other) { void psxsplash::Lua::CallOnCollide(GameObject* self, GameObject* other) {
L.push(traceback);
int errfunc = L.getTop(); // Save the error function index
L.getGlobal("onCollision"); L.getGlobal("onCollision");
if (!L.isFunction(-1)) { if (!L.isFunction(-1)) {
printf("Lua function 'onCollide' not found\n"); printf("Lua function 'onCollide' not found\n");
@@ -174,7 +156,7 @@ void psxsplash::Lua::CallOnCollide(GameObject* self, GameObject* other) {
PushGameObject(self); PushGameObject(self);
PushGameObject(other); PushGameObject(other);
if (L.pcall(2, 0)) { if (L.pcall(2, 0, errfunc) != LUA_OK) {
printf("Lua error: %s\n", L.toString(-1)); printf("Lua error: %s\n", L.toString(-1));
L.pop(); L.pop();
} }

View File

@@ -89,7 +89,6 @@ void PSXSplash::createScene() {
void MainScene::start(StartReason reason) { void MainScene::start(StartReason reason) {
app.m_loader.LoadSplashpack(_binary_output_bin_start, app.m_lua); 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); psxsplash::Renderer::GetInstance().SetCamera(m_mainCamera);
m_mainCamera.SetPosition(static_cast<psyqo::FixedPoint<12>>(app.m_loader.playerStartPos.x), m_mainCamera.SetPosition(static_cast<psyqo::FixedPoint<12>>(app.m_loader.playerStartPos.x),
@@ -117,6 +116,10 @@ void MainScene::start(StartReason reason) {
} }
void MainScene::frame() { void MainScene::frame() {
app.m_lua.CallOnCollide(app.m_loader.gameObjects[0], app.m_loader.gameObjects[1]);
uint32_t beginFrame = gpu().now(); uint32_t beginFrame = gpu().now();
auto currentFrameCounter = gpu().getFrameCount(); auto currentFrameCounter = gpu().getFrameCount();
auto deltaTime = currentFrameCounter - mainScene.m_lastFrameCounter; auto deltaTime = currentFrameCounter - mainScene.m_lastFrameCounter;