From b5b0ae464cc7cc9b3474c3b3b7f0a3f9f5d0cf63 Mon Sep 17 00:00:00 2001 From: jracek Date: Mon, 14 Apr 2025 23:53:31 +0200 Subject: [PATCH] Created and implemented scenemanager, include cleanup, fixed winbuild? --- Makefile | 2 + output.bin | Bin 408324 -> 408324 bytes src/camera.cpp | 2 +- src/controls.cpp | 56 +++++++++++++ src/controls.hh | 29 +++++++ src/gameobject.hh | 3 +- src/gtemath.hh | 1 + src/lua.cpp | 184 +++++++++++++++++++++++-------------------- src/lua.h | 16 +++- src/main.cpp | 134 ++----------------------------- src/navmesh.cpp | 10 +-- src/renderer.cpp | 1 - src/renderer.hh | 9 +-- src/scenemanager.cpp | 59 ++++++++++++++ src/scenemanager.hh | 40 ++++++++++ src/splashpack.cpp | 45 +++++------ src/splashpack.hh | 21 ++--- 17 files changed, 346 insertions(+), 266 deletions(-) create mode 100644 src/controls.cpp create mode 100644 src/controls.hh create mode 100644 src/scenemanager.cpp create mode 100644 src/scenemanager.hh diff --git a/Makefile b/Makefile index 9b02e59..434161e 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,8 @@ src/camera.cpp \ src/gtemath.cpp \ src/navmesh.cpp \ src/lua.cpp \ +src/scenemanager.cpp \ +src/controls.cpp \ output.o include third_party/nugget/psyqo-lua/psyqo-lua.mk diff --git a/output.bin b/output.bin index 08b7e33b8460e24452f9591dc2461a05c011abd2..9b8443c66d1d2d2d7afac0d776f44aa279157a7c 100644 GIT binary patch delta 4618 zcmZYB4NO#576)*k^G4n6tevthxUK@r;`p%yEVxRowc6rp5m+qD@KO0_8OltxMft9! zfZhR75eF*|iVAEIJ8h+y0Zc=t6x0MkP~#GD6NzR*LK~oAw>H#-WY2%x`|czdIXUyY z=iK++eec~F_KPq3#rO1It(h;WJUn*&$GR^3N}ZRNeKPRVDUC;|2mX6hdwF>LELXkY zsUs@I|NoQY8M#-@F02aDx*FZ9lAe+KT-6J!`W99_Sy;99#RccJ?-{ut(Ymne#=@#! z7ghy(FF5;*XXJMFXU=-*G_xV|q0?c{*5=8XnEbLx35ui5C58P7R27Zb^B$W-u? zzi>HEG9Nk{BIGW~bl6nzYzVKBB+NYHEv_PhWXRl?bti+@93W{=cNpzvE-fUZ`mxko zNnA!rI%92mdlZ)?YMrJxZYXLnmdjR>PD5vGZyc9{BsP6#Y^Q8?fJ&JUZ^cP$&6!L>hM)F11%HQfVJ%!X&z~_l0sZB3St=Y@PLNXOUnJJF`ElHE1 zHeJ+AlT7S*6!UN=?+SQcr)k-FA?CB!xg?NG7{?8hnOv$!YSWtx4a(hdkT{D*@}1ed zW|m}f|77Nz@?-{SbeeioeNLTncalizvg&iHi+EQxNzKv*->M)keI(a??+0G<=kkQ) znt#{&s{vfr{!XW9_G$2~QQr4`Bx9))MsYq?k}saOt!q=}x#5yFf6?_TNo!hTwz#g~ zr8-U5D!bOE?zTsnNT#^Gr&{b$EhIzc{(^qx zT^=RrDX^Qxd%DCM@8GSZu~a_uRuY@OJ-s!J%R!Q%s8PMxqb`#4#&yPuee8j&tJCd0 z)%;$kxs^1WII8FKY$tIT+tbC4luyzd*PSSKHXBKIa(AM5b03m?pV#lUYiXBJ7wt%5 zZ;2$K{U}RFF~sC>tGP@r~k6ksi8p^w~><`#8hf>5Yx|_tF(w!`Jq!N z{jfn+Lv-0&!dcU6%z8EW=kP{cuUA*N=p*tKR!#!|-(6UsUV{SjTQ zY2xipBB@PpFp3?inxsC*ZtlqC$Le!Qy{S>z*`AO%i=5fwO4qKSr+1w-NWAa+NV-ChuHK@%J=eCl5-{XIpV$_bV)~U z$6g%T1mFpuiWkr7c9%Sgnb^VS$tP*dZcP)v*=#Pco9lCU z%|nur{2{Y=2ep5OjHQZiv`7+bP*sq4Hi})+;47ZP%Ov;cdq;dXJ$8x1$FBTdT^6X* z+z9VlFTR_0yX2a`c%n*3Zin9p7jh*~r@l>}@2#mkwBEbXR`mN#+KH!&K8(I}kB9@rja(a55a#n7k}gPCLLqZEtm zALu|}amWzZUStUDEo5&=mGX&rsaRIU!xCT!OpgqK8IT!pj6@tQ5%(a87E?;1Wvxuc z-AG1V3hGjD|K6rL>20Y(KCw?aEUWinfGqPsXwViB`y3epYej~@E+RuWEGcj om6vgC?a11tva8x}r2m%6{@+NNOR5m{;!COswbv!pCbif906#Vl6#xJL delta 4695 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 diff --git a/src/camera.cpp b/src/camera.cpp index c0c629c..0dfe72b 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -30,7 +30,7 @@ void psxsplash::Camera::SetRotation(psyqo::Angle x, psyqo::Angle y, psyqo::Angle // XYZ multiplication order (matches C#) psyqo::SoftMath::multiplyMatrix33(rotY, rotX, &rotY); psyqo::SoftMath::multiplyMatrix33(rotY, rotZ, &rotY); - + m_rotationMatrix = rotY; } diff --git a/src/controls.cpp b/src/controls.cpp new file mode 100644 index 0000000..6337c9e --- /dev/null +++ b/src/controls.cpp @@ -0,0 +1,56 @@ +#include "controls.hh" + +#include + +void psxsplash::Controls::Init() { m_input.initialize(); } + +void psxsplash::Controls::HandleControls(psyqo::Vec3 &playerPosition, psyqo::Angle &playerRotationX, + psyqo::Angle &playerRotationY, psyqo::Angle &playerRotationZ, bool freecam, + int deltaTime) { + uint8_t rightX = m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 0); + uint8_t rightY = m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 1); + + uint8_t leftX = m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 2); + uint8_t leftY = m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 3); + + int16_t rightXOffset = (int16_t)rightX - 0x80; + int16_t rightYOffset = (int16_t)rightY - 0x80; + int16_t leftXOffset = (int16_t)leftX - 0x80; + int16_t leftYOffset = (int16_t)leftY - 0x80; + + if (__builtin_abs(leftXOffset) < m_stickDeadzone && __builtin_abs(leftYOffset) < m_stickDeadzone) { + m_sprinting = false; + } + + if (m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::L3)) { + m_sprinting = true; + } + + psyqo::FixedPoint<12> speed = m_sprinting ? sprintSpeed : moveSpeed; + + if (__builtin_abs(rightXOffset) > m_stickDeadzone) { + playerRotationY += (rightXOffset * rotSpeed * deltaTime) >> 7; + } + if (__builtin_abs(rightYOffset) > m_stickDeadzone) { + playerRotationX -= (rightYOffset * rotSpeed * deltaTime) >> 7; + playerRotationX = eastl::clamp(playerRotationX, -0.5_pi, 0.5_pi); + } + + if (__builtin_abs(leftYOffset) > m_stickDeadzone) { + psyqo::FixedPoint<12> forward = -(leftYOffset * speed * deltaTime) >> 7; + playerPosition.x += m_trig.sin(playerRotationY) * forward; + playerPosition.z += m_trig.cos(playerRotationY) * forward; + } + if (__builtin_abs(leftXOffset) > m_stickDeadzone) { + psyqo::FixedPoint<12> strafe = -(leftXOffset * speed * deltaTime) >> 7; + playerPosition.x -= m_trig.cos(playerRotationY) * strafe; + playerPosition.z += m_trig.sin(playerRotationY) * strafe; + } + + if (m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::L1)) { + playerPosition.y += speed * deltaTime; + } + if (m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::R1)) { + playerPosition.y -= speed * deltaTime; + } +} \ No newline at end of file diff --git a/src/controls.hh b/src/controls.hh new file mode 100644 index 0000000..09cfd87 --- /dev/null +++ b/src/controls.hh @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + +namespace psxsplash { + +using namespace psyqo::fixed_point_literals; +using namespace psyqo::trig_literals; + +class Controls { + public: + void Init(); + void HandleControls(psyqo::Vec3 &playerPosition, psyqo::Angle &playerRotationX, psyqo::Angle &playerRotationY, + psyqo::Angle &playerRotationZ, bool freecam, int deltaTime); + + private: + psyqo::AdvancedPad m_input; + psyqo::Trig<> m_trig; + + bool m_sprinting = false; + static constexpr uint8_t m_stickDeadzone = 0x30; + static constexpr psyqo::FixedPoint<12> moveSpeed = 0.002_fp; + static constexpr psyqo::Angle rotSpeed = 0.01_pi; + static constexpr psyqo::FixedPoint<12> sprintSpeed = 0.01_fp; +}; + +}; // namespace psxsplash \ No newline at end of file diff --git a/src/gameobject.hh b/src/gameobject.hh index ae762a0..e89c530 100644 --- a/src/gameobject.hh +++ b/src/gameobject.hh @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -17,7 +16,7 @@ class GameObject final { psyqo::Vec3 position; psyqo::Matrix33 rotation; uint16_t polyCount; - uint16_t reserved; + int16_t luaFileIndex; }; static_assert(sizeof(GameObject) == 56, "GameObject is not 56 bytes"); } // namespace psxsplash \ No newline at end of file diff --git a/src/gtemath.hh b/src/gtemath.hh index 73fb10b..063474e 100644 --- a/src/gtemath.hh +++ b/src/gtemath.hh @@ -1,4 +1,5 @@ #pragma once + #include namespace psxsplash { diff --git a/src/lua.cpp b/src/lua.cpp index 4d458f5..5c17d80 100644 --- a/src/lua.cpp +++ b/src/lua.cpp @@ -1,44 +1,38 @@ #include "lua.h" +#include + #include #include "gameobject.hh" -#include "psyqo-lua/lua.hh" constexpr const char METATABLE_SCRIPT[] = R"( - metatableForAllGameObjects = { - __index = function(self, key) - if key == "position" then - local pos = rawget(self, key) - if pos == nil then - pos = get_position(self.__cpp_ptr) - end - return pos - end - return nil - end, +return function(metatable) + local get_position = metatable.get_position + local set_position = metatable.set_position - __newindex = function(self, key, value) - if key == "position" then - set_position(self.__cpp_ptr, value) - return - end - rawset(self, key, value) + metatable.get_position = nil + metatable.set_position = nil + + function metatable.__index(self, key) + if key == "position" then + return get_position(self.__cpp_ptr) end - } + return nil + end + + function metatable.__newindex(self, key, value) + if key == "position" then + set_position(self.__cpp_ptr, value) + return + end + rawset(self, key, value) + end +end )"; // Lua helpers -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 gameobjectSetPosition(psyqo::Lua L) { auto go = L.toUserdata(1); L.getField(2, "x"); @@ -69,46 +63,67 @@ static int gameobjectGetPosition(psyqo::Lua L) { } void psxsplash::Lua::Init() { -// L.push(luaPrint); -// L.setGlobal("print"); - - L.push(gameobjectGetPosition); - L.setGlobal("get_position"); - - L.push(gameobjectSetPosition); - L.setGlobal("set_position"); - // Load and run the metatable script - if (L.loadBuffer(METATABLE_SCRIPT, "metatableForAllGameObjects") == 0) { - if (L.pcall(0, 0) == 0) { - // Script executed successfully - printf("Lua script 'metatableForAllGameObjects' loaded successfully\n"); + if (L.loadBuffer(METATABLE_SCRIPT, "buffer:metatableForAllGameObjects") == 0) { + if (L.pcall(0, 1) == 0) { + // This will be our metatable + L.newTable(); + + L.push(gameobjectGetPosition); + L.setField(-2, "get_position"); + + L.push(gameobjectSetPosition); + L.setField(-2, "set_position"); + + L.copy(-1); + m_metatableReference = L.ref(); + + if (L.pcall(1, 0) == 0) { + printf("Lua script 'metatableForAllGameObjects' executed successfully"); + } else { + printf("Error registering Lua script: %s\n", L.optString(-1, "Unknown error")); + L.clearStack(); + return; + } } else { // Print Lua error if script execution fails - printf("Error executing Lua script: %s\n", L.isString(-1) ? L.toString(-1) : "Unknown error"); - L.pop(); + printf("Error executing Lua script: %s\n", L.optString(-1, "Unknown error")); + L.clearStack(); + return; } } else { // Print Lua error if script loading fails - printf("Error loading Lua script: %s\n", L.isString(-1) ? L.toString(-1) : "Unknown error"); - L.pop(); + printf("Error loading Lua script: %s\n", L.optString(-1, "Unknown error")); + L.clearStack(); + return; } - // Check if the metatable was set as a global - L.getGlobal("metatableForAllGameObjects"); - if (L.isTable(-1)) { - printf("metatableForAllGameObjects successfully set as a global\n"); - } else { - printf("Warning: metatableForAllGameObjects not found after init\n"); - } - L.pop(); // Pop the global check + L.newTable(); + m_luascriptsReference = L.ref(); } -void psxsplash::Lua::LoadLuaFile(const char* code, size_t len) { - if (L.loadBuffer(code, len) != LUA_OK) { +void psxsplash::Lua::LoadLuaFile(const char* code, size_t len, int index) { + char filename[32]; + snprintf(filename, sizeof(filename), "lua_asset:%d", index); + if (L.loadBuffer(code, len, filename) != LUA_OK) { printf("Lua error: %s\n", L.toString(-1)); L.pop(); } + // (1) script func + L.rawGetI(LUA_REGISTRYINDEX, m_luascriptsReference); + // (1) script func (2) scripts table + L.newTable(); + // (1) script func (2) scripts table (3) {} + L.pushNumber(index); + // (1) script func (2) scripts table (3) {} (4) index + L.copy(-2); + // (1) script func (2) scripts table (3) {} (4) index (5) {} + L.setTable(-4); + // (1) script func (2) scripts table (3) {} + lua_setupvalue(L.getState(), -3, 1); + // (1) script func (2) scripts table + L.pop(); + // (1) script func if (L.pcall(0, 0)) { printf("Lua error: %s\n", L.toString(-1)); L.pop(); @@ -116,42 +131,41 @@ 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(); // (1) = GameObject*, (2) = {} - - // Set the __cpp_ptr field to store the C++ pointer - L.push(go); // (1) = GameObject*, (2) = {}, (3) = GameObject* + L.push(go); + // (1) go + L.newTable(); + // (1) go (2) {} + L.push(go); + // (1) go (2) {} (3) go 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 + // (1) go (2) { __cpp_ptr = go } + L.rawGetI(LUA_REGISTRYINDEX, m_metatableReference); + // (1) go (2) { __cpp_ptr = go } (3) metatable if (L.isTable(-1)) { - L.setMetatable(-2); // Set the metatable for the table + L.setMetatable(-2); } else { printf("Warning: metatableForAllGameObjects not found\n"); - L.pop(); // Pop the invalid metatable + L.pop(); } - // (1) = GameObject*, (2) = { __cpp_ptr = GameObject* + metatable } - + // (1) go (2) { __cpp_ptr = go + metatable } L.rawSet(LUA_REGISTRYINDEX); - - // stack empty - - // Debugging: Confirm the GameObject was registered + // empty stack printf("GameObject registered in Lua registry: %p\n", go); } void psxsplash::Lua::CallOnCollide(GameObject* self, GameObject* other) { - L.push(traceback); - int errfunc = L.getTop(); // Save the error function index - - L.getGlobal("onCollision"); + if (self->luaFileIndex == -1) { + return; + } + L.rawGetI(LUA_REGISTRYINDEX, m_luascriptsReference); + // (1) scripts table + L.rawGetI(-1, self->luaFileIndex); + // (1) script table (2) script environment + L.getField(-1, "onCollision"); + // (1) script table (2) script environment (3) onCollision if (!L.isFunction(-1)) { - printf("Lua function 'onCollide' not found\n"); - L.pop(); + printf("Lua function 'onCollision' not found\n"); + L.clearStack(); return; } @@ -160,16 +174,16 @@ void psxsplash::Lua::CallOnCollide(GameObject* self, GameObject* other) { if (L.pcall(2, 0) != LUA_OK) { printf("Lua error: %s\n", L.toString(-1)); - L.pop(); } + L.clearStack(); } void psxsplash::Lua::PushGameObject(GameObject* go) { - L.push(go); - L.rawGet(LUA_REGISTRYINDEX); + L.push(go); + L.rawGet(LUA_REGISTRYINDEX); - if (!L.isTable(-1)) { + if (!L.isTable(-1)) { printf("Warning: GameObject not found in Lua registry\n"); - L.pop(); + L.pop(); } } diff --git a/src/lua.h b/src/lua.h index 9445f7f..f0d714f 100644 --- a/src/lua.h +++ b/src/lua.h @@ -5,16 +5,28 @@ #include "gameobject.hh" namespace psxsplash { + +struct LuaFile { + union { + uint32_t luaCodeOffset; + const char* luaCode; + }; + uint32_t length; +}; + class Lua { public: void Init(); - - void LoadLuaFile(const char* code, size_t len); + + void LoadLuaFile(const char* code, size_t len, int index); void RegisterGameObject(GameObject* go); void CallOnCollide(GameObject* self, GameObject* other); private: void PushGameObject(GameObject* go); psyqo::Lua L; + + int m_metatableReference; + int m_luascriptsReference; }; } // namespace psxsplash \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a4b1c7c..038e050 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,3 @@ -#include - -#include -#include #include #include #include @@ -10,56 +6,29 @@ #include #include -#include "EASTL/algorithm.h" -#include "camera.hh" -#include "lua.h" -#include "navmesh.hh" -#include "psyqo/vector.hh" #include "renderer.hh" -#include "splashpack.hh" +#include "scenemanager.hh" // Data from the splashpack extern uint8_t _binary_output_bin_start[]; namespace { -using namespace psyqo::fixed_point_literals; -using namespace psyqo::trig_literals; - class PSXSplash final : public psyqo::Application { void prepare() override; void createScene() override; public: - psxsplash::Lua m_lua; - psxsplash::SplashPackLoader m_loader; - psyqo::Font<> m_font; - - psyqo::AdvancedPad m_input; - static constexpr uint8_t m_stickDeadzone = 0x30; }; class MainScene final : public psyqo::Scene { void frame() override; void start(StartReason reason) override; - psxsplash::Camera m_mainCamera; - psyqo::Angle camRotX, camRotY, camRotZ; - - psyqo::Trig<> m_trig; uint32_t m_lastFrameCounter; - static constexpr psyqo::FixedPoint<12> moveSpeed = 0.002_fp; - static constexpr psyqo::Angle rotSpeed = 0.01_pi; - - bool m_sprinting = false; - static constexpr psyqo::FixedPoint<12> sprintSpeed = 0.01_fp; - - bool m_freecam = false; - psyqo::FixedPoint<12> pheight = 0.0_fp; - - bool m_renderSelect = false; + psxsplash::SceneManager m_sceneManager; }; PSXSplash app; @@ -77,49 +46,16 @@ void PSXSplash::prepare() { // Initialize the Renderer singleton psxsplash::Renderer::Init(gpu()); - - m_lua.Init(); } void PSXSplash::createScene() { m_font.uploadSystemFont(gpu()); - m_input.initialize(); pushScene(&mainScene); } -void MainScene::start(StartReason reason) { - app.m_loader.LoadSplashpack(_binary_output_bin_start, app.m_lua); - psxsplash::Renderer::GetInstance().SetCamera(m_mainCamera); - - m_mainCamera.SetPosition(static_cast>(app.m_loader.playerStartPos.x), - static_cast>(app.m_loader.playerStartPos.y), - static_cast>(app.m_loader.playerStartPos.z)); - - pheight = psyqo::FixedPoint<12>(app.m_loader.playerHeight); - - app.m_input.setOnEvent( - eastl::function{[this](const psyqo::AdvancedPad::Event& event) { - if (event.pad != psyqo::AdvancedPad::Pad::Pad1a) return; - if (app.m_loader.navmeshes.empty()) return; - if (event.type == psyqo::AdvancedPad::Event::ButtonPressed) { - if (event.button == psyqo::AdvancedPad::Button::Triangle) { - m_freecam = !m_freecam; - } else if (event.button == psyqo::AdvancedPad::Button::Square) { - m_renderSelect = !m_renderSelect; - } - } - }}); - - if (app.m_loader.navmeshes.empty()) { - m_freecam = true; - } -} +void MainScene::start(StartReason reason) { m_sceneManager.InitializeScene(_binary_output_bin_start); } 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; @@ -131,70 +67,10 @@ void MainScene::frame() { mainScene.m_lastFrameCounter = currentFrameCounter; - uint8_t rightX = app.m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 0); - uint8_t rightY = app.m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 1); - - uint8_t leftX = app.m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 2); - uint8_t leftY = app.m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 3); - - int16_t rightXOffset = (int16_t)rightX - 0x80; - int16_t rightYOffset = (int16_t)rightY - 0x80; - int16_t leftXOffset = (int16_t)leftX - 0x80; - int16_t leftYOffset = (int16_t)leftY - 0x80; - - if (__builtin_abs(leftXOffset) < app.m_stickDeadzone && - __builtin_abs(leftYOffset) < app.m_stickDeadzone) { - m_sprinting = false; - } - - if (app.m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::L3)) { - m_sprinting = true; - } - - psyqo::FixedPoint<12> speed = m_sprinting ? sprintSpeed : moveSpeed; - - if (__builtin_abs(rightXOffset) > app.m_stickDeadzone) { - camRotY += (rightXOffset * rotSpeed * deltaTime) >> 7; - } - if (__builtin_abs(rightYOffset) > app.m_stickDeadzone) { - camRotX -= (rightYOffset * rotSpeed * deltaTime) >> 7; - camRotX = eastl::clamp(camRotX, -0.5_pi, 0.5_pi); - } - m_mainCamera.SetRotation(camRotX, camRotY, camRotZ); - - if (__builtin_abs(leftYOffset) > app.m_stickDeadzone) { - psyqo::FixedPoint<12> forward = -(leftYOffset * speed * deltaTime) >> 7; - m_mainCamera.MoveX((m_trig.sin(camRotY) * forward)); - m_mainCamera.MoveZ((m_trig.cos(camRotY) * forward)); - } - if (__builtin_abs(leftXOffset) > app.m_stickDeadzone) { - psyqo::FixedPoint<12> strafe = -(leftXOffset * speed * deltaTime) >> 7; - m_mainCamera.MoveX(-(m_trig.cos(camRotY) * strafe)); - m_mainCamera.MoveZ((m_trig.sin(camRotY) * strafe)); - } - - if (app.m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::L1)) { - m_mainCamera.MoveY(speed * deltaTime); - } - if (app.m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::R1)) { - m_mainCamera.MoveY(-speed * deltaTime); - } - - if (!m_freecam) { - psyqo::Vec3 adjustedPosition = - psxsplash::ComputeNavmeshPosition(m_mainCamera.GetPosition(), *app.m_loader.navmeshes[0], -pheight); - m_mainCamera.SetPosition(adjustedPosition.x, adjustedPosition.y, adjustedPosition.z); - } - - if (!m_renderSelect) { - psxsplash::Renderer::GetInstance().Render(app.m_loader.gameObjects); - } else { - psxsplash::Renderer::GetInstance().RenderNavmeshPreview(*app.m_loader.navmeshes[0], true); - } - + m_sceneManager.GameTick(); app.m_font.chainprintf(gpu(), {{.x = 2, .y = 2}}, {{.r = 0xff, .g = 0xff, .b = 0xff}}, "FPS: %i", - gpu().getRefreshRate() / deltaTime); + gpu().getRefreshRate() / deltaTime); gpu().pumpCallbacks(); uint32_t endFrame = gpu().now(); diff --git a/src/navmesh.cpp b/src/navmesh.cpp index bd21ed0..fa8bdfa 100644 --- a/src/navmesh.cpp +++ b/src/navmesh.cpp @@ -2,8 +2,8 @@ #include -#include "psyqo/fixed-point.hh" -#include "psyqo/vector.hh" +#include +#include using namespace psyqo::fixed_point_literals; @@ -80,10 +80,10 @@ psyqo::FixedPoint<12> CalculateY(const psyqo::Vec3& p, const NavMeshTri& tri) { } } -psyqo::Vec3 ComputeNavmeshPosition(psyqo::Vec3& position, Navmesh& navmesh, psyqo::FixedPoint<12> pheight) { +psyqo::Vec3 ComputeNavmeshPosition(psyqo::Vec3& position, Navmesh& navmesh, psyqo::FixedPoint<12> playerHeight) { for (int i = 0; i < navmesh.triangleCount; i++) { if (PointInTriangle(position, navmesh.polygons[i])) { - position.y = CalculateY(position, navmesh.polygons[i]) + pheight; + position.y = CalculateY(position, navmesh.polygons[i]) - playerHeight; return position; } } @@ -108,7 +108,7 @@ psyqo::Vec3 ComputeNavmeshPosition(psyqo::Vec3& position, Navmesh& navmesh, psyq if (distSq < minDist) { minDist = distSq; closestPoint = proj; - position.y = CalculateY(position, navmesh.polygons[i]) + pheight; + position.y = CalculateY(position, navmesh.polygons[i]) - playerHeight; } } } diff --git a/src/renderer.cpp b/src/renderer.cpp index 9d14658..49280c1 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/src/renderer.hh b/src/renderer.hh index c5a733a..4244b81 100644 --- a/src/renderer.hh +++ b/src/renderer.hh @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -25,7 +24,8 @@ class Renderer final { Renderer(const Renderer&) = delete; Renderer& operator=(const Renderer&) = delete; - // FIXME: I have no idea how to precompute the required sizes of these. It would be best to allocate them based on the scene + // FIXME: I have no idea how to precompute the required sizes of these. It would be best to allocate them based on + // the scene static constexpr size_t ORDERING_TABLE_SIZE = 2048 * 3; static constexpr size_t BUMP_ALLOCATOR_SIZE = 8096 * 24; @@ -33,7 +33,6 @@ class Renderer final { void SetCamera(Camera& camera); - void Render(eastl::vector& objects); void RenderNavmeshPreview(psxsplash::Navmesh navmesh, bool isOnMesh); @@ -61,8 +60,8 @@ class Renderer final { psyqo::Color m_clearcolor = {.r = 0, .g = 0, .b = 0}; - void recursiveSubdivideAndRender(Tri &tri, eastl::array &projected, int zIndex, - int maxIterations); + void recursiveSubdivideAndRender(Tri& tri, eastl::array& projected, int zIndex, + int maxIterations); }; } // namespace psxsplash \ No newline at end of file diff --git a/src/scenemanager.cpp b/src/scenemanager.cpp new file mode 100644 index 0000000..2742e7c --- /dev/null +++ b/src/scenemanager.cpp @@ -0,0 +1,59 @@ +#include "scenemanager.hh" + +#include + +#include "navmesh.hh" +#include "renderer.hh" +#include "splashpack.hh" + +using namespace psyqo::trig_literals; + +void psxsplash::SceneManager::InitializeScene(uint8_t* splashpackData) { + L.Init(); + + SplashpackSceneSetup sceneSetup; + m_loader.LoadSplashpack(splashpackData, sceneSetup); + + m_luaFiles = std::move(sceneSetup.luaFiles); + m_gameObjects = std::move(sceneSetup.objects); + m_navmeshes = std::move(sceneSetup.navmeshes); + + m_playerPosition = sceneSetup.playerStartPosition; + + playerRotationX = 0.0_pi; + playerRotationY = 0.0_pi; + playerRotationZ = 0.0_pi; + + m_playerHeight = sceneSetup.playerHeight; + + // Load Lua files + for (int i = 0; i < m_luaFiles.size(); i++) { + auto luaFile = m_luaFiles[i]; + L.LoadLuaFile(luaFile->luaCode, luaFile->length, i); + } + + // Register game objects + for (auto object : m_gameObjects) { + L.RegisterGameObject(object); + } + + m_controls.Init(); + Renderer::GetInstance().SetCamera(m_currentCamera); +} + +void psxsplash::SceneManager::GameTick() { + auto& renderer = psxsplash::Renderer::GetInstance(); + + renderer.Render(m_gameObjects); + + m_controls.HandleControls(m_playerPosition, playerRotationX, playerRotationY, playerRotationZ, false, 1); + if (!freecam) { + psxsplash::ComputeNavmeshPosition(m_playerPosition, *m_navmeshes[0], + static_cast>(m_playerHeight)); + } + + m_currentCamera.SetPosition(static_cast>(m_playerPosition.x), + static_cast>(m_playerPosition.y), + static_cast>(m_playerPosition.z)); + m_currentCamera.SetRotation(playerRotationX, playerRotationY, playerRotationZ); +} \ No newline at end of file diff --git a/src/scenemanager.hh b/src/scenemanager.hh new file mode 100644 index 0000000..7f3e399 --- /dev/null +++ b/src/scenemanager.hh @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include +#include + +#include "camera.hh" +#include "controls.hh" +#include "gameobject.hh" +#include "lua.h" +#include "splashpack.hh" + +namespace psxsplash { +class SceneManager { + public: + void InitializeScene(uint8_t* splashpackData); + void GameTick(); + + private: + psxsplash::Lua L; + psxsplash::SplashPackLoader m_loader; + + eastl::vector m_luaFiles; + eastl::vector m_gameObjects; + eastl::vector m_navmeshes; + + psxsplash::Controls m_controls; + + psxsplash::Camera m_currentCamera; + + psyqo::Vec3 m_playerPosition; + psyqo::Angle playerRotationX, playerRotationY, playerRotationZ; + + psyqo::FixedPoint<12, uint16_t> m_playerHeight; + + bool previewNavmesh = false; + bool freecam = false; +}; +}; // namespace psxsplash \ No newline at end of file diff --git a/src/splashpack.cpp b/src/splashpack.cpp index 85bb4b5..0aaee1a 100644 --- a/src/splashpack.cpp +++ b/src/splashpack.cpp @@ -1,14 +1,15 @@ #include "splashpack.hh" -#include -#include +#include + +#include +#include #include #include "gameobject.hh" #include "lua.h" #include "mesh.hh" -#include "psyqo/fixed-point.hh" -#include "psyqo/gte-registers.hh" +#include "navmesh.hh" #include "renderer.hh" namespace psxsplash { @@ -27,14 +28,6 @@ struct SPLASHPACKFileHeader { uint16_t pad[2]; }; -struct SPLASHPACKLuaFile { - union { - uint32_t luaCodeOffset; - const char* luaCode; - }; - uint32_t length; -}; - struct SPLASHPACKTextureAtlas { uint32_t polygonsOffset; uint16_t width, height; @@ -49,39 +42,39 @@ struct SPLASHPACKClut { uint16_t pad; }; -void SplashPackLoader::LoadSplashpack(uint8_t *data, psxsplash::Lua &lua) { +void SplashPackLoader::LoadSplashpack(uint8_t *data, SplashpackSceneSetup &setup) { psyqo::Kernel::assert(data != nullptr, "Splashpack loading data pointer is null"); psxsplash::SPLASHPACKFileHeader *header = reinterpret_cast(data); - psyqo::Kernel::assert(memcmp(header->magic, "SP", 2) == 0, "Splashpack has incorrect magic"); + psyqo::Kernel::assert(__builtin_memcmp(header->magic, "SP", 2) == 0, "Splashpack has incorrect magic"); - playerStartPos = header->playerStartPos; - playerStartRot = header->playerStartRot; - playerHeight = header->playerHeight; + setup.playerStartPosition = header->playerStartPos; + setup.playerStartRotation = header->playerStartRot; + setup.playerHeight = header->playerHeight; - gameObjects.reserve(header->gameObjectCount); - navmeshes.reserve(header->navmeshCount); + setup.luaFiles.reserve(header->luaFileCount); + setup.objects.reserve(header->gameObjectCount); + setup.navmeshes.reserve(header->navmeshCount); uint8_t *curentPointer = data + sizeof(psxsplash::SPLASHPACKFileHeader); for (uint16_t i = 0; i < header->luaFileCount; i++) { - psxsplash::SPLASHPACKLuaFile *luaHeader = reinterpret_cast(curentPointer); - luaHeader->luaCode = reinterpret_cast(data + luaHeader->luaCodeOffset); - lua.LoadLuaFile(luaHeader->luaCode, luaHeader->length); - curentPointer += sizeof(psxsplash::SPLASHPACKLuaFile); + psxsplash::LuaFile *luaHeader = reinterpret_cast(curentPointer); + luaHeader->luaCode = reinterpret_cast(data + luaHeader->luaCodeOffset); + setup.luaFiles.push_back(luaHeader); + curentPointer += sizeof(psxsplash::LuaFile); } for (uint16_t i = 0; i < header->gameObjectCount; i++) { psxsplash::GameObject *go = reinterpret_cast(curentPointer); go->polygons = reinterpret_cast(data + go->polygonsOffset); - lua.RegisterGameObject(go); - gameObjects.push_back(go); + setup.objects.push_back(go); curentPointer += sizeof(psxsplash::GameObject); } for (uint16_t i = 0; i < header->navmeshCount; i++) { psxsplash::Navmesh *navmesh = reinterpret_cast(curentPointer); navmesh->polygons = reinterpret_cast(data + navmesh->polygonsOffset); - navmeshes.push_back(navmesh); + setup.navmeshes.push_back(navmesh); curentPointer += sizeof(psxsplash::Navmesh); } diff --git a/src/splashpack.hh b/src/splashpack.hh index 9806bdc..080dca1 100644 --- a/src/splashpack.hh +++ b/src/splashpack.hh @@ -2,25 +2,26 @@ #include -#include +#include #include "gameobject.hh" #include "lua.h" #include "navmesh.hh" -#include "psyqo/fixed-point.hh" namespace psxsplash { - +struct SplashpackSceneSetup { + eastl::vector luaFiles; + eastl::vector objects; + eastl::vector navmeshes; + psyqo::GTE::PackedVec3 playerStartPosition; + psyqo::GTE::PackedVec3 playerStartRotation; + psyqo::FixedPoint<12, uint16_t> playerHeight; +}; + class SplashPackLoader { public: - eastl::vector gameObjects; - eastl::vector navmeshes; - - psyqo::GTE::PackedVec3 playerStartPos, playerStartRot; - psyqo::FixedPoint<12, uint16_t> playerHeight; - - void LoadSplashpack(uint8_t *data, Lua &lua); + void LoadSplashpack(uint8_t *data, SplashpackSceneSetup &setup); }; }; // namespace psxsplash \ No newline at end of file