Bounding Box bugfixes.

- Fixes all (I hope) BBox-related unknown pointer crashes.
- Fixes wrong BBox values with Frame Skip on (and the resulting unknown pointer crashes).
- Fixes a small oversight on the change I made to the ISO Properties dialog.

This should also be a (very very little) bit faster than the previous version.
This commit is contained in:
crudelios 2011-10-28 21:12:12 +01:00
parent ffd9b6875a
commit dd551814c9
5 changed files with 55 additions and 42 deletions

View File

@ -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);

View File

@ -133,6 +133,7 @@ private:
ID_DISCSPEED,
ID_MERGEBLOCKS,
ID_AUDIO_DSP_HLE,
ID_USE_BBOX,
ID_ZTP_SPEEDUP,
ID_PHACKENABLE,
ID_PHSETTINGS,

View File

@ -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);
}
}
}

View File

@ -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:

View File

@ -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()