From 5e8b836e8343ffd5e672ea38df7b8f5fc531925d Mon Sep 17 00:00:00 2001 From: rogerman Date: Sun, 13 Sep 2015 03:01:56 +0000 Subject: [PATCH] GPU: - Parse necessary registers upon loading state to ensure that internal variables get set properly. --- desmume/src/GPU.cpp | 26 +++++++++++++++++-- desmume/src/GPU.h | 2 ++ desmume/src/gfx3d.cpp | 60 ++++++++++++++++++++++++------------------- desmume/src/gfx3d.h | 6 +++-- 4 files changed, 63 insertions(+), 31 deletions(-) diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index 212b06890..33a2dd28f 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -221,8 +221,9 @@ bool gpu_loadstate(EMUFILE* is, int size) //subEngine->refreshAffineStartRegs(-1,-1); } - mainEngine->ParseReg_BLDALPHA(); - subEngine->ParseReg_BLDALPHA(); + mainEngine->ParseAllRegisters(); + subEngine->ParseAllRegisters(); + return !is->fail(); } @@ -2703,6 +2704,27 @@ void GPUEngineBase::REG_DISPx_pack_test() printf("\t%02x\n", (u32)((uintptr_t)(&r->DISP_MMEM_FIFO) - (uintptr_t)r) ); } +void GPUEngineBase::ParseAllRegisters() +{ + this->ParseReg_DISPCNT(); + // No need to call ParseReg_BGnCNT(), since it is + // already called by ParseReg_DISPCNT(). + + this->ParseReg_BGnX(); + this->ParseReg_BGnY(); + this->ParseReg_BGnX(); + this->ParseReg_BGnY(); + + this->ParseReg_WINnH<0>(); + this->ParseReg_WINnH<1>(); + + this->ParseReg_MOSAIC(); + this->ParseReg_BLDCNT(); + this->ParseReg_BLDALPHA(); + this->ParseReg_BLDY(); + this->ParseReg_MASTER_BRIGHT(); +} + GPUEngineA::GPUEngineA() { _engineID = GPUEngineID_Main; diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index cc5c80f00..b502c2c04 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -1173,6 +1173,8 @@ public: void ParseReg_BLDY(); void ParseReg_MASTER_BRIGHT(); + void ParseAllRegisters(); + template void RenderLine(const u16 l, bool skip); u16 BGSize[4][2]; diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 57aa36460..5bc8062f9 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -553,7 +553,7 @@ void gfx3d_init() vertlist = &vertlists[0]; } - gfx3d.state.currentDISP3DCNT.value = 0; + gfx3d.state.savedDISP3DCNT.value = 0; gfx3d.state.fogDensityTable = MMU.ARM9_REG+0x0360; gfx3d.state.edgeMarkColorTable = (u16 *)(MMU.ARM9_REG+0x0330); @@ -2383,29 +2383,6 @@ void gfx3d_sendCommand(u32 cmd, u32 param) } } -void ParseReg_DISP3DCNT() -{ - const IOREG_DISP3DCNT &DISP3DCNT = GPU->GetEngineMain()->GetIORegisterMap().DISP3DCNT; - - if (gfx3d.state.currentDISP3DCNT.value == DISP3DCNT.value) - { - return; - } - - gfx3d.state.currentDISP3DCNT.value = DISP3DCNT.value; - - gfx3d.state.enableTexturing = (DISP3DCNT.EnableTexMapping != 0); - gfx3d.state.shading = DISP3DCNT.PolygonShading; - gfx3d.state.enableAlphaTest = (DISP3DCNT.EnableAlphaTest != 0); - gfx3d.state.enableAlphaBlending = (DISP3DCNT.EnableAlphaBlending != 0); - gfx3d.state.enableAntialiasing = (DISP3DCNT.EnableAntiAliasing != 0); - gfx3d.state.enableEdgeMarking = (DISP3DCNT.EnableEdgeMarking != 0); - gfx3d.state.enableFogAlphaOnly = (DISP3DCNT.FogOnlyAlpha != 0); - gfx3d.state.enableFog = (DISP3DCNT.EnableFog != 0); - gfx3d.state.fogShift = DISP3DCNT.FogShiftSHR; - gfx3d.state.enableClearImage = (DISP3DCNT.RearPlaneMode != 0); -} - //-------------- //other misc stuff void gfx3d_glGetMatrix(const MatrixMode m_mode, int index, float *dst) @@ -2439,7 +2416,7 @@ void gfx3d_glGetLightColor(const size_t index, u32 &dst) //consider building a little state structure that looks exactly like this describes SFORMAT SF_GFX3D[]={ - { "GCTL", 4, 1, &MMU.ARM9_REG[0x0060]}, + { "GCTL", 4, 1, &gfx3d.state.savedDISP3DCNT}, { "GPAT", 4, 1, &polyAttr}, { "GPAP", 4, 1, &polyAttrPending}, { "GINB", 4, 1, &inBegin}, @@ -2578,8 +2555,8 @@ bool gfx3d_loadstate(EMUFILE* is, int size) listTwiddle = 0; polylist = &polylists[listTwiddle]; vertlist = &vertlists[listTwiddle]; - - gfx3d.state.currentDISP3DCNT.value = MMU.ARM9_REG[0x0060]; + + gfx3d_parseCurrentDISP3DCNT(); if (version >= 1) { @@ -2620,6 +2597,35 @@ bool gfx3d_loadstate(EMUFILE* is, int size) return true; } +void gfx3d_parseCurrentDISP3DCNT() +{ + const IOREG_DISP3DCNT &DISP3DCNT = gfx3d.state.savedDISP3DCNT; + + gfx3d.state.enableTexturing = (DISP3DCNT.EnableTexMapping != 0); + gfx3d.state.shading = DISP3DCNT.PolygonShading; + gfx3d.state.enableAlphaTest = (DISP3DCNT.EnableAlphaTest != 0); + gfx3d.state.enableAlphaBlending = (DISP3DCNT.EnableAlphaBlending != 0); + gfx3d.state.enableAntialiasing = (DISP3DCNT.EnableAntiAliasing != 0); + gfx3d.state.enableEdgeMarking = (DISP3DCNT.EnableEdgeMarking != 0); + gfx3d.state.enableFogAlphaOnly = (DISP3DCNT.FogOnlyAlpha != 0); + gfx3d.state.enableFog = (DISP3DCNT.EnableFog != 0); + gfx3d.state.fogShift = DISP3DCNT.FogShiftSHR; + gfx3d.state.enableClearImage = (DISP3DCNT.RearPlaneMode != 0); +} + +void ParseReg_DISP3DCNT() +{ + const IOREG_DISP3DCNT &DISP3DCNT = GPU->GetEngineMain()->GetIORegisterMap().DISP3DCNT; + + if (gfx3d.state.savedDISP3DCNT.value == DISP3DCNT.value) + { + return; + } + + gfx3d.state.savedDISP3DCNT.value = DISP3DCNT.value; + gfx3d_parseCurrentDISP3DCNT(); +} + //------------------- //clipping //------------------- diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index 6583ceb14..fde12857c 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -665,7 +665,7 @@ struct GFX3D_State u16ToonTable[i] = 0; } - IOREG_DISP3DCNT currentDISP3DCNT; + IOREG_DISP3DCNT savedDISP3DCNT; BOOL enableTexturing, enableAlphaTest, enableAlphaBlending, enableAntialiasing, enableEdgeMarking, enableClearImage, enableFog, enableFogAlphaOnly; @@ -768,7 +768,6 @@ u32 gfx3d_glGetPosRes(const size_t index); u16 gfx3d_glGetVecRes(const size_t index); void gfx3d_VBlankSignal(); void gfx3d_VBlankEndSignal(bool skipFrame); -void ParseReg_DISP3DCNT(); void gfx3d_execute3D(); void gfx3d_sendCommandToFIFO(u32 val); void gfx3d_sendCommand(u32 cmd, u32 param); @@ -786,4 +785,7 @@ bool gfx3d_loadstate(EMUFILE* is, int size); void gfx3d_ClearStack(); +void gfx3d_parseCurrentDISP3DCNT(); +void ParseReg_DISP3DCNT(); + #endif //_GFX3D_H_