diff --git a/Makefile b/Makefile index 434161e..2ad089b 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ src/navmesh.cpp \ src/lua.cpp \ src/scenemanager.cpp \ src/controls.cpp \ +src/profiler.cpp \ output.o include third_party/nugget/psyqo-lua/psyqo-lua.mk diff --git a/output.bin b/output.bin index 19705c8..a1e3c10 100644 Binary files a/output.bin and b/output.bin differ diff --git a/src/main.cpp b/src/main.cpp index 038e050..c3d75c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -66,8 +66,8 @@ void MainScene::frame() { } mainScene.m_lastFrameCounter = currentFrameCounter; - - m_sceneManager.GameTick(); + + m_sceneManager.GameTick(gpu()); app.m_font.chainprintf(gpu(), {{.x = 2, .y = 2}}, {{.r = 0xff, .g = 0xff, .b = 0xff}}, "FPS: %i", gpu().getRefreshRate() / deltaTime); diff --git a/src/profiler.cpp b/src/profiler.cpp new file mode 100644 index 0000000..715649b --- /dev/null +++ b/src/profiler.cpp @@ -0,0 +1,32 @@ +#include "profiler.hh" + +#include "psyqo/xprintf.h" + +using namespace psxsplash::debug; + +void pcsxRegisterVariable(void* address, const char* name) { + register void* a0 asm("a0") = address; + register const char* a1 asm("a1") = name; + __asm__ volatile("sb %0, 0x2081(%1)" : : "r"(255), "r"(0x1f800000), "r"(a0), "r"(a1)); +} + +void Profiler::initialize() { + reset(); + + pcsxRegisterVariable(§ionTimes[0], "profiler.rendering"); + pcsxRegisterVariable(§ionTimes[1], "profiler.lua"); + pcsxRegisterVariable(§ionTimes[2], "profiler.controls"); + pcsxRegisterVariable(§ionTimes[3], "profiler.navmesh"); +} + +void Profiler::reset() { + for (auto &time : sectionTimes) { + time = 0; + } +} + +void Profiler::dumpToTTY() { + printf("profiler.rendering:%d,profiler.lua:%d,profiler.controls:%d,profiler.navmesh:%d\n", sectionTimes[0], sectionTimes[1], sectionTimes[2], sectionTimes[3]); +} + + diff --git a/src/profiler.hh b/src/profiler.hh new file mode 100644 index 0000000..93f6a24 --- /dev/null +++ b/src/profiler.hh @@ -0,0 +1,44 @@ +#pragma once + +#include + +namespace psxsplash::debug { + +enum ProfilerSection { + PROFILER_RENDERING, + PROFILER_LUA, + PROFILER_CONTROLS, + PROFILER_NAVMESH, +}; + +class Profiler { +public: + // Singleton accessor + static Profiler& getInstance() { + static Profiler instance; + return instance; + } + + void initialize(); + void reset(); + void dumpToTTY(); + + void setSectionTime(ProfilerSection section, uint32_t time) { + sectionTimes[section] = time; + } + +private: + Profiler() = default; + ~Profiler() = default; + + // Delete copy/move semantics + Profiler(const Profiler&) = delete; + Profiler& operator=(const Profiler&) = delete; + Profiler(Profiler&&) = delete; + Profiler& operator=(Profiler&&) = delete; + + uint32_t sectionTimes[4] = {0, 0, 0, 0}; + +}; + +} // namespace psxsplash::debug diff --git a/src/renderer.cpp b/src/renderer.cpp index 49280c1..44bea9d 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -23,123 +23,45 @@ using namespace psyqo::GTE; psxsplash::Renderer *psxsplash::Renderer::instance = nullptr; void psxsplash::Renderer::Init(psyqo::GPU &gpuInstance) { - psyqo::Kernel::assert(instance == nullptr, "A second intialization of Renderer was tried"); + psyqo::Kernel::assert(instance == nullptr, + "A second intialization of Renderer was tried"); - clear(); - clear(); - clear(); + clear(); + clear(); + clear(); - write(psyqo::FixedPoint<16>(160.0).raw()); - write(psyqo::FixedPoint<16>(120.0).raw()); + write(psyqo::FixedPoint<16>(160.0).raw()); + write(psyqo::FixedPoint<16>(120.0).raw()); - write(120); + write(120); - write(ORDERING_TABLE_SIZE / 3); - write(ORDERING_TABLE_SIZE / 4); + write(ORDERING_TABLE_SIZE / 3); + write(ORDERING_TABLE_SIZE / 4); - if (!instance) { - instance = new Renderer(gpuInstance); - } + if (!instance) { + instance = new Renderer(gpuInstance); + } } -void psxsplash::Renderer::SetCamera(psxsplash::Camera &camera) { m_currentCamera = &camera; } +void psxsplash::Renderer::SetCamera(psxsplash::Camera &camera) { + m_currentCamera = &camera; +} void psxsplash::Renderer::Render(eastl::vector &objects) { - psyqo::Kernel::assert(m_currentCamera != nullptr, "PSXSPLASH: Tried to render without an active camera"); + psyqo::Kernel::assert(m_currentCamera != nullptr, + "PSXSPLASH: Tried to render without an active camera"); - uint8_t parity = m_gpu.getParity(); + uint8_t parity = m_gpu.getParity(); - auto &ot = m_ots[parity]; - auto &clear = m_clear[parity]; - auto &balloc = m_ballocs[parity]; + auto &ot = m_ots[parity]; + auto &clear = m_clear[parity]; + auto &balloc = m_ballocs[parity]; - balloc.reset(); - eastl::array projected; - for (auto &obj : objects) { - psyqo::Vec3 cameraPosition, objectPosition; - psyqo::Matrix33 finalMatrix; - - ::clear(); - ::clear(); - ::clear(); - - // Rotate the camera Translation vector by the camera rotation - writeSafe(m_currentCamera->GetRotation()); - writeSafe(-m_currentCamera->GetPosition()); - - Kernels::mvmva(); - cameraPosition = readSafe(); - - // Rotate the object Translation vector by the camera rotation - writeSafe(obj->position); - Kernels::mvmva(); - objectPosition = readSafe(); - - objectPosition.x += cameraPosition.x; - objectPosition.y += cameraPosition.y; - objectPosition.z += cameraPosition.z; - - // Combine object and camera rotations - MatrixMultiplyGTE(m_currentCamera->GetRotation(), obj->rotation, &finalMatrix); - - psyqo::GTE::writeSafe(objectPosition); - psyqo::GTE::writeSafe(finalMatrix); - - for (int i = 0; i < obj->polyCount; i++) { - Tri &tri = obj->polygons[i]; - psyqo::Vec3 result; - - writeSafe(tri.v0); - writeSafe(tri.v1); - writeSafe(tri.v2); - - Kernels::rtpt(); - Kernels::nclip(); - - int32_t mac0 = 0; - read(reinterpret_cast(&mac0)); - if (mac0 <= 0) continue; - - int32_t zIndex = 0; - uint32_t u0, u1, u2; - - read(&u0); - read(&u1); - read(&u2); - - int32_t sz0 = (int32_t)u0; - int32_t sz1 = (int32_t)u1; - int32_t sz2 = (int32_t)u2; - - if ((sz0 < 1 && sz1 < 1 && sz2 < 1)) { - continue; - }; - - zIndex = eastl::max(eastl::max(sz0, sz1), sz2); - if (zIndex < 0 || zIndex >= ORDERING_TABLE_SIZE) continue; - - read(&projected[0].packed); - read(&projected[1].packed); - read(&projected[2].packed); - - recursiveSubdivideAndRender(tri, projected, zIndex, 1); - } - } - m_gpu.getNextClear(clear.primitive, m_clearcolor); - m_gpu.chain(clear); - m_gpu.chain(ot); -} - -void psxsplash::Renderer::RenderNavmeshPreview(psxsplash::Navmesh navmesh, bool isOnMesh) { - uint8_t parity = m_gpu.getParity(); - eastl::array projected; - - auto &ot = m_ots[parity]; - auto &clear = m_clear[parity]; - auto &balloc = m_ballocs[parity]; - balloc.reset(); - - psyqo::Vec3 cameraPosition; + balloc.reset(); + eastl::array projected; + for (auto &obj : objects) { + psyqo::Vec3 cameraPosition, objectPosition; + psyqo::Matrix33 finalMatrix; ::clear(); ::clear(); @@ -147,229 +69,197 @@ void psxsplash::Renderer::RenderNavmeshPreview(psxsplash::Navmesh navmesh, bool // Rotate the camera Translation vector by the camera rotation writeSafe(m_currentCamera->GetRotation()); - writeSafe(m_currentCamera->GetPosition()); + writeSafe(-m_currentCamera->GetPosition()); Kernels::mvmva(); cameraPosition = readSafe(); - write(-cameraPosition.x.raw()); - write(-cameraPosition.y.raw()); - write(-cameraPosition.z.raw()); + // Rotate the object Translation vector by the camera rotation + writeSafe(obj->position); + Kernels::mvmva(); + objectPosition = readSafe(); - psyqo::GTE::writeSafe(m_currentCamera->GetRotation()); + objectPosition.x += cameraPosition.x; + objectPosition.y += cameraPosition.y; + objectPosition.z += cameraPosition.z; - for (int i = 0; i < navmesh.triangleCount; i++) { - NavMeshTri &tri = navmesh.polygons[i]; - psyqo::Vec3 result; + // Combine object and camera rotations + MatrixMultiplyGTE(m_currentCamera->GetRotation(), obj->rotation, + &finalMatrix); - writeSafe(tri.v0); - writeSafe(tri.v1); - writeSafe(tri.v2); + psyqo::GTE::writeSafe( + objectPosition); + psyqo::GTE::writeSafe(finalMatrix); - Kernels::rtpt(); - Kernels::nclip(); + for (int i = 0; i < obj->polyCount; i++) { + Tri &tri = obj->polygons[i]; + psyqo::Vec3 result; - int32_t mac0 = 0; - read(reinterpret_cast(&mac0)); - if (mac0 <= 0) continue; + writeSafe(tri.v0); + writeSafe(tri.v1); + writeSafe(tri.v2); - int32_t zIndex = 0; - uint32_t u0, u1, u2; - read(&u0); - read(&u1); - read(&u2); + Kernels::rtpt(); + Kernels::nclip(); - int32_t sz0 = *reinterpret_cast(&u0); - int32_t sz1 = *reinterpret_cast(&u1); - int32_t sz2 = *reinterpret_cast(&u2); + /*int32_t mac0 = 0; + read(reinterpret_cast(&mac0)); + if (mac0 <= 0) + continue;*/ - zIndex = eastl::max(eastl::max(sz0, sz1), sz2); - if (zIndex < 0 || zIndex >= ORDERING_TABLE_SIZE) continue; + int32_t zIndex = 0; + uint32_t u0, u1, u2; - read(&projected[0].packed); - read(&projected[1].packed); - read(&projected[2].packed); + read(&u0); + read(&u1); + read(&u2); - auto &prim = balloc.allocateFragment(); + int32_t sz0 = (int32_t)u0; + int32_t sz1 = (int32_t)u1; + int32_t sz2 = (int32_t)u2; - prim.primitive.pointA = projected[0]; - prim.primitive.pointB = projected[1]; - prim.primitive.pointC = projected[2]; + if ((sz0 < 1 && sz1 < 1 && sz2 < 1)) { + continue; + }; - psyqo::Color heightColor; + zIndex = eastl::max(eastl::max(sz0, sz1), sz2); + if (zIndex < 0 || zIndex >= ORDERING_TABLE_SIZE) + continue; - if (isOnMesh) { - heightColor.r = 0; - heightColor.g = ((tri.v0.y.raw() + tri.v1.y.raw() + tri.v2.y.raw()) / 3) * 100 % 256; - heightColor.b = 0; - } else { - heightColor.r = ((tri.v0.y.raw() + tri.v1.y.raw() + tri.v2.y.raw()) / 3) * 100 % 256; - heightColor.g = 0; - heightColor.b = 0; - } + read(&projected[0].packed); + read(&projected[1].packed); + read(&projected[2].packed); - prim.primitive.setColor(heightColor); - prim.primitive.setOpaque(); - ot.insert(prim, zIndex); + auto &prim = + balloc.allocateFragment(); + + prim.primitive.pointA = projected[0]; + prim.primitive.pointB = projected[1]; + prim.primitive.pointC = projected[2]; + + prim.primitive.uvA = tri.uvA; + prim.primitive.uvB = tri.uvB; + prim.primitive.uvC = tri.uvC; + prim.primitive.tpage = tri.tpage; + psyqo::PrimPieces::ClutIndex clut(tri.clutX, tri.clutY); + prim.primitive.clutIndex = clut; + + prim.primitive.setColorA(tri.colorA); + prim.primitive.setColorB(tri.colorB); + prim.primitive.setColorC(tri.colorC); + prim.primitive.setOpaque(); + + m_ots[m_gpu.getParity()].insert(prim, zIndex); } - m_gpu.getNextClear(clear.primitive, m_clearcolor); - m_gpu.chain(clear); - m_gpu.chain(ot); + } + m_gpu.getNextClear(clear.primitive, m_clearcolor); + m_gpu.chain(clear); + m_gpu.chain(ot); } -void psxsplash::Renderer::VramUpload(const uint16_t *imageData, int16_t posX, int16_t posY, int16_t width, +void psxsplash::Renderer::RenderNavmeshPreview(psxsplash::Navmesh navmesh, + bool isOnMesh) { + uint8_t parity = m_gpu.getParity(); + eastl::array projected; + + auto &ot = m_ots[parity]; + auto &clear = m_clear[parity]; + auto &balloc = m_ballocs[parity]; + balloc.reset(); + + psyqo::Vec3 cameraPosition; + + ::clear(); + ::clear(); + ::clear(); + + // Rotate the camera Translation vector by the camera rotation + writeSafe(m_currentCamera->GetRotation()); + writeSafe(m_currentCamera->GetPosition()); + + Kernels::mvmva(); + cameraPosition = readSafe(); + + write(-cameraPosition.x.raw()); + write(-cameraPosition.y.raw()); + write(-cameraPosition.z.raw()); + + psyqo::GTE::writeSafe( + m_currentCamera->GetRotation()); + + for (int i = 0; i < navmesh.triangleCount; i++) { + NavMeshTri &tri = navmesh.polygons[i]; + psyqo::Vec3 result; + + writeSafe(tri.v0); + writeSafe(tri.v1); + writeSafe(tri.v2); + + Kernels::rtpt(); + Kernels::nclip(); + + int32_t mac0 = 0; + read(reinterpret_cast(&mac0)); + if (mac0 <= 0) + continue; + + int32_t zIndex = 0; + uint32_t u0, u1, u2; + read(&u0); + read(&u1); + read(&u2); + + int32_t sz0 = *reinterpret_cast(&u0); + int32_t sz1 = *reinterpret_cast(&u1); + int32_t sz2 = *reinterpret_cast(&u2); + + zIndex = eastl::max(eastl::max(sz0, sz1), sz2); + if (zIndex < 0 || zIndex >= ORDERING_TABLE_SIZE) + continue; + + read(&projected[0].packed); + read(&projected[1].packed); + read(&projected[2].packed); + + auto &prim = balloc.allocateFragment(); + + prim.primitive.pointA = projected[0]; + prim.primitive.pointB = projected[1]; + prim.primitive.pointC = projected[2]; + + psyqo::Color heightColor; + + if (isOnMesh) { + heightColor.r = 0; + heightColor.g = + ((tri.v0.y.raw() + tri.v1.y.raw() + tri.v2.y.raw()) / 3) * 100 % 256; + heightColor.b = 0; + } else { + heightColor.r = + ((tri.v0.y.raw() + tri.v1.y.raw() + tri.v2.y.raw()) / 3) * 100 % 256; + heightColor.g = 0; + heightColor.b = 0; + } + + prim.primitive.setColor(heightColor); + prim.primitive.setOpaque(); + ot.insert(prim, zIndex); + } + m_gpu.getNextClear(clear.primitive, m_clearcolor); + m_gpu.chain(clear); + m_gpu.chain(ot); +} + +void psxsplash::Renderer::VramUpload(const uint16_t *imageData, int16_t posX, + int16_t posY, int16_t width, int16_t height) { - psyqo::Rect uploadRect{.a = {.x = posX, .y = posY}, .b = {width, height}}; - m_gpu.uploadToVRAM(imageData, uploadRect); + psyqo::Rect uploadRect{.a = {.x = posX, .y = posY}, .b = {width, height}}; + m_gpu.uploadToVRAM(imageData, uploadRect); } psyqo::Color averageColor(const psyqo::Color &a, const psyqo::Color &b) { - return psyqo::Color{static_cast((a.r + b.r) >> 1), static_cast((a.g + b.g) >> 1), - static_cast((a.b + b.b) >> 1)}; + return psyqo::Color{static_cast((a.r + b.r) >> 1), + static_cast((a.g + b.g) >> 1), + static_cast((a.b + b.b) >> 1)}; } -void psxsplash::Renderer::recursiveSubdivideAndRender(Tri &tri, eastl::array &projected, int zIndex, - int maxIterations) { - uint16_t minX = eastl::min({projected[0].x, projected[1].x, projected[2].x}); - uint16_t maxX = eastl::max({projected[0].x, projected[1].x, projected[2].x}); - uint16_t minY = eastl::min({projected[0].y, projected[1].y, projected[2].y}); - uint16_t maxY = eastl::max({projected[0].y, projected[1].y, projected[2].y}); - uint16_t width = maxX - minX; - uint16_t height = maxY - minY; - - bool leavingScreenSpace = false; - if (projected[0].x < -100 || projected[0].y < -100 || projected[1].x < -100 || projected[1].y < -100 || - projected[2].x < -100 || projected[2].y < -100 || width > 420 || height > 356) { - leavingScreenSpace = true; - } - - if (maxIterations == 0 || ((width < 512 && height < 256 && !leavingScreenSpace))) { - auto &balloc = m_ballocs[m_gpu.getParity()]; - - // The 20 is some headroom just in case - if (balloc.remaining() < sizeof(psyqo::Prim::GouraudTexturedTriangle) + 20) { - return; - } - auto &prim = balloc.allocateFragment(); - - prim.primitive.pointA = projected[0]; - prim.primitive.pointB = projected[1]; - prim.primitive.pointC = projected[2]; - - prim.primitive.uvA = tri.uvA; - prim.primitive.uvB = tri.uvB; - prim.primitive.uvC = tri.uvC; - prim.primitive.tpage = tri.tpage; - psyqo::PrimPieces::ClutIndex clut(tri.clutX, tri.clutY); - prim.primitive.clutIndex = clut; - prim.primitive.setColorA(tri.colorA); - prim.primitive.setColorB(tri.colorB); - prim.primitive.setColorC(tri.colorC); - prim.primitive.setOpaque(); - - m_ots[m_gpu.getParity()].insert(prim, zIndex); - return; - } - - // FIXME: This is slow. The optimal way to do this would be to export the triangles from unity such that - // the edge between v0 and v1 is always the longest edge. This way we can always split the triangle optimally. - auto distanceSq = [](const psyqo::Vertex &a, const psyqo::Vertex &b) -> uint32_t { - int dx = a.x - b.x; - int dy = a.y - b.y; - return dx * dx + dy * dy; - }; - - uint32_t d0 = distanceSq(projected[0], projected[1]); - uint32_t d1 = distanceSq(projected[1], projected[2]); - uint32_t d2 = distanceSq(projected[2], projected[0]); - - int i, j, k; - if (d0 >= d1 && d0 >= d2) { - i = 0; - j = 1; - k = 2; - } else if (d1 >= d0 && d1 >= d2) { - i = 1; - j = 2; - k = 0; - } else { - i = 2; - j = 0; - k = 1; - } - - auto getUVu = [&](int idx) -> uint8_t { - if (idx == 0) return tri.uvA.u; - if (idx == 1) return tri.uvB.u; - return tri.uvC.u; - }; - - auto getUVv = [&](int idx) -> uint8_t { - if (idx == 0) return tri.uvA.v; - if (idx == 1) return tri.uvB.v; - return tri.uvC.v; - }; - - auto getColor = [&](int idx) -> psyqo::Color { - if (idx == 0) return tri.colorA; - if (idx == 1) return tri.colorB; - return tri.colorC; - }; - - psyqo::Vertex mid; - mid.x = (projected[i].x + projected[j].x) >> 1; - mid.y = (projected[i].y + projected[j].y) >> 1; - - uint8_t newU = (getUVu(i) + getUVu(j)) / 2; - uint8_t newV = (getUVv(i) + getUVv(j)) / 2; - - psyqo::Color newColor = averageColor(getColor(i), getColor(j)); - - eastl::array projA, projB; - projA[0] = projected[i]; - projA[1] = mid; - projA[2] = projected[k]; - - projB[0] = mid; - projB[1] = projected[j]; - projB[2] = projected[k]; - - Tri triA, triB; - - triA.uvA = {getUVu(i), getUVv(i)}; - triA.uvB = {newU, newV}; - triA.uvC = {getUVu(k), getUVv(k)}; - - triA.colorA = getColor(i); - triA.colorB = newColor; - triA.colorC = getColor(k); - - /*triA.colorA = {.r = 255}; - triA.colorB = {.r = 255}; - triA.colorC = {.r = 255};*/ - - triA.tpage = tri.tpage; - triA.clutX = tri.clutX; - triA.clutY = tri.clutY; - triA.normal = tri.normal; - - triB.uvA = {newU, newV}; - triB.uvB = {getUVu(j), getUVv(j)}; - triB.uvC = {getUVu(k), getUVv(k)}; - - triB.colorA = newColor; - triB.colorB = getColor(j); - triB.colorC = getColor(k); - - /*triB.colorA = {.g = 255}; - triB.colorB = {.g = 255}; - triB.colorC = {.g = 255};*/ - - triB.tpage = tri.tpage; - triB.clutX = tri.clutX; - triB.clutY = tri.clutY; - triB.normal = tri.normal; - - recursiveSubdivideAndRender(triA, projA, zIndex, maxIterations - 1); - recursiveSubdivideAndRender(triB, projB, zIndex, maxIterations - 1); -} \ No newline at end of file diff --git a/src/scenemanager.cpp b/src/scenemanager.cpp index 2211853..d442436 100644 --- a/src/scenemanager.cpp +++ b/src/scenemanager.cpp @@ -3,6 +3,7 @@ #include #include "navmesh.hh" +#include "profiler.hh" #include "renderer.hh" #include "splashpack.hh" @@ -13,6 +14,11 @@ using namespace psyqo::trig_literals; void psxsplash::SceneManager::InitializeScene(uint8_t* splashpackData) { L.Init(); + debug::Profiler::getInstance().initialize(); + + + debug::Profiler::getInstance().initialize(); + SplashpackSceneSetup sceneSetup; m_loader.LoadSplashpack(splashpackData, sceneSetup); @@ -43,7 +49,7 @@ void psxsplash::SceneManager::InitializeScene(uint8_t* splashpackData) { // Register game objects for (auto object : m_gameObjects) { L.RegisterGameObject(object); - } + } m_controls.Init(); Renderer::GetInstance().SetCamera(m_currentCamera); @@ -51,21 +57,50 @@ void psxsplash::SceneManager::InitializeScene(uint8_t* splashpackData) { L.OnSceneCreationEnd(); } -void psxsplash::SceneManager::GameTick() { +void psxsplash::SceneManager::GameTick(psyqo::GPU &gpu) { + + + uint32_t renderingStart = gpu.now(); auto& renderer = psxsplash::Renderer::GetInstance(); - renderer.Render(m_gameObjects); + gpu.pumpCallbacks(); + uint32_t renderingEnd = gpu.now(); + uint32_t renderingTime = renderingEnd - renderingStart; + psxsplash::debug::Profiler::getInstance().setSectionTime(psxsplash::debug::PROFILER_RENDERING, renderingTime); + uint32_t luaStart = gpu.now(); + L.OnCollision(m_gameObjects[1], m_gameObjects[0]); // Example call, replace with actual logic + gpu.pumpCallbacks(); + uint32_t luaEnd = gpu.now(); + uint32_t luaTime = luaEnd - luaStart; + psxsplash::debug::Profiler::getInstance().setSectionTime(psxsplash::debug::PROFILER_LUA, luaTime); + + + uint32_t controlsStart = gpu.now(); m_controls.HandleControls(m_playerPosition, playerRotationX, playerRotationY, playerRotationZ, false, 1); + + gpu.pumpCallbacks(); + uint32_t controlsEnd = gpu.now(); + uint32_t controlsTime = controlsEnd - controlsStart; + psxsplash::debug::Profiler::getInstance().setSectionTime(psxsplash::debug::PROFILER_CONTROLS, controlsTime); + + uint32_t navmeshStart = gpu.now(); if (!freecam) { psxsplash::ComputeNavmeshPosition(m_playerPosition, *m_navmeshes[0], static_cast>(m_playerHeight)); } + gpu.pumpCallbacks(); + uint32_t navmeshEnd = gpu.now(); + uint32_t navmeshTime = navmeshEnd - navmeshStart; + psxsplash::debug::Profiler::getInstance().setSectionTime(psxsplash::debug::PROFILER_NAVMESH, navmeshTime); m_currentCamera.SetPosition(static_cast>(m_playerPosition.x), static_cast>(m_playerPosition.y), static_cast>(m_playerPosition.z)); m_currentCamera.SetRotation(playerRotationX, playerRotationY, playerRotationZ); - L.OnCollision(m_gameObjects[1], m_gameObjects[0]); // Example call, replace with actual logic + psxsplash::debug::Profiler::getInstance().dumpToTTY(); + + + } \ No newline at end of file diff --git a/src/scenemanager.hh b/src/scenemanager.hh index 3991600..53a1571 100644 --- a/src/scenemanager.hh +++ b/src/scenemanager.hh @@ -4,6 +4,7 @@ #include #include +#include #include "camera.hh" #include "controls.hh" @@ -15,7 +16,7 @@ namespace psxsplash { class SceneManager { public: void InitializeScene(uint8_t* splashpackData); - void GameTick(); + void GameTick(psyqo::GPU &gpu); private: psxsplash::Lua L;