diff --git a/Data/User/GameConfig/G8ME01.ini b/Data/User/GameConfig/G8ME01.ini index d49e5395d0..0033486b59 100644 --- a/Data/User/GameConfig/G8ME01.ini +++ b/Data/User/GameConfig/G8ME01.ini @@ -41,5 +41,7 @@ $Max Gold $Max Shop Points 026EE7F0 000003E7 [Video] +UseBBox = True ProjectionHack = 0 - +[Video_Hacks] +DlistCachingEnable = False diff --git a/Data/User/GameConfig/G8MP01.ini b/Data/User/GameConfig/G8MP01.ini index db66750a7f..5e1ff20ee6 100644 --- a/Data/User/GameConfig/G8MP01.ini +++ b/Data/User/GameConfig/G8MP01.ini @@ -4,3 +4,7 @@ EmulationStateId = 4 [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. +[Video] +UseBBox = True +[Video_Hacks] +DlistCachingEnable = False diff --git a/Data/User/GameConfig/NAEE01.ini b/Data/User/GameConfig/NAEE01.ini index 8ff0d929d0..b385f23889 100644 --- a/Data/User/GameConfig/NAEE01.ini +++ b/Data/User/GameConfig/NAEE01.ini @@ -5,3 +5,7 @@ EmulationIssues = Sound requires LLE. No graphical issues. EmulationStateId = 4 [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. +[Video] +UseBBox = True +[Video_Hacks] +DlistCachingEnable = False diff --git a/Data/User/GameConfig/R8PE01.ini b/Data/User/GameConfig/R8PE01.ini index 4ae6b89983..ce4ee47320 100644 --- a/Data/User/GameConfig/R8PE01.ini +++ b/Data/User/GameConfig/R8PE01.ini @@ -7,5 +7,8 @@ EmulationIssues = [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Video] +UseBBox = True ProjectionHack = 0 +[Video_Hacks] +DlistCachingEnable = False [Gecko] diff --git a/Data/User/GameConfig/R8PP01.ini b/Data/User/GameConfig/R8PP01.ini index a348557b9c..ccfb4ec45d 100644 --- a/Data/User/GameConfig/R8PP01.ini +++ b/Data/User/GameConfig/R8PP01.ini @@ -6,4 +6,7 @@ EmulationIssues = [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Video] +UseBBox = True ProjectionHack = 0 +[Video_Hacks] +DlistCachingEnable = False diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 4618e739ae..aa554e4b48 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -325,6 +325,9 @@ void CISOProperties::CreateGUIControls(bool IsWad) DisableWiimoteSpeaker->SetToolTip(_("Mutes the Wiimote speaker. Fixes random disconnections on real wiimotes. No effect on emulated wiimotes.")); // Video + UseBBox = new wxCheckBox(m_GameConfig, ID_ZTP_SPEEDUP, _("Enable Bounding Box Calculation"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER); + UseBBox->SetToolTip(_("If checked, the bounding box registers will be updated. Used by the Paper Mario games.")); + UseZTPSpeedupHack = new wxCheckBox(m_GameConfig, ID_ZTP_SPEEDUP, _("ZTP hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER); UseZTPSpeedupHack->SetToolTip(_("Enable this to speed up The Legend of Zelda: Twilight Princess. Disable for ANY other game.")); @@ -383,6 +386,7 @@ void CISOProperties::CreateGUIControls(bool IsWad) wxStaticBoxSizer * const sbVideoOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Video")); + sbVideoOverrides->Add(UseBBox, 0, wxLEFT, 5); sbVideoOverrides->Add(UseZTPSpeedupHack, 0, wxLEFT, 5); szrPHackSettings->Add(PHackEnable, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5); szrPHackSettings->Add(PHSettings, 0, wxLEFT, 5); @@ -898,7 +902,13 @@ void CISOProperties::LoadGameConfig() DisableWiimoteSpeaker->Set3StateValue((wxCheckBoxState)bTemp); else DisableWiimoteSpeaker->Set3StateValue(wxCHK_UNDETERMINED); - + + if (GameIni.Get("Video", "UseBBox", &bTemp)) + UseBBox->Set3StateValue((wxCheckBoxState)bTemp); + else + UseBBox->Set3StateValue(wxCHK_UNDETERMINED); + + if (GameIni.Get("Video", "ZTPSpeedupHack", &bTemp)) UseZTPSpeedupHack->Set3StateValue((wxCheckBoxState)bTemp); else @@ -992,6 +1002,11 @@ bool CISOProperties::SaveGameConfig() else GameIni.Set("Wii", "DisableWiimoteSpeaker", DisableWiimoteSpeaker->Get3StateValue()); + if (UseBBox->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Video", "UseBBox"); + else + GameIni.Set("Video", "UseBBox", UseBBox->Get3StateValue()); + if (UseZTPSpeedupHack->Get3StateValue() == wxCHK_UNDETERMINED) GameIni.DeleteKey("Video", "ZTPSpeedupHack"); else diff --git a/Source/Core/DolphinWX/Src/ISOProperties.h b/Source/Core/DolphinWX/Src/ISOProperties.h index 0add6e9451..7161585a36 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.h +++ b/Source/Core/DolphinWX/Src/ISOProperties.h @@ -74,7 +74,7 @@ private: // Wii wxCheckBox *EnableProgressiveScan, *EnableWideScreen, *DisableWiimoteSpeaker; // Video - wxCheckBox *UseZTPSpeedupHack, *PHackEnable; + wxCheckBox *UseZTPSpeedupHack, *PHackEnable, *UseBBox; wxButton *PHSettings; wxArrayString arrayStringFor_EmuState; diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index cee68327f5..d5909fdd95 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -257,9 +257,8 @@ void BPWritten(const BPCmd& bp) // We should be able to get away with deactivating the current bbox tracking // here. Not sure if there's a better spot to put this. // the number of lines copied is determined by the y scale * source efb height -#ifdef BBOX_SUPPORT + PixelEngine::bbox_active = false; -#endif float yScale; if (PE_copy.scale_invert) @@ -400,28 +399,29 @@ void BPWritten(const BPCmd& bp) case BPMEM_CLEARBBOX1: case BPMEM_CLEARBBOX2: { -#ifdef BBOX_SUPPORT - // which is which? these are GUESSES! - if (bp.address == BPMEM_CLEARBBOX1) { - int right = bp.newvalue >> 10; - int left = bp.newvalue & 0x3ff; + if(g_ActiveConfig.bUseBBox) + { + // which is which? these are GUESSES! + if (bp.address == BPMEM_CLEARBBOX1) { + int right = bp.newvalue >> 10; + int left = bp.newvalue & 0x3ff; - // We should only set these if bbox is calculated properly. - PixelEngine::bbox[0] = left; - PixelEngine::bbox[1] = right; - PixelEngine::bbox_active = true; - // WARN_LOG(VIDEO, "ClearBBox LR: %i, %08x - %i, %i", bp.address, bp.newvalue, left, right); - } else { - int bottom = bp.newvalue >> 10; - int top = bp.newvalue & 0x3ff; + // We should only set these if bbox is calculated properly. + PixelEngine::bbox[0] = left; + PixelEngine::bbox[1] = right; + PixelEngine::bbox_active = true; + // WARN_LOG(VIDEO, "ClearBBox LR: %i, %08x - %i, %i", bp.address, bp.newvalue, left, right); + } else { + int bottom = bp.newvalue >> 10; + int top = bp.newvalue & 0x3ff; - // We should only set these if bbox is calculated properly. - PixelEngine::bbox[2] = top; - PixelEngine::bbox[3] = bottom; - PixelEngine::bbox_active = true; - // WARN_LOG(VIDEO, "ClearBBox TB: %i, %08x - %i, %i", bp.address, bp.newvalue, top, bottom); + // We should only set these if bbox is calculated properly. + PixelEngine::bbox[2] = top; + PixelEngine::bbox[3] = bottom; + PixelEngine::bbox_active = true; + // WARN_LOG(VIDEO, "ClearBBox TB: %i, %08x - %i, %i", bp.address, bp.newvalue, top, bottom); + } } -#endif } break; case BPMEM_TEXINVALIDATE: // Used, if game has manual control the Texture Cache, which we don't allow diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index ce9e81219d..ee0538751a 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -101,7 +101,7 @@ void LOADERDECL PosMtx_Write() void LOADERDECL UpdateBoundingBox() { - if (!PixelEngine::bbox_active) + if (!PixelEngine::bbox_active) return; // Truly evil hack, reading backwards from the write pointer. If we were writing to write-only @@ -119,40 +119,46 @@ void LOADERDECL UpdateBoundingBox() t[1] = p[0] * world_matrix[4] + p[1] * world_matrix[5] + p[2] * world_matrix[6] + world_matrix[7]; t[2] = p[0] * world_matrix[8] + p[1] * world_matrix[9] + p[2] * world_matrix[10] + world_matrix[11]; - float o[4]; - o[2] = t[0] * proj_matrix[8] + t[1] * proj_matrix[9] + t[2] * proj_matrix[10] + proj_matrix[11]; - // Depth culling - if (o[2] < 0.0) { - // No pixels are likely to be drawn - don't update bounding box. - return; - } + float o[3]; o[0] = t[0] * proj_matrix[0] + t[1] * proj_matrix[1] + t[2] * proj_matrix[2] + proj_matrix[3]; o[1] = t[0] * proj_matrix[4] + t[1] * proj_matrix[5] + t[2] * proj_matrix[6] + proj_matrix[7]; - o[3] = t[0] * proj_matrix[12] + t[1] * proj_matrix[13] + t[2] * proj_matrix[14] + proj_matrix[15]; - - o[0] /= o[3]; - o[1] /= o[3]; + o[2] = t[0] * proj_matrix[12] + t[1] * proj_matrix[13] + t[2] * proj_matrix[14] + proj_matrix[15]; + + + o[0] /= o[2]; + o[1] /= o[2]; // should possibly adjust for viewport? - o[0] = (o[0] + 1.0f) * 320.0f; - o[1] = (o[1] + 1.0f) * 240.0f; + o[0] = (o[0] + 1.0f) * 304.0f; + o[1] = (1.0f - o[1]) * 240.0f; - if (o[0] < PixelEngine::bbox[0]) PixelEngine::bbox[0] = (u16)std::max(0.0f, o[0]); - if (o[0] > PixelEngine::bbox[1]) PixelEngine::bbox[1] = (u16)std::min(640.0f, o[0]); - if (o[1] < PixelEngine::bbox[2]) PixelEngine::bbox[2] = (u16)std::max(0.0f, o[1]); - if (o[1] > PixelEngine::bbox[3]) PixelEngine::bbox[3] = (u16)std::min(480.0f, o[1]); + if (o[0] < PixelEngine::bbox[0]) + { + PixelEngine::bbox[0] = (u16) std::max(0.0f, o[0]); - // Hardware tests bounding boxes in 2x2 blocks => left and top are even, right and bottom are odd - PixelEngine::bbox[0] &= ~1; - PixelEngine::bbox[1] |= 1; - PixelEngine::bbox[2] &= ~1; - PixelEngine::bbox[3] |= 1; + // Hardware tests bounding boxes in 2x2 blocks => left and top are even, right and bottom are odd + PixelEngine::bbox[0] &= ~1; + } - /* - if (GetAsyncKeyState(VK_LSHIFT)) { - ERROR_LOG(VIDEO, "XForm: %f %f %f to %f %f", p[0], p[1], p[2], o[0], o[1]); - ERROR_LOG(VIDEO, "%i %i %i %i", g_VideoInitialize.pBBox[0], g_VideoInitialize.pBBox[1], g_VideoInitialize.pBBox[2], g_VideoInitialize.pBBox[3]); - }*/ + if (o[0] > PixelEngine::bbox[1]) + { + PixelEngine::bbox[1] = (u16) std::min(608.0f, o[0]); + if(!(PixelEngine::bbox[1] & 1) && PixelEngine::bbox[1] != 0) + PixelEngine::bbox[1]--; + } + + if (o[1] < PixelEngine::bbox[2]) + { + PixelEngine::bbox[2] = (u16) std::max(0.0f, o[1]); + PixelEngine::bbox[2] &= ~1; + } + + if (o[1] > PixelEngine::bbox[3]) + { + PixelEngine::bbox[3] = (u16) std::min(480.0f, o[1]); + if(!(PixelEngine::bbox[3] & 1) && PixelEngine::bbox[3] != 0) + PixelEngine::bbox[3]--; + } } void LOADERDECL TexMtx_ReadDirect_UByte() @@ -290,9 +296,8 @@ void VertexLoader::CompileVertexTranslator() // OK, so we just got a point. Let's go back and read it for the bounding box. -#ifdef BBOX_SUPPORT - WriteCall(UpdateBoundingBox); -#endif + if(g_ActiveConfig.bUseBBox) + WriteCall(UpdateBoundingBox); // Normals vtx_decl.num_normals = 0; diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h index 80c0937884..9f6dd59cd3 100644 --- a/Source/Core/VideoCommon/Src/VideoCommon.h +++ b/Source/Core/VideoCommon/Src/VideoCommon.h @@ -56,12 +56,6 @@ enum MAX_XFB_HEIGHT = 574 }; -// If this is enabled, bounding boxes will be computed for everything drawn. -// This can theoretically have a big speed hit in some geom heavy games. Needs more work. -// Helps some effects in Paper Mario (but they aren't quite right yet). -// Do testing to figure out if the speed hit is bad? -// #define BBOX_SUPPORT - // Logging // ---------- void HandleGLError(); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 2c7788c9cc..b6ba76f45e 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -172,6 +172,7 @@ void VideoConfig::GameIniLoad(const char *ini_file) iniFile.GetIfExists("Video", "PH_ZNear", &sPhackvalue[0]); iniFile.GetIfExists("Video", "PH_ZFar", &sPhackvalue[1]); iniFile.GetIfExists("Video", "ZTPSpeedupHack", &bZTPSpeedHack); + iniFile.GetIfExists("Video", "UseBBox", &bUseBBox); } void VideoConfig::VerifyValidity() diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 83ec08784d..3bd833cc73 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -135,6 +135,7 @@ struct VideoConfig std::string sPhackvalue[2]; float fAspectRatioHackW, fAspectRatioHackH; bool bZTPSpeedHack; // The Legend of Zelda: Twilight Princess + bool bUseBBox; bool bEnablePixelLighting; bool bEnablePerPixelDepth;