feature: Added profiler which outputs to tty, removed subdivision entirely - to be remade later

This commit is contained in:
2025-09-04 18:04:30 +02:00
parent 8151f3864c
commit 55c1d2c39b
8 changed files with 314 additions and 311 deletions

View File

@@ -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);

32
src/profiler.cpp Normal file
View File

@@ -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(&sectionTimes[0], "profiler.rendering");
pcsxRegisterVariable(&sectionTimes[1], "profiler.lua");
pcsxRegisterVariable(&sectionTimes[2], "profiler.controls");
pcsxRegisterVariable(&sectionTimes[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]);
}

44
src/profiler.hh Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
#include <stdint.h>
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

View File

@@ -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<Register::TRX, Safe>();
clear<Register::TRY, Safe>();
clear<Register::TRZ, Safe>();
clear<Register::TRX, Safe>();
clear<Register::TRY, Safe>();
clear<Register::TRZ, Safe>();
write<Register::OFX, Safe>(psyqo::FixedPoint<16>(160.0).raw());
write<Register::OFY, Safe>(psyqo::FixedPoint<16>(120.0).raw());
write<Register::OFX, Safe>(psyqo::FixedPoint<16>(160.0).raw());
write<Register::OFY, Safe>(psyqo::FixedPoint<16>(120.0).raw());
write<Register::H, Safe>(120);
write<Register::H, Safe>(120);
write<Register::ZSF3, Safe>(ORDERING_TABLE_SIZE / 3);
write<Register::ZSF4, Safe>(ORDERING_TABLE_SIZE / 4);
write<Register::ZSF3, Safe>(ORDERING_TABLE_SIZE / 3);
write<Register::ZSF4, Safe>(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<GameObject *> &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<psyqo::Vertex, 3> projected;
for (auto &obj : objects) {
psyqo::Vec3 cameraPosition, objectPosition;
psyqo::Matrix33 finalMatrix;
::clear<Register::TRX, Safe>();
::clear<Register::TRY, Safe>();
::clear<Register::TRZ, Safe>();
// Rotate the camera Translation vector by the camera rotation
writeSafe<PseudoRegister::Rotation>(m_currentCamera->GetRotation());
writeSafe<PseudoRegister::V0>(-m_currentCamera->GetPosition());
Kernels::mvmva<Kernels::MX::RT, Kernels::MV::V0, Kernels::TV::TR>();
cameraPosition = readSafe<PseudoRegister::SV>();
// Rotate the object Translation vector by the camera rotation
writeSafe<PseudoRegister::V0>(obj->position);
Kernels::mvmva<Kernels::MX::RT, Kernels::MV::V0, Kernels::TV::TR>();
objectPosition = readSafe<PseudoRegister::SV>();
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<psyqo::GTE::PseudoRegister::Translation>(objectPosition);
psyqo::GTE::writeSafe<psyqo::GTE::PseudoRegister::Rotation>(finalMatrix);
for (int i = 0; i < obj->polyCount; i++) {
Tri &tri = obj->polygons[i];
psyqo::Vec3 result;
writeSafe<PseudoRegister::V0>(tri.v0);
writeSafe<PseudoRegister::V1>(tri.v1);
writeSafe<PseudoRegister::V2>(tri.v2);
Kernels::rtpt();
Kernels::nclip();
int32_t mac0 = 0;
read<Register::MAC0>(reinterpret_cast<uint32_t *>(&mac0));
if (mac0 <= 0) continue;
int32_t zIndex = 0;
uint32_t u0, u1, u2;
read<Register::SZ1>(&u0);
read<Register::SZ2>(&u1);
read<Register::SZ3>(&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<Register::SXY0>(&projected[0].packed);
read<Register::SXY1>(&projected[1].packed);
read<Register::SXY2>(&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<psyqo::Vertex, 3> 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<psyqo::Vertex, 3> projected;
for (auto &obj : objects) {
psyqo::Vec3 cameraPosition, objectPosition;
psyqo::Matrix33 finalMatrix;
::clear<Register::TRX, Safe>();
::clear<Register::TRY, Safe>();
@@ -147,229 +69,197 @@ void psxsplash::Renderer::RenderNavmeshPreview(psxsplash::Navmesh navmesh, bool
// Rotate the camera Translation vector by the camera rotation
writeSafe<PseudoRegister::Rotation>(m_currentCamera->GetRotation());
writeSafe<PseudoRegister::V0>(m_currentCamera->GetPosition());
writeSafe<PseudoRegister::V0>(-m_currentCamera->GetPosition());
Kernels::mvmva<Kernels::MX::RT, Kernels::MV::V0, Kernels::TV::TR>();
cameraPosition = readSafe<PseudoRegister::SV>();
write<Register::TRX, Safe>(-cameraPosition.x.raw());
write<Register::TRY, Safe>(-cameraPosition.y.raw());
write<Register::TRZ, Safe>(-cameraPosition.z.raw());
// Rotate the object Translation vector by the camera rotation
writeSafe<PseudoRegister::V0>(obj->position);
Kernels::mvmva<Kernels::MX::RT, Kernels::MV::V0, Kernels::TV::TR>();
objectPosition = readSafe<PseudoRegister::SV>();
psyqo::GTE::writeSafe<psyqo::GTE::PseudoRegister::Rotation>(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<PseudoRegister::V0>(tri.v0);
writeSafe<PseudoRegister::V1>(tri.v1);
writeSafe<PseudoRegister::V2>(tri.v2);
psyqo::GTE::writeSafe<psyqo::GTE::PseudoRegister::Translation>(
objectPosition);
psyqo::GTE::writeSafe<psyqo::GTE::PseudoRegister::Rotation>(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<Register::MAC0>(reinterpret_cast<uint32_t *>(&mac0));
if (mac0 <= 0) continue;
writeSafe<PseudoRegister::V0>(tri.v0);
writeSafe<PseudoRegister::V1>(tri.v1);
writeSafe<PseudoRegister::V2>(tri.v2);
int32_t zIndex = 0;
uint32_t u0, u1, u2;
read<Register::SZ0>(&u0);
read<Register::SZ1>(&u1);
read<Register::SZ2>(&u2);
Kernels::rtpt();
Kernels::nclip();
int32_t sz0 = *reinterpret_cast<int32_t *>(&u0);
int32_t sz1 = *reinterpret_cast<int32_t *>(&u1);
int32_t sz2 = *reinterpret_cast<int32_t *>(&u2);
/*int32_t mac0 = 0;
read<Register::MAC0>(reinterpret_cast<uint32_t *>(&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<Register::SXY0>(&projected[0].packed);
read<Register::SXY1>(&projected[1].packed);
read<Register::SXY2>(&projected[2].packed);
read<Register::SZ1>(&u0);
read<Register::SZ2>(&u1);
read<Register::SZ3>(&u2);
auto &prim = balloc.allocateFragment<psyqo::Prim::Triangle>();
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<Register::SXY0>(&projected[0].packed);
read<Register::SXY1>(&projected[1].packed);
read<Register::SXY2>(&projected[2].packed);
prim.primitive.setColor(heightColor);
prim.primitive.setOpaque();
ot.insert(prim, zIndex);
auto &prim =
balloc.allocateFragment<psyqo::Prim::GouraudTexturedTriangle>();
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<psyqo::Vertex, 3> projected;
auto &ot = m_ots[parity];
auto &clear = m_clear[parity];
auto &balloc = m_ballocs[parity];
balloc.reset();
psyqo::Vec3 cameraPosition;
::clear<Register::TRX, Safe>();
::clear<Register::TRY, Safe>();
::clear<Register::TRZ, Safe>();
// Rotate the camera Translation vector by the camera rotation
writeSafe<PseudoRegister::Rotation>(m_currentCamera->GetRotation());
writeSafe<PseudoRegister::V0>(m_currentCamera->GetPosition());
Kernels::mvmva<Kernels::MX::RT, Kernels::MV::V0, Kernels::TV::TR>();
cameraPosition = readSafe<PseudoRegister::SV>();
write<Register::TRX, Safe>(-cameraPosition.x.raw());
write<Register::TRY, Safe>(-cameraPosition.y.raw());
write<Register::TRZ, Safe>(-cameraPosition.z.raw());
psyqo::GTE::writeSafe<psyqo::GTE::PseudoRegister::Rotation>(
m_currentCamera->GetRotation());
for (int i = 0; i < navmesh.triangleCount; i++) {
NavMeshTri &tri = navmesh.polygons[i];
psyqo::Vec3 result;
writeSafe<PseudoRegister::V0>(tri.v0);
writeSafe<PseudoRegister::V1>(tri.v1);
writeSafe<PseudoRegister::V2>(tri.v2);
Kernels::rtpt();
Kernels::nclip();
int32_t mac0 = 0;
read<Register::MAC0>(reinterpret_cast<uint32_t *>(&mac0));
if (mac0 <= 0)
continue;
int32_t zIndex = 0;
uint32_t u0, u1, u2;
read<Register::SZ0>(&u0);
read<Register::SZ1>(&u1);
read<Register::SZ2>(&u2);
int32_t sz0 = *reinterpret_cast<int32_t *>(&u0);
int32_t sz1 = *reinterpret_cast<int32_t *>(&u1);
int32_t sz2 = *reinterpret_cast<int32_t *>(&u2);
zIndex = eastl::max(eastl::max(sz0, sz1), sz2);
if (zIndex < 0 || zIndex >= ORDERING_TABLE_SIZE)
continue;
read<Register::SXY0>(&projected[0].packed);
read<Register::SXY1>(&projected[1].packed);
read<Register::SXY2>(&projected[2].packed);
auto &prim = balloc.allocateFragment<psyqo::Prim::Triangle>();
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<uint8_t>((a.r + b.r) >> 1), static_cast<uint8_t>((a.g + b.g) >> 1),
static_cast<uint8_t>((a.b + b.b) >> 1)};
return psyqo::Color{static_cast<uint8_t>((a.r + b.r) >> 1),
static_cast<uint8_t>((a.g + b.g) >> 1),
static_cast<uint8_t>((a.b + b.b) >> 1)};
}
void psxsplash::Renderer::recursiveSubdivideAndRender(Tri &tri, eastl::array<psyqo::Vertex, 3> &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<psyqo::Prim::GouraudTexturedTriangle>();
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<psyqo::Vertex, 3> 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);
}

View File

@@ -3,6 +3,7 @@
#include <utility>
#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<psyqo::FixedPoint<12>>(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<psyqo::FixedPoint<12>>(m_playerPosition.x),
static_cast<psyqo::FixedPoint<12>>(m_playerPosition.y),
static_cast<psyqo::FixedPoint<12>>(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();
}

View File

@@ -4,6 +4,7 @@
#include <psyqo/trigonometry.hh>
#include <psyqo/vector.hh>
#include <psyqo/gpu.hh>
#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;