#include "renderer.hh" #include "EASTL/vector.h" #include "psyqo/fixed-point.hh" #include "psyqo/gte-kernels.hh" #include "psyqo/gte-registers.hh" #include "psyqo/primitives/common.hh" #include "psyqo/primitives/triangles.hh" #include "psyqo/soft-math.hh" #include "psyqo/trigonometry.hh" using namespace psyqo::fixed_point_literals; using namespace psyqo::trig_literals; 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(); psyqo::GTE::write( psyqo::FixedPoint<16>(160.0).raw()); psyqo::GTE::write( psyqo::FixedPoint<16>(120.0).raw()); psyqo::GTE::write(120); psyqo::GTE::write( ORDERING_TABLE_SIZE / 3); psyqo::GTE::write( ORDERING_TABLE_SIZE / 4); if (!instance) { instance = new Renderer(gpuInstance); } } void psxsplash::Renderer::render(eastl::vector &objects) { uint8_t parity = m_gpu.getParity(); auto &ot = m_ots[parity]; auto &clear = m_clear[parity]; auto &balloc = m_ballocs[parity]; eastl::array projected; m_gpu.getNextClear(clear.primitive, m_clearcolor); m_gpu.chain(clear); balloc.reset(); for (auto &obj : objects) { auto transform = psyqo::SoftMath::generateRotationMatrix33( 0, psyqo::SoftMath::Axis::X, m_trig); psyqo::GTE::writeUnsafe( transform); for (int i = 0; i < obj->polyCount; i++) { Tri &tri = obj->polygons[i]; psyqo::GTE::writeUnsafe(tri.v0); psyqo::GTE::writeUnsafe(tri.v1); psyqo::GTE::writeUnsafe(tri.v2); psyqo::GTE::Kernels::rtpt(); psyqo::GTE::Kernels::nclip(); int32_t mac0 = 0; psyqo::GTE::read( reinterpret_cast(&mac0)); if (mac0 <= 0) continue; psyqo::GTE::Kernels::avsz3(); int32_t zIndex = 0; psyqo::GTE::read( reinterpret_cast(&zIndex)); if (zIndex < 0 || zIndex >= ORDERING_TABLE_SIZE) continue; psyqo::GTE::read(&projected[0].packed); psyqo::GTE::read(&projected[1].packed); psyqo::GTE::read(&projected[2].packed); auto &prim = balloc.allocateFragment(); psyqo::PrimPieces::ClutIndex clut(obj->clutX, obj->clutY); 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 = obj->texture; prim.primitive.clutIndex = clut; prim.primitive.setColorA(tri.colorA); prim.primitive.setColorB(tri.colorB); prim.primitive.setColorC(tri.colorC); prim.primitive.setOpaque(); 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); }