From ea7987f0ae15945fde4543f5b094ea9144893039 Mon Sep 17 00:00:00 2001 From: wiidev Date: Fri, 17 Apr 2020 06:11:25 +0100 Subject: [PATCH] Fix video mode patching Bug reported @ https://gbatemp.net/posts/9015326 --- resources/wiiflow_game_booter/source/main.cpp | 2 + .../wiiflow_game_booter/source/videopatch.c | 156 +++++++++--------- 2 files changed, 77 insertions(+), 81 deletions(-) diff --git a/resources/wiiflow_game_booter/source/main.cpp b/resources/wiiflow_game_booter/source/main.cpp index 811d2b4e..812524b1 100644 --- a/resources/wiiflow_game_booter/source/main.cpp +++ b/resources/wiiflow_game_booter/source/main.cpp @@ -105,6 +105,8 @@ int main() u32 offset = 0; Disc_FindPartition(&offset); WDVD_OpenPartition(offset, &GameIOS); + if(normalCFG.vidMode == 5) + normalCFG.patchVidMode = 1; //progressive mode requires this vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg); AppEntrypoint = Apploader_Run(normalCFG.vidMode, vmode, normalCFG.vipatch, normalCFG.countryString, normalCFG.patchVidMode, normalCFG.aspectRatio, normalCFG.returnTo, normalCFG.patchregion, normalCFG.private_server, normalCFG.patchFix480p); diff --git a/resources/wiiflow_game_booter/source/videopatch.c b/resources/wiiflow_game_booter/source/videopatch.c index bc319393..4ce75981 100644 --- a/resources/wiiflow_game_booter/source/videopatch.c +++ b/resources/wiiflow_game_booter/source/videopatch.c @@ -6,8 +6,6 @@ #define ARRAY_SIZE(a) (sizeof a / sizeof a[0]) -extern GXRModeObj TVNtsc480Int; - GXRModeObj TVPal528Prog = { 6, // viDisplayMode @@ -78,7 +76,7 @@ GXRModeObj TVPal528ProgSoft = }; -GXRModeObj TVPal528ProgUnknown = +GXRModeObj TVPal524ProgAa = { 6, // viDisplayMode 640, // fbWidth @@ -113,86 +111,41 @@ GXRModeObj TVPal528ProgUnknown = }; -GXRModeObj TVPal574IntDfScale = -{ - VI_TVMODE_PAL_INT, // viDisplayMode - 640, // fbWidth - 480, // efbHeight - 574, // xfbHeight - (VI_MAX_WIDTH_PAL - 640)/2, // viXOrigin - (VI_MAX_HEIGHT_PAL - 574)/2, // viYOrigin - 640, // viWidth - 574, // viHeight - VI_XFBMODE_DF, // xFBmode - GX_FALSE, // field_rendering - GX_FALSE, // aa - - // sample points arranged in increasing Y order - { - {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each - {6,6},{6,6},{6,6}, // pix 1 - {6,6},{6,6},{6,6}, // pix 2 - {6,6},{6,6},{6,6} // pix 3 - }, - // vertical filter[7], 1/64 units, 6 bits each - { - 8, // line n-1 - 8, // line n-1 - 10, // line n - 12, // line n - 10, // line n - 8, // line n+1 - 8 // line n+1 - } -}; - -static const GXRModeObj *g_vidmodes[] = { +static GXRModeObj* vmodes[] = { + &TVNtsc240Ds, + &TVNtsc240DsAa, + &TVNtsc240Int, + &TVNtsc240IntAa, &TVNtsc480Int, + &TVNtsc480IntAa, &TVNtsc480IntDf, &TVNtsc480Prog, - - &TVPal528Int, + &TVNtsc480ProgSoft, + &TVNtsc480ProgAa, + &TVMpal480IntDf, + &TVPal264Ds, + &TVPal264DsAa, + &TVPal264Int, + &TVPal264IntAa, + &TVPal524ProgAa, + &TVPal524IntAa, + &TVPal528Int, &TVPal528IntDf, &TVPal528Prog, &TVPal528ProgSoft, - &TVPal528ProgUnknown, - - &TVMpal480IntDf, - &TVMpal480Prog, - + &TVPal576IntDfScale, + &TVEurgb60Hz240Ds, + &TVEurgb60Hz240DsAa, + &TVEurgb60Hz240Int, + &TVEurgb60Hz240IntAa, &TVEurgb60Hz480Int, &TVEurgb60Hz480IntDf, - &TVEurgb60Hz480Prog + &TVEurgb60Hz480IntAa, + &TVEurgb60Hz480Prog, + &TVEurgb60Hz480ProgSoft, + &TVEurgb60Hz480ProgAa }; -// Level : -// 0 : If same number of lines and same mode type (interlaced, progressive) -// 1 : If same mode type -// 2 : Always -static void applyVideoPatch(void *dst, u32 len, GXRModeObj *rmode, int level) -{ - u32 i; - u32 *bufEnd = (u32 *)((u8 *)dst + (len - sizeof *rmode)); - u32 *p = (u32 *)dst; - while (p <= bufEnd) - { - for (i = 0; i < ARRAY_SIZE(g_vidmodes); ++i) - if (memcmp(p, g_vidmodes[i], sizeof *rmode) == 0) - { - // Video mode description found, replace it - GXRModeObj *m = (GXRModeObj *)p; - if (level == 2 - || (((m->viTVMode & 3) == VI_PROGRESSIVE) == ((rmode->viTVMode & 3) == VI_PROGRESSIVE) - && (level == 1 || m->viHeight == rmode->viHeight))) - memcpy(p, rmode, sizeof *rmode); - p = (u32 *)(m + 1); - break; - } - if (i == ARRAY_SIZE(g_vidmodes)) - p++; - } -} - static bool compare_videomodes(GXRModeObj* mode1, GXRModeObj* mode2) { return memcmp(mode1, mode2, sizeof *mode1) == 0; // padding seems to always be 0 @@ -210,14 +163,15 @@ static GXRModeObj* PAL2NTSC[]={ &TVPal264Int, &TVNtsc240Int, &TVPal264IntAa, &TVNtsc240IntAa, &TVPal524IntAa, &TVNtsc480IntAa, - &TVPal528Int, &TVNtsc480IntAa, + &TVPal528Int, &TVNtsc480Int, &TVPal528IntDf, &TVNtsc480IntDf, - &TVPal574IntDfScale, &TVNtsc480IntDf, + &TVPal528Prog, &TVNtsc480Prog, + &TVPal576IntDfScale, &TVNtsc480IntDf, &TVEurgb60Hz240Ds, &TVNtsc240Ds, &TVEurgb60Hz240DsAa, &TVNtsc240DsAa, &TVEurgb60Hz240Int, &TVNtsc240Int, &TVEurgb60Hz240IntAa, &TVNtsc240IntAa, - &TVEurgb60Hz480Int, &TVNtsc480IntAa, + &TVEurgb60Hz480Int, &TVNtsc480Int, &TVEurgb60Hz480IntDf, &TVNtsc480IntDf, &TVEurgb60Hz480IntAa, &TVNtsc480IntAa, &TVEurgb60Hz480Prog, &TVNtsc480Prog, @@ -231,9 +185,10 @@ static GXRModeObj* NTSC2PAL[]={ &TVNtsc240DsAa, &TVPal264DsAa, &TVNtsc240Int, &TVPal264Int, &TVNtsc240IntAa, &TVPal264IntAa, + &TVNtsc480Int, &TVPal528Int, &TVNtsc480IntDf, &TVPal528IntDf, &TVNtsc480IntAa, &TVPal524IntAa, - &TVNtsc480Prog, &TVPal528IntDf, + &TVNtsc480Prog, &TVPal528Prog, 0,0 }; @@ -242,12 +197,49 @@ static GXRModeObj* NTSC2PAL60[]={ &TVNtsc240DsAa, &TVEurgb60Hz240DsAa, &TVNtsc240Int, &TVEurgb60Hz240Int, &TVNtsc240IntAa, &TVEurgb60Hz240IntAa, + &TVNtsc480Int, &TVEurgb60Hz480Int, &TVNtsc480IntDf, &TVEurgb60Hz480IntDf, &TVNtsc480IntAa, &TVEurgb60Hz480IntAa, &TVNtsc480Prog, &TVEurgb60Hz480Prog, 0,0 }; +static void applyVideoPatch(void *Address, u32 Size, GXRModeObj* rmode, bool patchAll) +{ + u8 *Addr = (u8 *)Address; + bool found = 0; + u32 i; + + while(Size >= sizeof(GXRModeObj)) + { + // Video mode pattern found + if( (((GXRModeObj*)Addr)->fbWidth == 0x0280 && ((GXRModeObj*)Addr)->viWidth == 0x02c4) || // TVEurgb60Hz480Prog + (((GXRModeObj*)Addr)->fbWidth == 0x0280 && ((GXRModeObj*)Addr)->viWidth == 0x0280) ) // All other video modes + { + found = 0; + for(i = 0; i < sizeof(vmodes)/sizeof(vmodes[0]); i++) + { + if(compare_videomodes(vmodes[i], (GXRModeObj*)Addr)) + { + found = 1; + patch_videomode((GXRModeObj*)Addr, rmode); + Addr += (sizeof(GXRModeObj)-4); + Size -= (sizeof(GXRModeObj)-4); + break; + } + } + if(patchAll && !found) + { + patch_videomode((GXRModeObj*)Addr, rmode); + Addr += (sizeof(GXRModeObj)-4); + Size -= (sizeof(GXRModeObj)-4); + } + } + Addr += 4; + Size -= 4; + } +} + static bool Search_and_patch_Video_Modes(void *Address, u32 Size, GXRModeObj* Table[]) { u8 *Addr = (u8 *)Address; @@ -277,14 +269,16 @@ void patchVideoModes(void *dst, u32 len, int vidMode, GXRModeObj *vmode, int pat { GXRModeObj **table = 0; - if(patchVidModes && vmode != 0) - applyVideoPatch(dst, len, vmode, patchVidModes - 1); + // Video patch set to "all" or the video mode is progressive + if((patchVidModes == 3 || vidMode == 5) && vmode != 0) + applyVideoPatch(dst, len, vmode, true); + // Video patch set to "more" + else if(patchVidModes == 2 && vmode != 0) + applyVideoPatch(dst, len, vmode, false); else { switch(vidMode) { - case 0: // default / disc / game - break; case 1: // SYSTEM switch(CONF_GetVideo()) {