Added splashpack parser, made renderer a singleton
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "psyqo/trigonometry.hh"
|
#include "psyqo/matrix.hh"
|
||||||
#include "psyqo/vector.hh"
|
#include "psyqo/vector.hh"
|
||||||
|
|
||||||
#include "mesh.hh"
|
#include "mesh.hh"
|
||||||
@@ -9,9 +9,13 @@ namespace psxsplash {
|
|||||||
|
|
||||||
class GameObject final {
|
class GameObject final {
|
||||||
public:
|
public:
|
||||||
psyqo::Vec3 m_pos;
|
psyqo::Vec3 position;
|
||||||
psyqo::Angle m_rot[3];
|
psyqo::Matrix33 rotation;
|
||||||
Mesh m_mesh;
|
psyqo::PrimPieces::TPageAttr texture;
|
||||||
bool m_is_static;
|
uint16_t polyCount;
|
||||||
|
union {
|
||||||
|
Tri *polygons;
|
||||||
|
uint32_t polygonsOffset;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
} // namespace psxsplash
|
} // namespace psxsplash
|
||||||
@@ -18,8 +18,6 @@ class PSXSplash final : public psyqo::Application {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
psyqo::Font<> m_font;
|
psyqo::Font<> m_font;
|
||||||
psxsplash::Renderer m_renderer;
|
|
||||||
PSXSplash() : m_renderer(gpu()) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MainScene final : public psyqo::Scene {
|
class MainScene final : public psyqo::Scene {
|
||||||
@@ -39,7 +37,7 @@ void PSXSplash::prepare() {
|
|||||||
.set(psyqo::GPU::ColorMode::C15BITS)
|
.set(psyqo::GPU::ColorMode::C15BITS)
|
||||||
.set(psyqo::GPU::Interlace::PROGRESSIVE);
|
.set(psyqo::GPU::Interlace::PROGRESSIVE);
|
||||||
gpu().initialize(config);
|
gpu().initialize(config);
|
||||||
m_renderer.initialize();
|
psxsplash::Renderer::init(gpu());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PSXSplash::createScene() {
|
void PSXSplash::createScene() {
|
||||||
@@ -47,6 +45,6 @@ void PSXSplash::createScene() {
|
|||||||
pushScene(&mainScene);
|
pushScene(&mainScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainScene::frame() { psxSplash.m_renderer.render(objects); }
|
void MainScene::frame() { psxsplash::Renderer::getInstance().render(objects); }
|
||||||
|
|
||||||
int main() { return psxSplash.run(); }
|
int main() { return psxSplash.run(); }
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace psxsplash {
|
|||||||
class Tri final {
|
class Tri final {
|
||||||
public:
|
public:
|
||||||
psyqo::GTE::PackedVec3 v0, v1, v2;
|
psyqo::GTE::PackedVec3 v0, v1, v2;
|
||||||
psyqo::GTE::PackedVec3 n0, n1, n2;
|
psyqo::GTE::PackedVec3 normal;
|
||||||
psyqo::PrimPieces::UVCoords uvA, uvB;
|
psyqo::PrimPieces::UVCoords uvA, uvB;
|
||||||
psyqo::PrimPieces::UVCoordsPadded uvC;
|
psyqo::PrimPieces::UVCoordsPadded uvC;
|
||||||
psyqo::Color colorA, colorB, colorC;
|
psyqo::Color colorA, colorB, colorC;
|
||||||
@@ -21,4 +21,4 @@ class Mesh final {
|
|||||||
Texture m_texture;
|
Texture m_texture;
|
||||||
eastl::array<Tri> m_polygons;
|
eastl::array<Tri> m_polygons;
|
||||||
};
|
};
|
||||||
} // namespace psxsplash
|
} // namespace psxsplash
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "psyqo/primitives/triangles.hh"
|
|
||||||
|
|
||||||
#include "gameobject.hh"
|
|
||||||
#include "psyqo/soft-math.hh"
|
|
||||||
#include "renderer.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::Register::TRX, psyqo::GTE::Unsafe>();
|
psyqo::GTE::clear<psyqo::GTE::Register::TRX, psyqo::GTE::Unsafe>();
|
||||||
psyqo::GTE::clear<psyqo::GTE::Register::TRY, psyqo::GTE::Unsafe>();
|
psyqo::GTE::clear<psyqo::GTE::Register::TRY, psyqo::GTE::Unsafe>();
|
||||||
psyqo::GTE::clear<psyqo::GTE::Register::TRZ, psyqo::GTE::Unsafe>();
|
psyqo::GTE::clear<psyqo::GTE::Register::TRZ, psyqo::GTE::Unsafe>();
|
||||||
@@ -22,8 +23,14 @@ void psxsplash::Renderer::initialize() {
|
|||||||
ORDERING_TABLE_SIZE / 3);
|
ORDERING_TABLE_SIZE / 3);
|
||||||
psyqo::GTE::write<psyqo::GTE::Register::ZSF4, psyqo::GTE::Unsafe>(
|
psyqo::GTE::write<psyqo::GTE::Register::ZSF4, psyqo::GTE::Unsafe>(
|
||||||
ORDERING_TABLE_SIZE / 4);
|
ORDERING_TABLE_SIZE / 4);
|
||||||
|
|
||||||
|
if(!instance) {
|
||||||
|
instance = new Renderer(gpuInstance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void psxsplash::Renderer::render(eastl::array<GameObject> &objects) {
|
void psxsplash::Renderer::render(eastl::array<GameObject> &objects) {
|
||||||
uint8_t parity = m_gpu.getParity();
|
uint8_t parity = m_gpu.getParity();
|
||||||
|
|
||||||
@@ -40,32 +47,19 @@ void psxsplash::Renderer::render(eastl::array<GameObject> &objects) {
|
|||||||
|
|
||||||
for (auto &obj : objects) {
|
for (auto &obj : objects) {
|
||||||
|
|
||||||
auto &mesh = obj.m_mesh;
|
|
||||||
auto &texture = mesh.m_texture;
|
|
||||||
|
|
||||||
psyqo::GTE::write<psyqo::GTE::Register::TRX, psyqo::GTE::Unsafe>(
|
psyqo::GTE::write<psyqo::GTE::Register::TRX, psyqo::GTE::Unsafe>(
|
||||||
obj.m_pos.x.raw());
|
obj.position.x.raw());
|
||||||
psyqo::GTE::write<psyqo::GTE::Register::TRY, psyqo::GTE::Unsafe>(
|
psyqo::GTE::write<psyqo::GTE::Register::TRY, psyqo::GTE::Unsafe>(
|
||||||
obj.m_pos.y.raw());
|
obj.position.y.raw());
|
||||||
psyqo::GTE::write<psyqo::GTE::Register::TRZ, psyqo::GTE::Unsafe>(
|
psyqo::GTE::write<psyqo::GTE::Register::TRZ, psyqo::GTE::Unsafe>(
|
||||||
obj.m_pos.z.raw());
|
obj.position.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);
|
|
||||||
|
|
||||||
psyqo::GTE::writeUnsafe<psyqo::GTE::PseudoRegister::Rotation>(
|
psyqo::GTE::writeUnsafe<psyqo::GTE::PseudoRegister::Rotation>(
|
||||||
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<psyqo::GTE::PseudoRegister::V0>(tri.v0);
|
psyqo::GTE::writeUnsafe<psyqo::GTE::PseudoRegister::V0>(tri.v0);
|
||||||
psyqo::GTE::writeUnsafe<psyqo::GTE::PseudoRegister::V1>(tri.v1);
|
psyqo::GTE::writeUnsafe<psyqo::GTE::PseudoRegister::V1>(tri.v1);
|
||||||
@@ -100,11 +94,16 @@ void psxsplash::Renderer::render(eastl::array<GameObject> &objects) {
|
|||||||
prim.primitive.uvA = tri.uvA;
|
prim.primitive.uvA = tri.uvA;
|
||||||
prim.primitive.uvB = tri.uvB;
|
prim.primitive.uvB = tri.uvB;
|
||||||
prim.primitive.uvC = tri.uvC;
|
prim.primitive.uvC = tri.uvC;
|
||||||
prim.primitive.tpage = texture.m_tpage;
|
prim.primitive.tpage = obj.texture;
|
||||||
|
|
||||||
ot.insert(prim, zIndex);
|
ot.insert(prim, zIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_gpu.chain(ot);
|
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);
|
||||||
}
|
}
|
||||||
@@ -9,25 +9,45 @@
|
|||||||
#include "psyqo/primitives/common.hh"
|
#include "psyqo/primitives/common.hh"
|
||||||
#include "psyqo/primitives/misc.hh"
|
#include "psyqo/primitives/misc.hh"
|
||||||
#include "psyqo/trigonometry.hh"
|
#include "psyqo/trigonometry.hh"
|
||||||
|
#include "psyqo/kernel.hh"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace psxsplash {
|
namespace psxsplash {
|
||||||
|
|
||||||
class Renderer final {
|
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 ORDERING_TABLE_SIZE = 1024;
|
||||||
static constexpr size_t BUMP_ALLOCATOR_SIZE = 100000;
|
static constexpr size_t BUMP_ALLOCATOR_SIZE = 100000;
|
||||||
|
|
||||||
|
static void init(psyqo::GPU &gpuInstance);
|
||||||
|
|
||||||
|
void render(eastl::array<GameObject> &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::GPU &m_gpu;
|
||||||
psyqo::Trig<> m_trig;
|
psyqo::Trig<> m_trig;
|
||||||
|
|
||||||
public:
|
|
||||||
psyqo::OrderingTable<ORDERING_TABLE_SIZE> m_ots[2];
|
psyqo::OrderingTable<ORDERING_TABLE_SIZE> m_ots[2];
|
||||||
psyqo::Fragments::SimpleFragment<psyqo::Prim::FastFill> m_clear[2];
|
psyqo::Fragments::SimpleFragment<psyqo::Prim::FastFill> m_clear[2];
|
||||||
psyqo::Color m_clearcolor = {.r = 63, .g = 63, .b = 63};
|
psyqo::Color m_clearcolor = {.r = 63, .g = 63, .b = 63};
|
||||||
psyqo::BumpAllocator<BUMP_ALLOCATOR_SIZE> m_ballocs[2];
|
psyqo::BumpAllocator<BUMP_ALLOCATOR_SIZE> m_ballocs[2];
|
||||||
|
|
||||||
Renderer(psyqo::GPU &gpuInstance) : m_gpu(gpuInstance) {}
|
|
||||||
void initialize();
|
|
||||||
void render(eastl::array<GameObject> &objects);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace psxsplash
|
} // namespace psxsplash
|
||||||
33
src/splashpack.cpp
Normal file
33
src/splashpack.cpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#include "splashpack.hh"
|
||||||
|
#include "gameobject.hh"
|
||||||
|
#include "mesh.hh"
|
||||||
|
#include "renderer.hh"
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
eastl::vector<psxsplash::GameObject*> LoadSplashpack(uint8_t *data) {
|
||||||
|
assert(data != nullptr);
|
||||||
|
psxsplash::SPLASHPACKFileHeader *header =
|
||||||
|
reinterpret_cast<psxsplash::SPLASHPACKFileHeader *>(data);
|
||||||
|
assert(memcmp(header->magic, "SP", 10) == 0);
|
||||||
|
|
||||||
|
eastl::vector<psxsplash::GameObject*> 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<psxsplash::GameObject*>(curentPointer);
|
||||||
|
go->polygons = reinterpret_cast<psxsplash::Tri*>(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<psxsplash::SPLASHPACKTextureAtlas *>(curentPointer);
|
||||||
|
psxsplash::Renderer::getInstance().vramUpload((uint16_t*) (data += atlas->polygonsOffset), atlas->x, atlas->y, atlas->width, atlas->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gameObjects;
|
||||||
|
}
|
||||||
23
src/splashpack.hh
Normal file
23
src/splashpack.hh
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "EASTL/vector.h"
|
||||||
|
#include "gameobject.hh"
|
||||||
|
#include <cstdint>
|
||||||
|
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<GameObject> LoadSplashpack(const uint8_t *data);
|
||||||
|
|
||||||
|
}; // namespace psxsplash
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
namespace psxsplash {
|
namespace psxsplash {
|
||||||
class Texture final {
|
class Texture final {
|
||||||
public:
|
public:
|
||||||
psyqo::Prim::TPageAttr::ColorMode m_colormode;
|
|
||||||
psyqo::PrimPieces::TPageAttr m_tpage;
|
psyqo::PrimPieces::TPageAttr m_tpage;
|
||||||
uint8_t m_width, m_height;
|
uint8_t m_width, m_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace psxsplash
|
} // namespace psxsplash
|
||||||
Reference in New Issue
Block a user