From 61d7c5caf55c0ef14bc77b4c5c8112eae597c4ff Mon Sep 17 00:00:00 2001 From: wiidev Date: Sat, 25 Sep 2021 20:00:02 +0100 Subject: [PATCH] Add deflicker filter options --- .../source/ChannelHandler.cpp | 33 ++++++- .../source/ChannelHandler.hpp | 2 +- .../wiiflow_game_booter/source/Config.hpp | 1 + .../wiiflow_game_booter/source/apploader.c | 41 ++++++-- .../wiiflow_game_booter/source/apploader.h | 12 ++- resources/wiiflow_game_booter/source/main.cpp | 4 +- .../wiiflow_game_booter/source/patchcode.c | 94 +++++++++++++++++++ .../wiiflow_game_booter/source/patchcode.h | 3 + source/booter/Config.h | 1 + source/booter/external_booter.cpp | 3 +- source/booter/external_booter.hpp | 2 +- source/menu/menu.hpp | 14 ++- source/menu/menu_config7.cpp | 38 ++++++++ source/menu/menu_config_game.cpp | 50 ++++++++++ source/menu/menu_game_boot.cpp | 9 +- wii/wiiflow/Languages/english.ini | 8 ++ 16 files changed, 299 insertions(+), 16 deletions(-) diff --git a/resources/wiiflow_game_booter/source/ChannelHandler.cpp b/resources/wiiflow_game_booter/source/ChannelHandler.cpp index ef1cdf5e..76485c53 100644 --- a/resources/wiiflow_game_booter/source/ChannelHandler.cpp +++ b/resources/wiiflow_game_booter/source/ChannelHandler.cpp @@ -41,6 +41,7 @@ #include "utils.h" #include "videopatch.h" #include "video_tinyload.h" +#include "apploader.h" void *dolchunkoffset[18]; u32 dolchunksize[18]; @@ -149,8 +150,13 @@ u32 LoadChannel(u64 title, bool dol, u32 *IOS) } void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, - u8 private_server, bool patchFix480p, u8 bootType) + u8 private_server, bool patchFix480p, u8 deflicker, u8 bootType) { + u8 vfilter_off[7] = {0, 0, 21, 22, 21, 0, 0}; + u8 vfilter_low[7] = {4, 4, 16, 16, 16, 4, 4}; + u8 vfilter_medium[7] = {4, 8, 12, 16, 12, 8, 4}; + u8 vfilter_high[7] = {8, 8, 10, 12, 10, 8, 8}; + bool hookpatched = false; for(u8 i = 0; i < dolchunkcount; i++) { @@ -167,6 +173,31 @@ void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryStrin PrivateServerPatcher(dolchunkoffset[i], dolchunksize[i], private_server); if(hooktype != 0 && hookpatched == false) hookpatched = dogamehooks(dolchunkoffset[i], dolchunksize[i], true); + + if (deflicker == DEFLICKER_ON_LOW) + { + patch_vfilters(dolchunkoffset[i], dolchunksize[i], vfilter_low); + patch_vfilters_rogue(dolchunkoffset[i], dolchunksize[i], vfilter_low); + } + else if (deflicker == DEFLICKER_ON_MEDIUM) + { + patch_vfilters(dolchunkoffset[i], dolchunksize[i], vfilter_medium); + patch_vfilters_rogue(dolchunkoffset[i], dolchunksize[i], vfilter_medium); + } + else if (deflicker == DEFLICKER_ON_HIGH) + { + patch_vfilters(dolchunkoffset[i], dolchunksize[i], vfilter_high); + patch_vfilters_rogue(dolchunkoffset[i], dolchunksize[i], vfilter_high); + } + else if (deflicker != DEFLICKER_NORMAL) // Either safe or extended + { + patch_vfilters(dolchunkoffset[i], dolchunksize[i], vfilter_off); + patch_vfilters_rogue(dolchunkoffset[i], dolchunksize[i], vfilter_off); + // This might break fade and brightness effects + if (deflicker == DEFLICKER_OFF_EXTENDED) + deflicker_patch(dolchunkoffset[i], dolchunksize[i]); + } + DCFlushRange(dolchunkoffset[i], dolchunksize[i]); ICInvalidateRange(dolchunkoffset[i], dolchunksize[i]); prog10(); diff --git a/resources/wiiflow_game_booter/source/ChannelHandler.hpp b/resources/wiiflow_game_booter/source/ChannelHandler.hpp index d94de943..1cd664ab 100644 --- a/resources/wiiflow_game_booter/source/ChannelHandler.hpp +++ b/resources/wiiflow_game_booter/source/ChannelHandler.hpp @@ -14,7 +14,7 @@ typedef struct _dolheader } ATTRIBUTE_PACKED dolheader; void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, - u8 patchVidModes, int aspectRatio, u8 private_server, bool patchFix480p, u8 bootType); + u8 patchVidModes, int aspectRatio, u8 private_server, bool patchFix480p, u8 deflicker, u8 bootType); u32 LoadChannel(u64 title, bool dol, u32 *IOS); #endif /* __CHANHANDLE_HPP_ */ diff --git a/resources/wiiflow_game_booter/source/Config.hpp b/resources/wiiflow_game_booter/source/Config.hpp index f69de83b..d0f0249e 100644 --- a/resources/wiiflow_game_booter/source/Config.hpp +++ b/resources/wiiflow_game_booter/source/Config.hpp @@ -48,6 +48,7 @@ struct the_CFG { u8 vipatch; s8 aspectRatio; bool patchFix480p; + u8 deflicker; u8 private_server; u8 *cheats; u32 cheatSize; diff --git a/resources/wiiflow_game_booter/source/apploader.c b/resources/wiiflow_game_booter/source/apploader.c index a19d0131..041cb03a 100644 --- a/resources/wiiflow_game_booter/source/apploader.c +++ b/resources/wiiflow_game_booter/source/apploader.c @@ -29,7 +29,7 @@ static const char *GameID = (const char*)0x80000000; #define APPLDR_CODE 0x918 void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, - bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo, bool patchregion, u8 private_server, u8 bootType); + bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo, bool patchregion, u8 private_server, u8 deflicker, u8 bootType); static void patch_NoDiscinDrive(void *buffer, u32 len); static void Anti_002_fix(void *Address, int Size); static bool Remove_001_Protection(void *Address, int Size); @@ -50,7 +50,7 @@ static struct } apploader_hdr ATTRIBUTE_ALIGN(32); u32 Apploader_Run(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo, - bool patchregion , u8 private_server, bool patchFix480p, u8 bootType) + bool patchregion , u8 private_server, bool patchFix480p, u8 deflicker, u8 bootType) { //! Disable private server for games that still have official servers. if (memcmp(GameID, "SC7", 3) == 0 || memcmp(GameID, "RJA", 3) == 0 || @@ -105,9 +105,9 @@ u32 Apploader_Run(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryStrin WDVD_Read(dst, len, offset); // if server is wiimmfi and game is mario kart wii don't use private server. use MarioKartWiiWiimmfiPatch below if(private_server == PRIVSERV_WIIMMFI && memcmp("RMC", GameID, 3) == 0)// 2= wiimmfi - maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio, returnTo, patchregion, 0, bootType); + maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio, returnTo, patchregion, 0, deflicker, bootType); else - maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio, returnTo, patchregion, private_server, bootType); + maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio, returnTo, patchregion, private_server, deflicker, bootType); DCFlushRange(dst, len); ICInvalidateRange(dst, len); @@ -132,8 +132,13 @@ u32 Apploader_Run(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryStrin return (u32)appldr_final(); } -void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo, bool patchregion , u8 private_server, u8 bootType) +void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo, bool patchregion , u8 private_server, u8 deflicker, u8 bootType) { + u8 vfilter_off[7] = {0, 0, 21, 22, 21, 0, 0}; + u8 vfilter_low[7] = {4, 4, 16, 16, 16, 4, 4}; + u8 vfilter_medium[7] = {4, 8, 12, 16, 12, 8, 4}; + u8 vfilter_high[7] = {8, 8, 10, 12, 10, 8, 8}; + do_wip_code((u8 *)dst, len); Remove_001_Protection(dst, len); if(CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13) @@ -161,7 +166,31 @@ void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipa if(patchregion) PatchRegion(dst, len); if(private_server) - PrivateServerPatcher(dst,len, private_server); + PrivateServerPatcher(dst,len, private_server); + + if(deflicker == DEFLICKER_ON_LOW) + { + patch_vfilters(dst, len, vfilter_low); + patch_vfilters_rogue(dst, len, vfilter_low); + } + else if(deflicker == DEFLICKER_ON_MEDIUM) + { + patch_vfilters(dst, len, vfilter_medium); + patch_vfilters_rogue(dst, len, vfilter_medium); + } + else if(deflicker == DEFLICKER_ON_HIGH) + { + patch_vfilters(dst, len, vfilter_high); + patch_vfilters_rogue(dst, len, vfilter_high); + } + else if(deflicker != DEFLICKER_NORMAL) // Either safe or extended + { + patch_vfilters(dst, len, vfilter_off); + patch_vfilters_rogue(dst, len, vfilter_off); + // This might break fade and brightness effects + if (deflicker == DEFLICKER_OFF_EXTENDED) + deflicker_patch(dst, len); + } } static void patch_NoDiscinDrive(void *buffer, u32 len) diff --git a/resources/wiiflow_game_booter/source/apploader.h b/resources/wiiflow_game_booter/source/apploader.h index eb0ffd57..c01fefc6 100644 --- a/resources/wiiflow_game_booter/source/apploader.h +++ b/resources/wiiflow_game_booter/source/apploader.h @@ -7,7 +7,7 @@ extern "C" { /* Prototypes */ u32 Apploader_Run(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo, - bool patchregion, u8 private_server, bool patchFix480p, u8 bootType); + bool patchregion, u8 private_server, bool patchFix480p, u8 deflicker, u8 bootType); enum { @@ -18,6 +18,16 @@ enum }; +enum +{ + DEFLICKER_NORMAL, + DEFLICKER_OFF, + DEFLICKER_OFF_EXTENDED, + DEFLICKER_ON_LOW, + DEFLICKER_ON_MEDIUM, + DEFLICKER_ON_HIGH +}; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/resources/wiiflow_game_booter/source/main.cpp b/resources/wiiflow_game_booter/source/main.cpp index 4964b2d2..478981d9 100644 --- a/resources/wiiflow_game_booter/source/main.cpp +++ b/resources/wiiflow_game_booter/source/main.cpp @@ -107,7 +107,7 @@ int main() 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, normalCFG.BootType); + normalCFG.returnTo, normalCFG.patchregion, normalCFG.private_server, normalCFG.patchFix480p, normalCFG.deflicker, normalCFG.BootType); WDVD_Close(); } else if(normalCFG.BootType == TYPE_CHANNEL) @@ -117,7 +117,7 @@ int main() vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg); AppEntrypoint = LoadChannel(normalCFG.title, normalCFG.use_dol, &GameIOS); PatchChannel(normalCFG.vidMode, vmode, normalCFG.vipatch, normalCFG.countryString, normalCFG.patchVidMode, normalCFG.aspectRatio, - normalCFG.private_server, normalCFG.patchFix480p, normalCFG.BootType); + normalCFG.private_server, normalCFG.patchFix480p, normalCFG.deflicker, normalCFG.BootType); ISFS_Deinitialize(); } gprintf("Entrypoint: %08x, Requested Game IOS: %i\n", AppEntrypoint, GameIOS); diff --git a/resources/wiiflow_game_booter/source/patchcode.c b/resources/wiiflow_game_booter/source/patchcode.c index 983e12e9..ba4aa5a6 100644 --- a/resources/wiiflow_game_booter/source/patchcode.c +++ b/resources/wiiflow_game_booter/source/patchcode.c @@ -184,6 +184,20 @@ unsigned char patch_setting[44] = 0x00, 0x00, 0x00, 0x00, }; +const u8 PATTERN[12][2] = { + {6, 6}, {6, 6}, {6, 6}, + {6, 6}, {6, 6}, {6, 6}, + {6, 6}, {6, 6}, {6, 6}, + {6, 6}, {6, 6}, {6, 6} +}; + +const u8 PATTERN_AA[12][2] = { + {3, 2}, {9, 6}, {3, 10}, + {3, 2}, {9, 6}, {3, 10}, + {9, 2}, {3, 6}, {9, 10}, + {9, 2}, {3, 6}, {9, 10} +}; + bool dogamehooks(void *addr, u32 len, bool channel) { /* @@ -1309,3 +1323,83 @@ u32 do_new_wiimmfi() { // returns 0 when all patching is done and game is ready to be booted. return 0; } + +// Deflicker filter patching by wiidev (blackb0x @ GBAtemp) +void patch_vfilters(void *addr, u32 len, u8 *vfilter) +{ + u8 *addr_start = addr; + while (len >= sizeof(GXRModeObj)) + { + GXRModeObj *vidmode = (GXRModeObj *)addr_start; + if ((memcmp(vidmode->sample_pattern, PATTERN, 24) == 0 || memcmp(vidmode->sample_pattern, PATTERN_AA, 24) == 0) && + (vidmode->fbWidth == 640 || vidmode->fbWidth == 608 || vidmode->fbWidth == 512) && + (vidmode->field_rendering == 0 || vidmode->field_rendering == 1) && + (vidmode->aa == 0 || vidmode->aa == 1)) + { + gprintf("Replaced vfilter %02x%02x%02x%02x%02x%02x%02x @ %p (GXRModeObj)\n", + vidmode->vfilter[0], vidmode->vfilter[1], vidmode->vfilter[2], vidmode->vfilter[3], + vidmode->vfilter[4], vidmode->vfilter[5], vidmode->vfilter[6], addr_start); + memcpy(vidmode->vfilter, vfilter, 7); + addr_start += (sizeof(GXRModeObj) - 4); + len -= (sizeof(GXRModeObj) - 4); + } + addr_start += 4; + len -= 4; + } +} + +void patch_vfilters_rogue(void *addr, u32 len, u8 *vfilter) +{ + u8 known_vfilters[7][7] = { + {8, 8, 10, 12, 10, 8, 8}, + {4, 8, 12, 16, 12, 8, 4}, + {7, 7, 12, 12, 12, 7, 7}, + {5, 5, 15, 14, 15, 5, 5}, + {4, 4, 15, 18, 15, 4, 4}, + {4, 4, 16, 16, 16, 4, 4}, + {2, 2, 17, 22, 17, 2, 2} + }; + u8 *addr_start = addr; + u8 *addr_end = addr + len - 8; + while (addr_start <= addr_end) + { + u8 known_vfilter[7]; + for (int i = 0; i < 7; i++) + { + for (int x = 0; x < 7; x++) + known_vfilter[x] = known_vfilters[i][x]; + if (!addr_start[7] && memcmp(addr_start, known_vfilter, 7) == 0) + { + gprintf("Replaced vfilter %02x%02x%02x%02x%02x%02x%02x @ %p\n", addr_start[0], addr_start[1], addr_start[2], + addr_start[3], addr_start[4], addr_start[5], addr_start[6], addr_start); + memcpy(addr_start, vfilter, 7); + addr_start += 7; + break; + } + } + addr_start += 1; + } +} + +void deflicker_patch(void *addr, u32 len) +{ + u32 SearchPattern[18] = { + 0x3D20CC01, 0x39400061, 0x99498000, + 0x2C050000, 0x38800053, 0x39600000, + 0x90098000, 0x38000054, 0x39800000, + 0x508BC00E, 0x99498000, 0x500CC00E, + 0x90698000, 0x99498000, 0x90E98000, + 0x99498000, 0x91098000, 0x41820040}; + u8 *addr_start = addr; + u8 *addr_end = addr + len - sizeof(SearchPattern); + while (addr_start <= addr_end) + { + if (memcmp(addr_start, SearchPattern, sizeof(SearchPattern)) == 0) + { + *((u32 *)addr_start + 17) = 0x48000040; // Change beq to b + gprintf("Patched GXSetCopyFilter @ %p\n", addr_start); + return; + } + addr_start += 4; + } +} diff --git a/resources/wiiflow_game_booter/source/patchcode.h b/resources/wiiflow_game_booter/source/patchcode.h index 0a747e81..819ae89c 100644 --- a/resources/wiiflow_game_booter/source/patchcode.h +++ b/resources/wiiflow_game_booter/source/patchcode.h @@ -30,6 +30,9 @@ extern u32 hooktype; extern u8 configbytes[2]; // Function prototypes +void deflicker_patch(void *addr, u32 len); +void patch_vfilters(void *addr, u32 len, u8 *vfilter); +void patch_vfilters_rogue(void *addr, u32 len, u8 *vfilter); bool dogamehooks(void *addr, u32 len, bool channel); void langpatcher(void *addr, u32 len); void vidolpatcher(void *addr, u32 len); diff --git a/source/booter/Config.h b/source/booter/Config.h index 4191e99f..b734a2d5 100644 --- a/source/booter/Config.h +++ b/source/booter/Config.h @@ -48,6 +48,7 @@ struct the_CFG { u8 vipatch; s8 aspectRatio; bool patchFix480p; + u8 deflicker; u8 private_server; u8 *cheats; u32 cheatSize; diff --git a/source/booter/external_booter.cpp b/source/booter/external_booter.cpp index f41373f1..4a1824e0 100644 --- a/source/booter/external_booter.cpp +++ b/source/booter/external_booter.cpp @@ -62,7 +62,7 @@ u8 *booter_ptr = NULL; u32 booter_size = 0; void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, s8 aspectRatio, u8 private_server, bool patchFix480p, - u32 returnTo, u8 BootType, bool use_led) + u8 deflicker, u32 returnTo, u8 BootType, bool use_led) { normalCFG.vidMode = vidMode; normalCFG.vipatch = vipatch; @@ -71,6 +71,7 @@ void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 pat normalCFG.aspectRatio = aspectRatio; normalCFG.private_server = private_server; normalCFG.patchFix480p = patchFix480p; + normalCFG.deflicker = deflicker; normalCFG.returnTo = returnTo; normalCFG.configbytes[0] = configbytes[0]; normalCFG.configbytes[1] = configbytes[1]; diff --git a/source/booter/external_booter.hpp b/source/booter/external_booter.hpp index a76b5bb3..c48ae06c 100644 --- a/source/booter/external_booter.hpp +++ b/source/booter/external_booter.hpp @@ -29,7 +29,7 @@ extern u32 hooktype; #endif void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, s8 aspectRatio, u8 private_server, bool patchFix480p, - u32 returnTo, u8 BootType, bool use_led); + u8 deflicker, u32 returnTo, u8 BootType, bool use_led); bool ExternalBooter_LoadBins(const char *binDir); void ExternalBooter_ChannelSetup(u64 title, bool dol); void ExternalBooter_WiiGameSetup(bool wbfs, bool dvd, bool patchregion, const char *ID); diff --git a/source/menu/menu.hpp b/source/menu/menu.hpp index 3fd64b08..c7251000 100644 --- a/source/menu/menu.hpp +++ b/source/menu/menu.hpp @@ -339,7 +339,12 @@ private: s16 m_config7Lbl4; s16 m_config7Btn1; s16 m_config7Btn2; + s16 m_config7Btn3; + s16 m_config7Lbl3Val; + s16 m_config7Btn3M; + s16 m_config7Btn3P; + s16 m_config7Btn4; s16 m_config7Lbl4Val; s16 m_config7Btn4M; @@ -590,6 +595,11 @@ private: s16 m_gameSettingsLblFix480p; s16 m_gameSettingsBtnFix480p; + + s16 m_gameSettingsLblDeflickerWii; + s16 m_gameSettingsLblDeflickerWiiVal; + s16 m_gameSettingsBtnDeflickerWiiM; + s16 m_gameSettingsBtnDeflickerWiiP; s16 m_gameSettingsLblManage; s16 m_gameSettingsBtnManage; @@ -1292,7 +1302,9 @@ private: static const SOption _GlobalVideoModes[6]; static const SOption _VideoModes[7]; static const SOption _languages[11]; - + + static const SOption _GlobalDeflickerOptions[6]; + static const SOption _DeflickerOptions[7]; static const SOption _GlobalGCvideoModes[6]; static const SOption _GlobalGClanguages[7]; static const SOption _GCvideoModes[7]; diff --git a/source/menu/menu_config7.cpp b/source/menu/menu_config7.cpp index e6bde39c..b510c861 100644 --- a/source/menu/menu_config7.cpp +++ b/source/menu/menu_config7.cpp @@ -1,6 +1,11 @@ #include "menu.hpp" +template static inline T loopNum(T i, T s) +{ + return (i + s) % s; +} + void CMenu::_hideConfig7(bool instant) { _hideConfigCommon(instant); @@ -13,6 +18,10 @@ void CMenu::_hideConfig7(bool instant) m_btnMgr.hide(m_config7Btn3, instant); m_btnMgr.hide(m_config7Lbl4, instant); m_btnMgr.hide(m_config7Btn4, instant); + + m_btnMgr.hide(m_config7Lbl3Val, instant); + m_btnMgr.hide(m_config7Btn3M, instant); + m_btnMgr.hide(m_config7Btn3P, instant); m_btnMgr.hide(m_config7Lbl4Val, instant); m_btnMgr.hide(m_config7Btn4M, instant); @@ -36,6 +45,10 @@ void CMenu::_showConfig7(int curPage) m_btnMgr.hide(m_config7Lbl4, true); m_btnMgr.hide(m_config7Btn4, true); + m_btnMgr.hide(m_config7Lbl3Val, true); + m_btnMgr.hide(m_config7Btn3M, true); + m_btnMgr.hide(m_config7Btn3P, true); + m_btnMgr.hide(m_config7Lbl4Val, true); m_btnMgr.hide(m_config7Btn4M, true); m_btnMgr.hide(m_config7Btn4P, true); @@ -59,6 +72,13 @@ void CMenu::_showConfig7(int curPage) if(curPage == 7 || curPage == 11 || curPage == 12 || curPage == 13) m_btnMgr.show(m_config7Btn4); + else if(curPage == 14) + { + m_btnMgr.show(m_config7Lbl3); + m_btnMgr.show(m_config7Lbl3Val); + m_btnMgr.show(m_config7Btn3M); + m_btnMgr.show(m_config7Btn3P); + } else if(curPage != 14) { m_btnMgr.show(m_config7Lbl4Val); @@ -149,6 +169,9 @@ void CMenu::_showConfig7(int curPage) m_btnMgr.setText(m_config7Btn1, m_cfg.getBool("PROXY", "proxy_use_system") ? _t("on", L"On") : _t("off", L"Off")); m_btnMgr.setText(m_config7Lbl2, _t("cfg730", L"Always show main icons")); m_btnMgr.setText(m_config7Btn2, !m_cfg.getBool("GENERAL", "auto_hide_icons", true) ? _t("yes", L"Yes") : _t("no", L"No")); + m_btnMgr.setText(m_config7Lbl3, _t("cfgg61", L"Deflicker Filter")); + int i = min(max(0, m_cfg.getInt("GENERAL", "deflicker_wii", 0)), (int)ARRAY_SIZE(CMenu::_GlobalDeflickerOptions) - 1); + m_btnMgr.setText(m_config7Lbl3Val, _t(CMenu::_GlobalDeflickerOptions[i].id, CMenu::_GlobalDeflickerOptions[i].text)); } } @@ -372,6 +395,13 @@ int CMenu::_config7(int curPage) m_btnMgr.setText(m_config7Btn2, !val ? _t("yes", L"Yes") : _t("no", L"No")); Auto_hide_icons = val; } + else if(m_btnMgr.selected(m_config7Btn3P) || m_btnMgr.selected(m_config7Btn3M)) + { + s8 direction = m_btnMgr.selected(m_config7Btn3P) ? 1 : -1; + m_cfg.setInt("GENERAL", "deflicker_wii", loopNum(m_cfg.getUInt("GENERAL", "deflicker_wii") + direction, ARRAY_SIZE(CMenu::_GlobalDeflickerOptions))); + int val = m_cfg.getInt("GENERAL", "deflicker_wii"); + m_btnMgr.setText(m_config7Lbl3Val, _t(CMenu::_GlobalDeflickerOptions[val].id, CMenu::_GlobalDeflickerOptions[val].text)); + } } } } @@ -402,6 +432,10 @@ void CMenu::_initConfig7Menu() m_config7Btn3 = _addButton("CONFIG7/LINE3_BTN", theme.btnFont, L"", 420, 250, 200, 48, theme.btnFontColor); m_config7Lbl4 = _addLabel("CONFIG7/LINE4", theme.lblFont, L"", 20, 305, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE); m_config7Btn4 = _addButton("CONFIG7/LINE4_BTN", theme.btnFont, L"", 420, 310, 200, 48, theme.btnFontColor); + + m_config7Lbl3Val = _addLabel("CONFIG7/LINE3_VAL", theme.btnFont, L"", 468, 250, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC); + m_config7Btn3M = _addPicButton("CONFIG7/LINE3_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 420, 250, 48, 48); + m_config7Btn3P = _addPicButton("CONFIG7/LINE3_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 572, 250, 48, 48); m_config7Lbl4Val = _addLabel("CONFIG7/LINE4_VAL", theme.btnFont, L"", 468, 310, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC); m_config7Btn4M = _addPicButton("CONFIG7/LINE4_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 420, 310, 48, 48); @@ -415,6 +449,10 @@ void CMenu::_initConfig7Menu() _setHideAnim(m_config7Btn3, "CONFIG7/LINE3_BTN", -50, 0, 1.f, 0.f); _setHideAnim(m_config7Lbl4, "CONFIG7/LINE4", 50, 0, -2.f, 0.f); _setHideAnim(m_config7Btn4, "CONFIG7/LINE4_BTN", -50, 0, 1.f, 0.f); + + _setHideAnim(m_config7Lbl3Val, "CONFIG7/LINE3_VAL", -50, 0, 1.f, 0.f); + _setHideAnim(m_config7Btn3M, "CONFIG7/LINE3_MINUS", -50, 0, 1.f, 0.f); + _setHideAnim(m_config7Btn3P, "CONFIG7/LINE3_PLUS", -50, 0, 1.f, 0.f); _setHideAnim(m_config7Lbl4Val, "CONFIG7/LINE4_VAL", -50, 0, 1.f, 0.f); _setHideAnim(m_config7Btn4M, "CONFIG7/LINE4_MINUS", -50, 0, 1.f, 0.f); diff --git a/source/menu/menu_config_game.cpp b/source/menu/menu_config_game.cpp index f492c278..1cad40da 100644 --- a/source/menu/menu_config_game.cpp +++ b/source/menu/menu_config_game.cpp @@ -31,6 +31,25 @@ const CMenu::SOption CMenu::_VideoModes[7] = { { "vidprog", L"Progressive" }, }; +const CMenu::SOption CMenu::_GlobalDeflickerOptions[6] = { + { "df_norm", L"Normal" }, + { "df_off", L"Off (Safe)" }, + { "df_ext", L"Off (Extended)" }, + { "df_low", L"On (Low)" }, + { "df_med", L"On (Medium)" }, + { "df_high", L"On (High)" }, +}; + +const CMenu::SOption CMenu::_DeflickerOptions[7] = { + { "df_def", L"Default" }, + { "df_norm", L"Normal" }, + { "df_off", L"Off (Safe)" }, + { "df_ext", L"Off (Extended)" }, + { "df_low", L"On (Low)" }, + { "df_med", L"On (Medium)" }, + { "df_high", L"On (High)" }, +}; + const CMenu::SOption CMenu::_GlobalGCvideoModes[6] = { { "vidgame", L"Game" }, { "vidp50", L"PAL 50Hz" }, @@ -234,6 +253,10 @@ void CMenu::_hideGameSettingsPg(bool instant) m_btnMgr.hide(m_gameSettingsBtnPrivateServerM, instant); m_btnMgr.hide(m_gameSettingsLblFix480p, instant); m_btnMgr.hide(m_gameSettingsBtnFix480p, instant); + m_btnMgr.hide(m_gameSettingsLblDeflickerWii, instant); + m_btnMgr.hide(m_gameSettingsLblDeflickerWiiVal, instant); + m_btnMgr.hide(m_gameSettingsBtnDeflickerWiiP, instant); + m_btnMgr.hide(m_gameSettingsBtnDeflickerWiiM, instant); //All m_btnMgr.hide(m_gameSettingsLblManage, instant); m_btnMgr.hide(m_gameSettingsBtnManage, instant); @@ -569,6 +592,11 @@ void CMenu::_showGameSettings() m_btnMgr.show(m_gameSettingsLblFix480p); m_btnMgr.show(m_gameSettingsBtnFix480p); + + m_btnMgr.show(m_gameSettingsLblDeflickerWii); + m_btnMgr.show(m_gameSettingsLblDeflickerWiiVal); + m_btnMgr.show(m_gameSettingsBtnDeflickerWiiM); + m_btnMgr.show(m_gameSettingsBtnDeflickerWiiP); //} } } @@ -642,6 +670,10 @@ void CMenu::_showGameSettings() m_btnMgr.setText(m_gameSettingsLblPrivateServerVal, _t(CMenu::_privateServer[i].id, CMenu::_privateServer[i].text)); m_btnMgr.setText(m_gameSettingsBtnFix480p, _optBoolToString(m_gcfg2.getOptBool(id, "fix480p", 2))); + + i = min(m_gcfg2.getUInt(id, "deflicker_wii", 0), ARRAY_SIZE(CMenu::_DeflickerOptions) - 1u); + m_btnMgr.setText(m_gameSettingsLblDeflickerWiiVal, _t(CMenu::_DeflickerOptions[i].id, CMenu::_DeflickerOptions[i].text)); + m_btnMgr.setText(m_gameSettingsBtnCustom, _optBoolToString(m_gcfg2.getOptBool(id, "custom", 0))); m_btnMgr.setText(m_gameSettingsBtnLaunchNK, _optBoolToString(m_gcfg2.getOptBool(id, "useneek", 0))); m_btnMgr.setText(m_gameSettingsBtnApploader, _optBoolToString(m_gcfg2.getOptBool(id, "apploader", 0))); @@ -997,6 +1029,12 @@ void CMenu::_gameSettings(const dir_discHdr *hdr, bool disc) m_gcfg2.setOptBool(id, "fix480p", loopNum(m_gcfg2.getOptBool(id, "fix480p") + 1, 3)); _showGameSettings(); } + else if(m_btnMgr.selected(m_gameSettingsBtnDeflickerWiiP) || m_btnMgr.selected(m_gameSettingsBtnDeflickerWiiM)) + { + s8 direction = m_btnMgr.selected(m_gameSettingsBtnDeflickerWiiP) ? 1 : -1; + m_gcfg2.setInt(id, "deflicker_wii", loopNum(m_gcfg2.getUInt(id, "deflicker_wii") + direction, ARRAY_SIZE(CMenu::_DeflickerOptions))); + _showGameSettings(); + } else if(m_btnMgr.selected(m_gameSettingsBtnAdultOnly)) { if(disc) @@ -1170,6 +1208,12 @@ void CMenu::_initGameSettingsMenu() m_gameSettingsLblFix480p = _addLabel("GAME_SETTINGS/FIX480P", theme.lblFont, L"", 20, 245, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE); m_gameSettingsBtnFix480p = _addButton("GAME_SETTINGS/FIX480P_BTN", theme.btnFont, L"", 420, 250, 200, 48, theme.btnFontColor); + + m_gameSettingsLblDeflickerWii = _addLabel("GAME_SETTINGS/DEFLICKER_WII", theme.lblFont, L"", 20, 305, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE); + m_gameSettingsLblDeflickerWiiVal = _addLabel("GAME_SETTINGS/DEFLICKER_WII_BTN", theme.btnFont, L"", 468, 310, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC); + m_gameSettingsBtnDeflickerWiiM = _addPicButton("GAME_SETTINGS/DEFLICKER_WII_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 420, 310, 48, 48); + m_gameSettingsBtnDeflickerWiiP = _addPicButton("GAME_SETTINGS/DEFLICKER_WII_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 572, 310, 48, 48); + //GC m_gameSettingsLblWidth = _addLabel("GAME_SETTINGS/NIN_WIDTH", theme.lblFont, L"", 20, 185, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE); m_gameSettingsLblWidthVal = _addLabel("GAME_SETTINGS/NIN_WIDTH_BTN", theme.btnFont, L"", 468, 190, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC); @@ -1235,6 +1279,11 @@ void CMenu::_initGameSettingsMenu() _setHideAnim(m_gameSettingsLblFix480p, "GAME_SETTINGS/FIX480P", 50, 0, -2.f, 0.f); _setHideAnim(m_gameSettingsBtnFix480p, "GAME_SETTINGS/FIX480P_BTN", -50, 0, 1.f, 0.f); + _setHideAnim(m_gameSettingsLblDeflickerWii, "GAME_SETTINGS/DEFLICKER_WII", 50, 0, -2.f, 0.f); + _setHideAnim(m_gameSettingsLblDeflickerWiiVal, "GAME_SETTINGS/DEFLICKER_WII_BTN", -50, 0, 1.f, 0.f); + _setHideAnim(m_gameSettingsBtnDeflickerWiiM, "GAME_SETTINGS/DEFLICKER_WII_MINUS", -50, 0, 1.f, 0.f); + _setHideAnim(m_gameSettingsBtnDeflickerWiiP, "GAME_SETTINGS/DEFLICKER_WII_PLUS", -50, 0, 1.f, 0.f); + _setHideAnim(m_gameSettingsLblVipatch, "GAME_SETTINGS/VIPATCH", 50, 0, -2.f, 0.f); _setHideAnim(m_gameSettingsBtnVipatch, "GAME_SETTINGS/VIPATCH_BTN", -50, 0, 1.f, 0.f); @@ -1400,4 +1449,5 @@ void CMenu::_textGameSettings(void) m_btnMgr.setText(m_gameSettingsLblFix480p, _t("cfgg49", L"480p Pixel Patch")); m_btnMgr.setText(m_gameSettingsLblWidth, _t("cfgg54", L"Video Width")); m_btnMgr.setText(m_gameSettingsLblPos, _t("cfgg55", L"Video Position")); + m_btnMgr.setText(m_gameSettingsLblDeflickerWii, _t("cfgg61", L"Deflicker Filter")); } diff --git a/source/menu/menu_game_boot.cpp b/source/menu/menu_game_boot.cpp index 654053fa..291c0079 100644 --- a/source/menu/menu_game_boot.cpp +++ b/source/menu/menu_game_boot.cpp @@ -781,6 +781,8 @@ void CMenu::_launchChannel(dir_discHdr *hdr) u8 private_server = m_gcfg2.getUInt(id, "private_server", 0); int fix480pVal = m_gcfg2.getOptBool(id, "fix480p", 2); bool fix480p = fix480pVal == 0 ? false : (fix480pVal == 1 ? true : m_cfg.getBool(WII_DOMAIN, "fix480p", false)); + u8 deflicker = min(m_gcfg2.getUInt(id, "deflicker_wii", 0), ARRAY_SIZE(CMenu::_DeflickerOptions) - 1u); + deflicker = (deflicker == 0) ? min(m_cfg.getUInt("GENERAL", "deflicker_wii", 0), ARRAY_SIZE(CMenu::_GlobalDeflickerOptions) - 1u) : deflicker - 1; u32 returnTo = 0; const char *rtrn = m_cfg.getString("GENERAL", "returnto").c_str(); @@ -909,7 +911,7 @@ void CMenu::_launchChannel(dir_discHdr *hdr) Identify(gameTitle); ExternalBooter_ChannelSetup(gameTitle, use_dol); - WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, private_server, fix480p, 0, TYPE_CHANNEL, use_led); + WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, private_server, fix480p, deflicker, 0, TYPE_CHANNEL, use_led); } Sys_Exit(); } @@ -986,6 +988,9 @@ void CMenu::_launchWii(dir_discHdr *hdr, bool dvd, bool disc_cfg) int fix480pVal = m_gcfg2.getOptBool(id, "fix480p", 2); bool fix480p = fix480pVal == 0 ? false : (fix480pVal == 1 ? true : m_cfg.getBool(WII_DOMAIN, "fix480p", false)); + u8 deflicker = min(m_gcfg2.getUInt(id, "deflicker_wii", 0), ARRAY_SIZE(CMenu::_DeflickerOptions) - 1u); + deflicker = (deflicker == 0) ? min(m_cfg.getUInt("GENERAL", "deflicker_wii", 0), ARRAY_SIZE(CMenu::_GlobalDeflickerOptions) - 1u) : deflicker-1; + u8 videoMode = min(m_gcfg2.getUInt(id, "video_mode", 0), ARRAY_SIZE(CMenu::_VideoModes) - 1u); videoMode = (videoMode == 0) ? min(m_cfg.getUInt("GENERAL", "video_mode", 0), ARRAY_SIZE(CMenu::_GlobalVideoModes) - 1u) : videoMode-1; @@ -1171,7 +1176,7 @@ void CMenu::_launchWii(dir_discHdr *hdr, bool dvd, bool disc_cfg) } ExternalBooter_WiiGameSetup(wbfs_partition, dvd, patchregion, id.c_str()); - WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, private_server, fix480p, returnTo, TYPE_WII_GAME, use_led); + WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, private_server, fix480p, deflicker, returnTo, TYPE_WII_GAME, use_led); Sys_Exit(); } diff --git a/wii/wiiflow/Languages/english.ini b/wii/wiiflow/Languages/english.ini index c419caed..1fff21d5 100644 --- a/wii/wiiflow/Languages/english.ini +++ b/wii/wiiflow/Languages/english.ini @@ -167,6 +167,7 @@ cfgg57=Not allowed for disc! cfgg58=Adult only cfgg59=BBA Emulation cfgg60=BBA Net Profile +cfgg61=Deflicker Filter cfgg4=Patch country strings cfgg5=Ocarina cfgg6= @@ -255,6 +256,13 @@ custom=Custom def=Default deltcover=Cover is deleted. deltbanner=Banner is deleted. +df_def=Default +df_ext=Off (Extended) +df_high=On (High) +df_low=On (Low) +df_med=On (Medium) +df_norm=Normal +df_off=Off (Safe) disabled=Disabled discq=This game has multiple discs. Please select the disc to launch. disc1=Disc 1