diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index aa554e4b48..731cfac932 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -325,7 +325,7 @@ 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 = new wxCheckBox(m_GameConfig, ID_USE_BBOX, _("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); diff --git a/Source/Core/DolphinWX/Src/ISOProperties.h b/Source/Core/DolphinWX/Src/ISOProperties.h index 7161585a36..6e72993b42 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.h +++ b/Source/Core/DolphinWX/Src/ISOProperties.h @@ -133,6 +133,7 @@ private: ID_DISCSPEED, ID_MERGEBLOCKS, ID_AUDIO_DSP_HLE, + ID_USE_BBOX, ID_ZTP_SPEEDUP, ID_PHACKENABLE, ID_PHSETTINGS, diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index d5909fdd95..d06f1de8b9 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -37,6 +37,8 @@ u32 mapTexAddress; bool mapTexFound; int numWrites; +extern volatile bool g_bSkipCurrentFrame; + static const float s_gammaLUT[] = { 1.0f, @@ -401,7 +403,11 @@ void BPWritten(const BPCmd& bp) { if(g_ActiveConfig.bUseBBox) { - // which is which? these are GUESSES! + // Don't compute bounding box if this frame is being skipped! + // Wrong but valid values are better than bogus values... + if(g_bSkipCurrentFrame) + break; + if (bp.address == BPMEM_CLEARBBOX1) { int right = bp.newvalue >> 10; int left = bp.newvalue & 0x3ff; @@ -410,7 +416,6 @@ void BPWritten(const BPCmd& bp) 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; @@ -419,7 +424,6 @@ void BPWritten(const BPCmd& bp) 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); } } } diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp index 3b6d1b7487..90f1546ebd 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.cpp +++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp @@ -206,14 +206,45 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) INFO_LOG(PIXELENGINE, "(r16) TOKEN_REG : %04x", _uReturnValue); break; - // The return values for these BBOX registers need to be gotten from the bounding box of the object. - // See http://code.google.com/p/dolphin-emu/issues/detail?id=360#c74 for more details. + case PE_BBOX_LEFT: + { + // Left must be even and 606px max + _uReturnValue = std::min((u16) 606, bbox[0]) & ~1; - // 0x80, 0xa0, 0x80, 0xa0 makes Paper Mario happy. - case PE_BBOX_LEFT: _uReturnValue = bbox[0]; INFO_LOG(PIXELENGINE, "R: BBOX_LEFT = %i", bbox[0]); bbox_active = false; break; - case PE_BBOX_RIGHT: _uReturnValue = bbox[1]; INFO_LOG(PIXELENGINE, "R: BBOX_RIGHT = %i", bbox[1]); bbox_active = false; break; - case PE_BBOX_TOP: _uReturnValue = bbox[2]; INFO_LOG(PIXELENGINE, "R: BBOX_TOP = %i", bbox[2]); bbox_active = false; break; - case PE_BBOX_BOTTOM: _uReturnValue = bbox[3]; INFO_LOG(PIXELENGINE, "R: BBOX_BOTTOM = %i", bbox[3]); bbox_active = false; break; + INFO_LOG(PIXELENGINE, "R: BBOX_LEFT = %i", _uReturnValue); + bbox_active = false; + break; + } + + case PE_BBOX_RIGHT: + { + // Right must be odd and 607px max + _uReturnValue = std::min((u16) 607, bbox[1]) | 1; + + INFO_LOG(PIXELENGINE, "R: BBOX_RIGHT = %i", _uReturnValue); + bbox_active = false; + break; + } + + case PE_BBOX_TOP: + { + // Top must be even and 478px max + _uReturnValue = std::min((u16) 478, bbox[2]) & ~1; + + INFO_LOG(PIXELENGINE, "R: BBOX_TOP = %i", _uReturnValue); + bbox_active = false; + break; + } + + case PE_BBOX_BOTTOM: + { + // Bottom must be odd and 479px max + _uReturnValue = std::min((u16) 479, bbox[3]) | 1; + + INFO_LOG(PIXELENGINE, "R: BBOX_BOTTOM = %i", _uReturnValue); + bbox_active = false; + break; + } case PE_PERF_0L: case PE_PERF_0H: diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index ee0538751a..fb34ce1bc1 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -111,7 +111,7 @@ void LOADERDECL UpdateBoundingBox() // Then convert to screen space and update the bounding box. float p[3] = {data[0], data[1], data[2]}; - const float *world_matrix = (float*)xfmem + MatrixIndexA.PosNormalMtxIdx * 4; + const float *world_matrix = (float*)xfmem + MatrixIndexA.PosNormalMtxIdx * 4; const float *proj_matrix = &g_fProjectionMatrix[0]; float t[3]; @@ -124,41 +124,18 @@ void LOADERDECL UpdateBoundingBox() o[1] = t[0] * proj_matrix[4] + t[1] * proj_matrix[5] + t[2] * proj_matrix[6] + proj_matrix[7]; 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? + // Max width seems to be 608, while max height is 480 + // Here height is set to 484 as BBox bottom always seems to be off by a few pixels o[0] = (o[0] + 1.0f) * 304.0f; - o[1] = (1.0f - o[1]) * 240.0f; + o[1] = (1.0f - o[1]) * 242.0f; - 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; - } - - 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]--; - } + 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) 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) o[1]; } void LOADERDECL TexMtx_ReadDirect_UByte()