From 183dd57136b4342eb81b9bc3f3a5be140a483935 Mon Sep 17 00:00:00 2001 From: rogerman Date: Wed, 18 May 2022 10:32:06 -0700 Subject: [PATCH] GPU: Fix a long-standing bug with 2D rotation-scale rendering on big-endian systems. --- desmume/src/GPU.cpp | 34 ++++++++++---------------------- desmume/src/MMU.cpp | 48 ++++++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 48 deletions(-) diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index 020f2be0c..88611dc6f 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -909,8 +909,8 @@ void GPUEngineBase::UpdatePropertiesWithoutRender(const u16 l) { IOREG_BG2Parameter &BG2Param = this->_IORegisterMap->BG2Param; - BG2Param.BG2X.value += BG2Param.BG2PB.value; - BG2Param.BG2Y.value += BG2Param.BG2PD.value; + BG2Param.BG2X.value += LE_TO_LOCAL_16(BG2Param.BG2PB.value); + BG2Param.BG2Y.value += LE_TO_LOCAL_16(BG2Param.BG2PD.value); } if ( this->_isBGLayerShown[GPULayerID_BG3] && @@ -918,8 +918,8 @@ void GPUEngineBase::UpdatePropertiesWithoutRender(const u16 l) { IOREG_BG3Parameter &BG3Param = this->_IORegisterMap->BG3Param; - BG3Param.BG3X.value += BG3Param.BG3PB.value; - BG3Param.BG3Y.value += BG3Param.BG3PD.value; + BG3Param.BG3X.value += LE_TO_LOCAL_16(BG3Param.BG3PB.value); + BG3Param.BG3Y.value += LE_TO_LOCAL_16(BG3Param.BG3PD.value); } } @@ -1127,22 +1127,8 @@ void GPUEngineBase::_RenderPixelIterate_Final(GPUEngineCompositorInfo &compInfo, const s32 wmask = wh - 1; const s32 hmask = ht - 1; - IOREG_BGnX x; - IOREG_BGnY y; - x.value = LOCAL_TO_LE_32(param.BGnX.value); - y.value = LOCAL_TO_LE_32(param.BGnY.value); - -#ifdef MSB_FIRST - // This only seems to work in the unrotated/unscaled case. - // - // All the working values should be correct on big-endian, but there is something else wrong going - // on somewhere else, but that remains a mystery at this time. In the meantime, this hack will have - // to remain in order to fix a bunch of games that use affine or extended layers, just as long as - // they don't perform any rotation/scaling. - // - rogerman, 2017-10-17 - x.value = ((x.value & 0xFF000000) >> 16) | (x.value & 0x00FF00FF) | ((x.value & 0x0000FF00) << 16); - y.value = ((y.value & 0xFF000000) >> 16) | (y.value & 0x00FF00FF) | ((y.value & 0x0000FF00) << 16); -#endif + IOREG_BGnX x = param.BGnX; + IOREG_BGnY y = param.BGnY; u8 index; u16 srcColor; @@ -1738,8 +1724,8 @@ void GPUEngineBase::_LineRot(GPUEngineCompositorInfo &compInfo) IOREG_BGnParameter *__restrict bgParams = (compInfo.renderState.selectedLayerID == GPULayerID_BG2) ? (IOREG_BGnParameter *)&this->_IORegisterMap->BG2Param : (IOREG_BGnParameter *)&this->_IORegisterMap->BG3Param; this->_RenderLine_BGAffine(compInfo, *bgParams); - bgParams->BGnX.value += bgParams->BGnPB.value; - bgParams->BGnY.value += bgParams->BGnPD.value; + bgParams->BGnX.value += LE_TO_LOCAL_16(bgParams->BGnPB.value); + bgParams->BGnY.value += LE_TO_LOCAL_16(bgParams->BGnPD.value); } } @@ -1756,8 +1742,8 @@ void GPUEngineBase::_LineExtRot(GPUEngineCompositorInfo &compInfo, bool &outUseC IOREG_BGnParameter *__restrict bgParams = (compInfo.renderState.selectedLayerID == GPULayerID_BG2) ? (IOREG_BGnParameter *)&this->_IORegisterMap->BG2Param : (IOREG_BGnParameter *)&this->_IORegisterMap->BG3Param; this->_RenderLine_BGExtended(compInfo, *bgParams, outUseCustomVRAM); - bgParams->BGnX.value += bgParams->BGnPB.value; - bgParams->BGnY.value += bgParams->BGnPD.value; + bgParams->BGnX.value += LE_TO_LOCAL_16(bgParams->BGnPB.value); + bgParams->BGnY.value += LE_TO_LOCAL_16(bgParams->BGnPD.value); } } diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 203ab08dc..6a783a7b7 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -3826,42 +3826,42 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) return; case REG_DISPA_BG2XL: - T1WriteWord(MMU.ARM9_REG, 0x0028, val); + HostWriteWord(MMU.ARM9_REG, 0x0028, val); mainEngine->ParseReg_BGnX(); return; case REG_DISPA_BG2XH: - T1WriteWord(MMU.ARM9_REG, 0x002A, val); + HostWriteWord(MMU.ARM9_REG, 0x002A, val); mainEngine->ParseReg_BGnX(); return; case REG_DISPA_BG2YL: - T1WriteWord(MMU.ARM9_REG, 0x002C, val); + HostWriteWord(MMU.ARM9_REG, 0x002C, val); mainEngine->ParseReg_BGnY(); return; case REG_DISPA_BG2YH: - T1WriteWord(MMU.ARM9_REG, 0x002E, val); + HostWriteWord(MMU.ARM9_REG, 0x002E, val); mainEngine->ParseReg_BGnY(); return; case REG_DISPA_BG3XL: - T1WriteWord(MMU.ARM9_REG, 0x0038, val); + HostWriteWord(MMU.ARM9_REG, 0x0038, val); mainEngine->ParseReg_BGnX(); return; case REG_DISPA_BG3XH: - T1WriteWord(MMU.ARM9_REG, 0x003A, val); + HostWriteWord(MMU.ARM9_REG, 0x003A, val); mainEngine->ParseReg_BGnX(); return; case REG_DISPA_BG3YL: - T1WriteWord(MMU.ARM9_REG, 0x003C, val); + HostWriteWord(MMU.ARM9_REG, 0x003C, val); mainEngine->ParseReg_BGnY(); return; case REG_DISPA_BG3YH: - T1WriteWord(MMU.ARM9_REG, 0x003E, val); + HostWriteWord(MMU.ARM9_REG, 0x003E, val); mainEngine->ParseReg_BGnY(); return; @@ -4011,42 +4011,42 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) return; case REG_DISPB_BG2XL: - T1WriteWord(MMU.ARM9_REG, 0x1028, val); + HostWriteWord(MMU.ARM9_REG, 0x1028, val); subEngine->ParseReg_BGnX(); return; case REG_DISPB_BG2XH: - T1WriteWord(MMU.ARM9_REG, 0x102A, val); + HostWriteWord(MMU.ARM9_REG, 0x102A, val); subEngine->ParseReg_BGnX(); return; case REG_DISPB_BG2YL: - T1WriteWord(MMU.ARM9_REG, 0x102C, val); + HostWriteWord(MMU.ARM9_REG, 0x102C, val); subEngine->ParseReg_BGnY(); return; case REG_DISPB_BG2YH: - T1WriteWord(MMU.ARM9_REG, 0x102E, val); + HostWriteWord(MMU.ARM9_REG, 0x102E, val); subEngine->ParseReg_BGnY(); return; case REG_DISPB_BG3XL: - T1WriteWord(MMU.ARM9_REG, 0x1038, val); + HostWriteWord(MMU.ARM9_REG, 0x1038, val); subEngine->ParseReg_BGnX(); return; case REG_DISPB_BG3XH: - T1WriteWord(MMU.ARM9_REG, 0x103A, val); + HostWriteWord(MMU.ARM9_REG, 0x103A, val); subEngine->ParseReg_BGnX(); return; case REG_DISPB_BG3YL: - T1WriteWord(MMU.ARM9_REG, 0x103C, val); + HostWriteWord(MMU.ARM9_REG, 0x103C, val); subEngine->ParseReg_BGnY(); return; case REG_DISPB_BG3YH: - T1WriteWord(MMU.ARM9_REG, 0x103E, val); + HostWriteWord(MMU.ARM9_REG, 0x103E, val); subEngine->ParseReg_BGnY(); return; @@ -4429,22 +4429,22 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) return; case REG_DISPA_BG2XL: - T1WriteLong(MMU.ARM9_REG, 0x0028, val); + HostWriteLong(MMU.ARM9_REG, 0x0028, val); mainEngine->ParseReg_BGnX(); return; case REG_DISPA_BG2YL: - T1WriteLong(MMU.ARM9_REG, 0x002C, val); + HostWriteLong(MMU.ARM9_REG, 0x002C, val); mainEngine->ParseReg_BGnY(); return; case REG_DISPA_BG3XL: - T1WriteLong(MMU.ARM9_REG, 0x0038, val); + HostWriteLong(MMU.ARM9_REG, 0x0038, val); mainEngine->ParseReg_BGnX(); return; case REG_DISPA_BG3YL: - T1WriteLong(MMU.ARM9_REG, 0x003C, val); + HostWriteLong(MMU.ARM9_REG, 0x003C, val); mainEngine->ParseReg_BGnY(); return; @@ -4542,22 +4542,22 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) return; case REG_DISPB_BG2XL: - T1WriteLong(MMU.ARM9_REG, 0x1028, val); + HostWriteLong(MMU.ARM9_REG, 0x1028, val); subEngine->ParseReg_BGnX(); return; case REG_DISPB_BG2YL: - T1WriteLong(MMU.ARM9_REG, 0x102C, val); + HostWriteLong(MMU.ARM9_REG, 0x102C, val); subEngine->ParseReg_BGnY(); return; case REG_DISPB_BG3XL: - T1WriteLong(MMU.ARM9_REG, 0x1038, val); + HostWriteLong(MMU.ARM9_REG, 0x1038, val); subEngine->ParseReg_BGnX(); return; case REG_DISPB_BG3YL: - T1WriteLong(MMU.ARM9_REG, 0x103C, val); + HostWriteLong(MMU.ARM9_REG, 0x103C, val); subEngine->ParseReg_BGnY(); return;