From 9fe24cb1e7b2cb9b77ff1a6ce4b0ba9bf052f347 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Tue, 9 May 2017 22:22:52 +0200 Subject: [PATCH] latch 3D registers upon VBlank (fixes the last bugs in Gericom's train game) --- src/GPU3D.cpp | 44 +++++++++++++++++++++++++++++++++++--------- src/GPU3D.h | 14 +++++++++----- src/GPU3D_Soft.cpp | 12 ++++++------ src/wx/Platform.cpp | 2 +- 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 0f700d96..4d9eca3c 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -60,7 +60,16 @@ // // viewport Y coordinates are upside-down // -// clear color/depth/bitmap/etc registers (04000350/04000354) are double-buffered +// several registers are latched upon VBlank, the renderer uses the latched registers +// latched registers include: +// DISP3DCNT +// alpha test ref value +// fog color, offset, density table +// toon table +// edge table +// clear attributes +// +// TODO: check how DISP_1DOT_DEPTH works and whether it's latched namespace GPU3D @@ -153,16 +162,27 @@ FIFO* CmdPIPE; u32 NumCommands, CurCommand, ParamCount, TotalParams; u32 DispCnt; -u8 AlphaRefVal; -u8 AlphaRef; +u8 AlphaRefVal, AlphaRef; u16 ToonTable[32]; u16 EdgeTable[8]; -u32 FogColor; -u32 FogOffset; +u32 FogColor, FogOffset; u8 FogDensityTable[32]; +u32 ClearAttr1, ClearAttr2; + +u32 RenderDispCnt; +u8 RenderAlphaRef; + +u16 RenderToonTable[32]; +u16 RenderEdgeTable[8]; + +u32 RenderFogColor, RenderFogOffset; +u8 RenderFogDensityTable[32]; + +u32 RenderClearAttr1, RenderClearAttr2; + u32 GXStat; u32 ExecParams[32]; @@ -241,9 +261,6 @@ Vertex* RenderVertexRAM; Polygon* RenderPolygonRAM; u32 RenderNumPolygons; -u32 ClearAttr1, ClearAttr2; -u32 RenderClearAttr1, RenderClearAttr2; - u32 FlushRequest; u32 FlushAttributes; @@ -1790,7 +1807,16 @@ void VBlank() RenderPolygonRAM = CurPolygonRAM; RenderNumPolygons = NumPolygons; - // TODO: find out which other registers are latched for rendering + RenderDispCnt = DispCnt; + RenderAlphaRef = AlphaRef; + + memcpy(RenderEdgeTable, EdgeTable, 8*2); + memcpy(RenderToonTable, ToonTable, 32*2); + + RenderFogColor = FogColor; + RenderFogOffset = FogOffset; + memcpy(RenderFogDensityTable, FogDensityTable, 32); + RenderClearAttr1 = ClearAttr1; RenderClearAttr2 = ClearAttr2; diff --git a/src/GPU3D.h b/src/GPU3D.h index fdb85f8c..ae246589 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -65,12 +65,16 @@ typedef struct } Polygon; -extern u32 DispCnt; -extern u8 AlphaRef; -extern s32 Viewport[4]; -extern u32 RenderClearAttr1, RenderClearAttr2; +extern u32 RenderDispCnt; +extern u8 RenderAlphaRef; -extern u16 ToonTable[32]; +extern u16 RenderToonTable[32]; +extern u16 RenderEdgeTable[8]; + +extern u32 RenderFogColor, RenderFogOffset; +extern u8 RenderFogDensityTable[32]; + +extern u32 RenderClearAttr1, RenderClearAttr2; bool Init(); void DeInit(); diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp index 55dd9061..67d797d1 100644 --- a/src/GPU3D_Soft.cpp +++ b/src/GPU3D_Soft.cpp @@ -549,14 +549,14 @@ u32 RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16 t) if (blendmode == 2) { - u16 tooncolor = ToonTable[vr >> 1]; + u16 tooncolor = RenderToonTable[vr >> 1]; vr = (tooncolor << 1) & 0x3E; if (vr) vr++; vg = (tooncolor >> 4) & 0x3E; if (vg) vg++; vb = (tooncolor >> 9) & 0x3E; if (vb) vb++; } - if ((DispCnt & (1<<0)) && (((polygon->TexParam >> 26) & 0x7) != 0)) + if ((RenderDispCnt & (1<<0)) && (((polygon->TexParam >> 26) & 0x7) != 0)) { u8 tr, tg, tb; @@ -609,7 +609,7 @@ u32 RenderPixel(Polygon* polygon, u8 vr, u8 vg, u8 vb, s16 s, s16 t) a = polyalpha; } - if ((blendmode == 2) && (DispCnt & (1<<1))) + if ((blendmode == 2) && (RenderDispCnt & (1<<1))) { r += vr; g += vg; @@ -968,7 +968,7 @@ void RenderPolygon(Polygon* polygon) // alpha test // TODO: check alpha test when blending is disabled - if (alpha <= AlphaRef) continue; + if (alpha <= RenderAlphaRef) continue; if (alpha == 31) { @@ -1001,7 +1001,7 @@ void RenderPolygon(Polygon* polygon) u32 dstcolor = ColorBuffer[pixeladdr]; u32 dstalpha = dstcolor >> 24; - if ((dstalpha > 0) && (DispCnt & (1<<3))) + if ((dstalpha > 0) && (RenderDispCnt & (1<<3))) { u32 srcR = color & 0x3F; u32 srcG = (color >> 8) & 0x3F; @@ -1039,7 +1039,7 @@ void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys) { u32 polyid = RenderClearAttr1 & 0x3F000000; - if (DispCnt & (1<<14)) + if (RenderDispCnt & (1<<14)) { u8 xoff = (RenderClearAttr2 >> 16) & 0xFF; u8 yoff = (RenderClearAttr2 >> 24) & 0xFF; diff --git a/src/wx/Platform.cpp b/src/wx/Platform.cpp index 8bcbb7ed..482b886f 100644 --- a/src/wx/Platform.cpp +++ b/src/wx/Platform.cpp @@ -17,7 +17,7 @@ */ #include -#include "Platform.h" +#include "../Platform.h" namespace Platform