Implement the correct method for determining field order.

Based on advice from tueidj we implement this method based on how
TVs actually determin the field order.

Removes spammy messages about "Invalid field order"
This commit is contained in:
Scott Mansell 2014-07-17 23:56:23 +12:00
parent 063f530d4c
commit 7aff56bef5
1 changed files with 18 additions and 19 deletions

View File

@ -519,27 +519,26 @@ static void BeginField(FieldType field)
u32 fbHeight = m_VerticalTimingRegister.ACV * (field == FIELD_PROGRESSIVE ? 1 : 2); u32 fbHeight = m_VerticalTimingRegister.ACV * (field == FIELD_PROGRESSIVE ? 1 : 2);
u32 xfbAddr; u32 xfbAddr;
// NTSC and PAL have opposite field orders. // Only the top field is valid in progressive mode.
if (m_DisplayControlRegister.FMT == 1) // PAL if (field == FieldType::FIELD_PROGRESSIVE)
{ {
// But the PAL ports of some games are poorly programmed and don't use correct ordering.
// Zelda: Wind Waker and Simpsons Hit & Run are exampes of this, there are probally more.
// PAL Wind Waker also runs at 30fps instead of 25.
if (field == FieldType::FIELD_PROGRESSIVE || GetXFBAddressBottom() != (GetXFBAddressTop() - 1280))
{
WARN_LOG(VIDEOINTERFACE, "PAL game is trying to use incorrect (NTSC) field ordering");
// Lets kindly fix this for them.
xfbAddr = GetXFBAddressTop(); xfbAddr = GetXFBAddressTop();
// TODO: PAL Simpsons Hit & Run now has a green line at the bottom when Real XFB is used.
// Might be a bug later on in our code, or a bug in the actual game.
} }
else else
{ {
xfbAddr = GetXFBAddressBottom(); // If we are displaying an interlaced field, we convert it to a progressive field
} // by simply using the whole XFB, which 99% of the time contains a whole progressive
} else { // frame.
// All known NTSC games use the top/odd field as the upper field but
// PAL games are known to whimsically arrange the fields in either order.
// So to work out which field is pointing to the top of the progressive XFB we check
// which field has the lower PRB value in the VBlank Timing Registers.
if(m_VBlankTimingOdd.PRB < m_VBlankTimingEven.PRB)
xfbAddr = GetXFBAddressTop(); xfbAddr = GetXFBAddressTop();
else
xfbAddr = GetXFBAddressBottom();
} }
static const char* const fieldTypeNames[] = { "Progressive", "Upper", "Lower" }; static const char* const fieldTypeNames[] = { "Progressive", "Upper", "Lower" };