From c67e017772b914ad0b1b2cb8d6f61c58470e81a3 Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Fri, 22 Sep 2017 15:24:00 +0700 Subject: [PATCH] Correct Tri commands for F3DSWRS ucode. Fixed Star Wars: Rogue Squadron HLE glitches. #1584 --- src/GraphicsDrawer.cpp | 9 ++++++++ src/GraphicsDrawer.h | 4 ++++ src/uCodes/F3DSWRS.cpp | 47 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/GraphicsDrawer.cpp b/src/GraphicsDrawer.cpp index b793371f..3f6b3c53 100644 --- a/src/GraphicsDrawer.cpp +++ b/src/GraphicsDrawer.cpp @@ -160,6 +160,13 @@ void GraphicsDrawer::_updateDepthCompare() const } } +SPVertex & GraphicsDrawer::getCurrentDMAVertex() +{ + if (m_dmaVerticesNum >= m_dmaVertices.size()) + m_dmaVertices.resize(std::max(static_cast::size_type>(64), m_dmaVertices.size() * 2)); + return m_dmaVertices[m_dmaVerticesNum++]; +} + inline bool _needAdjustCoordinate(DisplayWindow & _wnd) { @@ -770,6 +777,7 @@ void GraphicsDrawer::drawDMATriangles(u32 _numVtx) triParams.combiner = currentCombiner(); gfxContext.drawTriangles(triParams); g_debugger.addTriangles(triParams); + m_dmaVerticesNum = 0; if (config.frameBufferEmulation.enable != 0) { const f32 maxY = renderTriangles(m_dmaVertices.data(), nullptr, _numVtx); @@ -1633,6 +1641,7 @@ void GraphicsDrawer::_initData() for (auto vtx : triangles.vertices) vtx.w = 1.0f; triangles.num = 0; + m_dmaVerticesNum = 0; } void GraphicsDrawer::_destroyData() diff --git a/src/GraphicsDrawer.h b/src/GraphicsDrawer.h index 68b0b231..899cc1f8 100644 --- a/src/GraphicsDrawer.h +++ b/src/GraphicsDrawer.h @@ -139,6 +139,9 @@ public: SPVertex * getDMAVerticesData() { return m_dmaVertices.data(); } + SPVertex & getCurrentDMAVertex(); + size_t getDMAVerticesCount() const { return m_dmaVerticesNum; } + void updateScissor(FrameBuffer * _pBuffer) const; DrawingState getDrawingState() const { return m_drawingState; } @@ -191,6 +194,7 @@ private: } triangles; std::vector m_dmaVertices; + size_t m_dmaVerticesNum; RectVertex m_rect[4]; diff --git a/src/uCodes/F3DSWRS.cpp b/src/uCodes/F3DSWRS.cpp index 524fd24a..d836c0b3 100644 --- a/src/uCodes/F3DSWRS.cpp +++ b/src/uCodes/F3DSWRS.cpp @@ -1044,6 +1044,38 @@ void F3DSWRS_EndDisplayList(u32, u32) // _updateSWDL(); } +static +void _addVertices(const u32 _vert[3], GraphicsDrawer & _drawer) +{ + if (_drawer.isClipped(_vert[0], _vert[1], _vert[2])) + return; + + SPVertex & vtx0 = _drawer.getVertex(_vert[(((RSP.w1 >> 24) & 3) % 3)]); + + for (u32 i = 0; i < 3; ++i) { + SPVertex & vtx = _drawer.getVertex(_vert[i]); + + if ((gSP.geometryMode & G_SHADE) == 0) { + // Prim shading + vtx.flat_r = gDP.primColor.r; + vtx.flat_g = gDP.primColor.g; + vtx.flat_b = gDP.primColor.b; + vtx.flat_a = gDP.primColor.a; + } else if ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) { + // Flat shading + vtx.r = vtx.flat_r = vtx0.r; + vtx.g = vtx.flat_g = vtx0.g; + vtx.b = vtx.flat_b = vtx0.b; + vtx.a = vtx.flat_a = vtx0.a; + } + + if (gDP.otherMode.depthSource == G_ZS_PRIM) + vtx.z = gDP.primDepth.z * vtx.w; + + _drawer.getCurrentDMAVertex() = vtx; + } +} + void F3DSWRS_Tri1(u32 _w0, u32 _w1) { DebugMsg(DEBUG_NORMAL, "F3DSWRS_Tri1 (0x%08x, 0x%08x)\n", _w0, _w1); @@ -1063,7 +1095,11 @@ void F3DSWRS_Tri1(u32 _w0, u32 _w1) RSP.PC[RSP.PCi] += 16; RSP.nextCmd = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi] + 16], 24, 8); - gSP1Triangle(v1, v2, v3); + GraphicsDrawer & drawer = dwnd().getDrawer(); + _addVertices(vert, drawer); + if (RSP.nextCmd != G_TRI1 && RSP.nextCmd != G_TRI2) + drawer.drawDMATriangles(drawer.getDMAVerticesCount()); + RSP.PC[RSP.PCi] += 8; } @@ -1088,7 +1124,14 @@ void F3DSWRS_Tri2(u32 _w0, u32 _w1) RSP.PC[RSP.PCi] += 16; RSP.nextCmd = _SHIFTR(*(u32*)&RDRAM[RSP.PC[RSP.PCi] + 16], 24, 8); - gSP2Triangles(v1, v2, v3, 0, v1, v3, v4, 0); + GraphicsDrawer & drawer = dwnd().getDrawer(); + const u32 vert1[3] = { v1, v2, v3 }; + _addVertices(vert1, drawer); + const u32 vert2[3] = { v1, v3, v4 }; + _addVertices(vert2, drawer); + if (RSP.nextCmd != G_TRI1 && RSP.nextCmd != G_TRI2) + drawer.drawDMATriangles(drawer.getDMAVerticesCount()); + RSP.PC[RSP.PCi] += 8; }