From 0d46881d7f7cac71ed82e328cf78eb60fc496603 Mon Sep 17 00:00:00 2001 From: jracek Date: Fri, 21 Mar 2025 17:54:25 +0100 Subject: [PATCH] Added splashpack parser, made renderer a singleton --- src/gameobject.hh | 14 +++++++----- src/main.cpp | 6 ++--- src/mesh.hh | 4 ++-- src/renderer.cpp | 55 +++++++++++++++++++++++----------------------- src/renderer.hh | 28 +++++++++++++++++++---- src/splashpack.cpp | 33 ++++++++++++++++++++++++++++ src/splashpack.hh | 23 +++++++++++++++++++ src/texture.hh | 2 +- 8 files changed, 121 insertions(+), 44 deletions(-) create mode 100644 src/splashpack.cpp create mode 100644 src/splashpack.hh diff --git a/src/gameobject.hh b/src/gameobject.hh index 80eb40a..5e8a5a0 100644 --- a/src/gameobject.hh +++ b/src/gameobject.hh @@ -1,6 +1,6 @@ #pragma once -#include "psyqo/trigonometry.hh" +#include "psyqo/matrix.hh" #include "psyqo/vector.hh" #include "mesh.hh" @@ -9,9 +9,13 @@ namespace psxsplash { class GameObject final { public: - psyqo::Vec3 m_pos; - psyqo::Angle m_rot[3]; - Mesh m_mesh; - bool m_is_static; + psyqo::Vec3 position; + psyqo::Matrix33 rotation; + psyqo::PrimPieces::TPageAttr texture; + uint16_t polyCount; + union { + Tri *polygons; + uint32_t polygonsOffset; + }; }; } // namespace psxsplash \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 87f52ed..e11b1cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,8 +18,6 @@ class PSXSplash final : public psyqo::Application { public: psyqo::Font<> m_font; - psxsplash::Renderer m_renderer; - PSXSplash() : m_renderer(gpu()) {} }; class MainScene final : public psyqo::Scene { @@ -39,7 +37,7 @@ void PSXSplash::prepare() { .set(psyqo::GPU::ColorMode::C15BITS) .set(psyqo::GPU::Interlace::PROGRESSIVE); gpu().initialize(config); - m_renderer.initialize(); + psxsplash::Renderer::init(gpu()); } void PSXSplash::createScene() { @@ -47,6 +45,6 @@ void PSXSplash::createScene() { pushScene(&mainScene); } -void MainScene::frame() { psxSplash.m_renderer.render(objects); } +void MainScene::frame() { psxsplash::Renderer::getInstance().render(objects); } int main() { return psxSplash.run(); } diff --git a/src/mesh.hh b/src/mesh.hh index 71c0843..838f36e 100644 --- a/src/mesh.hh +++ b/src/mesh.hh @@ -10,7 +10,7 @@ namespace psxsplash { class Tri final { public: psyqo::GTE::PackedVec3 v0, v1, v2; - psyqo::GTE::PackedVec3 n0, n1, n2; + psyqo::GTE::PackedVec3 normal; psyqo::PrimPieces::UVCoords uvA, uvB; psyqo::PrimPieces::UVCoordsPadded uvC; psyqo::Color colorA, colorB, colorC; @@ -21,4 +21,4 @@ class Mesh final { Texture m_texture; eastl::array m_polygons; }; -} // namespace psxsplash \ No newline at end of file +} // namespace psxsplash diff --git a/src/renderer.cpp b/src/renderer.cpp index c97e143..d53564e 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1,12 +1,13 @@ -#include - -#include "psyqo/primitives/triangles.hh" - -#include "gameobject.hh" -#include "psyqo/soft-math.hh" #include "renderer.hh" -void psxsplash::Renderer::initialize() { +#include "psyqo/gte-kernels.hh" +#include "psyqo/primitives/triangles.hh" + +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::GTE::clear(); psyqo::GTE::clear(); psyqo::GTE::clear(); @@ -22,8 +23,14 @@ void psxsplash::Renderer::initialize() { ORDERING_TABLE_SIZE / 3); psyqo::GTE::write( ORDERING_TABLE_SIZE / 4); + + if(!instance) { + instance = new Renderer(gpuInstance); + } } + + void psxsplash::Renderer::render(eastl::array &objects) { uint8_t parity = m_gpu.getParity(); @@ -40,32 +47,19 @@ void psxsplash::Renderer::render(eastl::array &objects) { for (auto &obj : objects) { - auto &mesh = obj.m_mesh; - auto &texture = mesh.m_texture; - psyqo::GTE::write( - obj.m_pos.x.raw()); + obj.position.x.raw()); psyqo::GTE::write( - obj.m_pos.y.raw()); + obj.position.y.raw()); psyqo::GTE::write( - obj.m_pos.z.raw()); - - auto transform = psyqo::SoftMath::generateRotationMatrix33( - obj.m_rot[0], psyqo::SoftMath::Axis::X, m_trig); - auto rot = psyqo::SoftMath::generateRotationMatrix33( - obj.m_rot[1], psyqo::SoftMath::Axis::Y, m_trig); - - psyqo::SoftMath::multiplyMatrix33(transform, rot, &transform); - - auto rotZ = psyqo::SoftMath::generateRotationMatrix33( - obj.m_rot[2], psyqo::SoftMath::Axis::Z, m_trig); - - psyqo::SoftMath::multiplyMatrix33(transform, rotZ, &transform); + obj.position.z.raw()); psyqo::GTE::writeUnsafe( - transform); + obj.rotation); - for (auto &tri : mesh.m_polygons) { + for (int i = 0; i < obj.polyCount; i++) { + + Tri& tri = obj.polygons[i]; psyqo::GTE::writeUnsafe(tri.v0); psyqo::GTE::writeUnsafe(tri.v1); @@ -100,11 +94,16 @@ void psxsplash::Renderer::render(eastl::array &objects) { prim.primitive.uvA = tri.uvA; prim.primitive.uvB = tri.uvB; prim.primitive.uvC = tri.uvC; - prim.primitive.tpage = texture.m_tpage; + prim.primitive.tpage = obj.texture; ot.insert(prim, zIndex); } } 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); } \ No newline at end of file diff --git a/src/renderer.hh b/src/renderer.hh index 172d2a8..aa14c4b 100644 --- a/src/renderer.hh +++ b/src/renderer.hh @@ -9,25 +9,45 @@ #include "psyqo/primitives/common.hh" #include "psyqo/primitives/misc.hh" #include "psyqo/trigonometry.hh" +#include "psyqo/kernel.hh" +#include namespace psxsplash { class Renderer final { + + public: + Renderer(const Renderer&) = delete; + Renderer& operator=(const Renderer&) = delete; + static constexpr size_t ORDERING_TABLE_SIZE = 1024; static constexpr size_t BUMP_ALLOCATOR_SIZE = 100000; + static void init(psyqo::GPU &gpuInstance); + + void render(eastl::array &objects); + void vramUpload(const uint16_t* imageData, int16_t posX, int16_t posY, int16_t width, int16_t height); + + static Renderer& getInstance() { + psyqo::Kernel::assert(instance != nullptr, "Access to renderer was tried without prior initialization"); + return *instance; + } + + private: + static Renderer* instance; + + Renderer(psyqo::GPU &gpuInstance) : m_gpu(gpuInstance) {} + ~Renderer() { } + psyqo::GPU &m_gpu; psyqo::Trig<> m_trig; - public: psyqo::OrderingTable m_ots[2]; psyqo::Fragments::SimpleFragment m_clear[2]; psyqo::Color m_clearcolor = {.r = 63, .g = 63, .b = 63}; psyqo::BumpAllocator m_ballocs[2]; - Renderer(psyqo::GPU &gpuInstance) : m_gpu(gpuInstance) {} - void initialize(); - void render(eastl::array &objects); }; + } // namespace psxsplash \ No newline at end of file diff --git a/src/splashpack.cpp b/src/splashpack.cpp new file mode 100644 index 0000000..817838a --- /dev/null +++ b/src/splashpack.cpp @@ -0,0 +1,33 @@ +#include "splashpack.hh" +#include "gameobject.hh" +#include "mesh.hh" +#include "renderer.hh" +#include +#include +#include + +eastl::vector LoadSplashpack(uint8_t *data) { + assert(data != nullptr); + psxsplash::SPLASHPACKFileHeader *header = + reinterpret_cast(data); + assert(memcmp(header->magic, "SP", 10) == 0); + + eastl::vector gameObjects; + gameObjects.reserve(header->gameObjectCount); + + uint8_t* curentPointer = data += sizeof(psxsplash::SPLASHPACKFileHeader); + + for(uint16_t i = 0; i < header->gameObjectCount; i++) { + psxsplash::GameObject* go = reinterpret_cast(curentPointer); + go->polygons = reinterpret_cast(data += go->polygonsOffset); + gameObjects.push_back(go); + curentPointer += sizeof(psxsplash::GameObject); + } + + for(uint16_t i = 0; i < header->textureAtlasCount; i++) { + psxsplash::SPLASHPACKTextureAtlas* atlas = reinterpret_cast(curentPointer); + psxsplash::Renderer::getInstance().vramUpload((uint16_t*) (data += atlas->polygonsOffset), atlas->x, atlas->y, atlas->width, atlas->height); + } + + return gameObjects; +} diff --git a/src/splashpack.hh b/src/splashpack.hh new file mode 100644 index 0000000..fcdb145 --- /dev/null +++ b/src/splashpack.hh @@ -0,0 +1,23 @@ +#pragma once + +#include "EASTL/vector.h" +#include "gameobject.hh" +#include +namespace psxsplash { + +struct SPLASHPACKFileHeader { + char magic[2]; + uint16_t version; + uint16_t gameObjectCount; + uint16_t textureAtlasCount; +}; + +struct SPLASHPACKTextureAtlas { + uint32_t polygonsOffset; + uint16_t width, height; + uint16_t x,y; +}; + +eastl::vector LoadSplashpack(const uint8_t *data); + +}; // namespace psxsplash \ No newline at end of file diff --git a/src/texture.hh b/src/texture.hh index c1dc616..942b08a 100644 --- a/src/texture.hh +++ b/src/texture.hh @@ -7,8 +7,8 @@ namespace psxsplash { class Texture final { public: - psyqo::Prim::TPageAttr::ColorMode m_colormode; psyqo::PrimPieces::TPageAttr m_tpage; uint8_t m_width, m_height; }; + } // namespace psxsplash \ No newline at end of file