- added extremes 480p pixel patch via leseratte's usbloader gx code. only for wii games. there is a global default setting in main settings pg 13

and each game has a setting on page 5 that can be default, off, or on.
This commit is contained in:
Fledge68 2019-09-23 09:20:22 -05:00
parent 6e5c168185
commit 7eeaf4e053
18 changed files with 167 additions and 21 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 MiB

After

Width:  |  Height:  |  Size: 3.4 MiB

View File

@ -33,6 +33,7 @@ struct the_CFG {
bool use_led;
bool patchregion;
bool private_server;
bool patchFix480p;
/* needed for channels */
u64 title;
bool use_dol;

View File

@ -48,7 +48,8 @@ static struct
s32 padding;
} apploader_hdr ATTRIBUTE_ALIGN(32);
u32 Apploader_Run(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo, bool patchregion , bool private_server)
u32 Apploader_Run(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo,
bool patchregion , bool private_server, bool patchFix480p)
{
PrinceOfPersiaPatch();
NewSuperMarioBrosPatch();
@ -103,7 +104,10 @@ u32 Apploader_Run(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryStrin
free_wip();
if(hooktype != 0 && hookpatched)
ocarina_do_code();
if(patchFix480p)
PatchFix480p();
MarioKartWiiWiimmfiPatch(private_server);
/* Set entry point from apploader */

View File

@ -6,8 +6,8 @@ extern "C" {
#endif /* __cplusplus */
/* Prototypes */
u32 Apploader_Run(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString,
u8 patchVidModes, int aspectRatio, u32 returnTo, bool patchregion, bool private_server);
u32 Apploader_Run(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo,
bool patchregion, bool private_server, bool patchFix480p);
#ifdef __cplusplus
}

View File

@ -106,8 +106,8 @@ int main()
Disc_FindPartition(&offset);
WDVD_OpenPartition(offset, &GameIOS);
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);
AppEntrypoint = Apploader_Run(normalCFG.vidMode, vmode, normalCFG.vipatch, normalCFG.countryString, normalCFG.patchVidMode, normalCFG.aspectRatio,
normalCFG.returnTo, normalCFG.patchregion, normalCFG.private_server, normalCFG.patchFix480p);
WDVD_Close();
}
else if(normalCFG.BootType == TYPE_CHANNEL)

View File

@ -686,6 +686,107 @@ void domainpatcher(void *addr, u32 len, const char* domain)
while (++cur < end);
}
/** 480p Pixel Fix Patch by leseratte
fix for a Nintendo Revolution SDK bug found by Extrems affecting early Wii console when using 480p video mode.
https://shmups.system11.org/viewtopic.php?p=1361158#p1361158
https://github.com/ExtremsCorner/libogc-rice/commit/941d687e271fada68c359bbed98bed1fbb454448
**/
void PatchFix480p()
{
u8 prefix[2] = { 0x4b, 0xff };
/// Patch offset: ----------VVVVVVVV
u32 Pattern_MKW[8] = { 0x38000065, 0x9b810019, 0x38810018, 0x386000e0, 0x98010018, 0x38a00002};
u32 patches_MKW[2] = { 0x38600003, 0x98610019 };
/// Used by: MKWii, Wii Play, Need for Speed Nitro, Wii Sports, ...
/// Patch offset: ----------------------------------------------VVVVVVVV
u32 Pattern_NSMB[8] = { 0x38000065, 0x9801001c, 0x3881001c, 0x386000e0, 0x9b81001d, 0x38a00002};
u32 patches_NSMB[2] = { 0x38a00003, 0x98a1001d };
/// Used by: New Super Mario Bros, ...
/*
* Code block that is being patched (in MKW):
*
* 4bffe30d: bl WaitMicroTime
* 38000065: li r0, 0x65
* 9b810019: stb r28, 25(r1) // store the wrong value (1)
* 38810018: addi r4, r1, 0x18
* 386000e0: li r3, 0xe0
* 98010018: stb r0, 24(r1)
* 38a00002: li r5, 2
* 4bffe73d: bl __VISendI2CData
*
* r28 is a register that is set to 1 at the beginning of the function.
* However, its contents are used elsewhere as well, so we can't just modify this one function.
*
* The following code first searches for one of the patterns above, then replaces the
* "stb r28, 25(r1)" instruction that stores the wrong value on the stack with a branch instead
* That branch branches to the injected custom code ("li r3, 3; stb r3, 25(r1)") that stores the
* correct value (3) instead. At the end of the injected code will be another branch that branches
* back to the instruction after the one that has been replaced (so, to "addi r4, r1, 0x18").
* r3 can safely be used as a temporary register because its contents will be replaced immediately
* afterwards anyways.
*
*/
void * offset = NULL;
void * addr = (void*)0x80000000;
u32 len = 0x900000;
void * patch_ptr = 0 ;
void * a = addr;
while ((char*)a < ((char*)addr + len)) {
if (memcmp(a, &Pattern_MKW, 6 * 4) == 0) {
// Found pattern?
if (memcmp(a - 4, &prefix, 2) == 0) {
if (memcmp(a + 8*4, &prefix, 2) == 0) {
offset = a + 4;
//hexdump (a, 30);
patch_ptr = &patches_MKW;
break;
}
}
}
else if (memcmp(a, &Pattern_NSMB, 6 * 4) == 0) {
// Found pattern?
if (memcmp(a - 4, &prefix, 2) == 0) {
if (memcmp(a + 8*4, &prefix, 2) == 0) {
offset = a + 16;
//hexdump (a, 30);
patch_ptr = &patches_NSMB;
break;
}
}
}
a+= 4;
}
if (offset == 0) {
// offset is still 0, we didn't find the pattern, return
gprintf("Didn't find offset for 480p patch!\n");
return;
}
// If we are here, we found the offset. Lets grab some space
// from the heap for our patch
u32 old_heap_ptr = *(u32*)0x80003110;
*((u32*)0x80003110) = (old_heap_ptr - 0x20);
u32 heap_space = old_heap_ptr-0x20;
gprintf("Found offset for 480p patch - create branch from 0x%x to heap (0x%x)\n", offset, heap_space);
//hexdump (offset, 30);
memcpy((void*)heap_space, patch_ptr, 8);
*((u32*)offset) = 0x48000000 + (((u32)(heap_space) - ((u32)(offset))) & 0x3ffffff);
*((u32*)((u32)heap_space + 8)) = 0x48000000 + (((u32)((u32)offset + 4) - ((u32)(heap_space + 8))) & 0x3ffffff);
return;
}
u32 do_new_wiimmfi() {
// As of November 2018, Wiimmfi requires a special Wiimmfi patcher

View File

@ -40,6 +40,7 @@ bool PatchReturnTo(void *Address, int Size, u32 id);
void Patch_fwrite(void *Address, int Size);
s32 BlockIOSReload(void);
void PatchRegion(void *Address, int Size);
void PatchFix480p();
u32 do_new_wiimmfi();
void PrivateServerPatcher(void *addr, u32 len);
void domainpatcher(void *addr, u32 len, const char* domain);

View File

@ -33,6 +33,7 @@ struct the_CFG {
bool use_led;
bool patchregion;
bool private_server;
bool patchFix480p;
/* needed for channels */
u64 title;
bool use_dol;

View File

@ -126,7 +126,7 @@ bool ExternalBooter_LoadBins(const char *binDir)
extern FragList *frag_list;
extern s32 wbfsDev;
extern u32 wbfs_part_idx;
void ExternalBooter_WiiGameSetup(bool wbfs, bool dvd, bool patchregion, bool private_server, const char *ID)
void ExternalBooter_WiiGameSetup(bool wbfs, bool dvd, bool patchregion, bool private_server, bool patchFix480p, const char *ID)
{
memset(&normalCFG, 0, sizeof(the_CFG));
normalCFG.GameBootType = dvd ? TYPE_WII_DISC : (wbfs ? TYPE_WII_WBFS : TYPE_WII_WBFS_EXT);
@ -136,6 +136,7 @@ void ExternalBooter_WiiGameSetup(bool wbfs, bool dvd, bool patchregion, bool pri
normalCFG.wbfsPart = wbfs_part_idx;
normalCFG.patchregion = patchregion;
normalCFG.private_server = private_server;
normalCFG.patchFix480p = patchFix480p;
}
void ExternalBooter_ChannelSetup(u64 title, bool dol)

View File

@ -32,7 +32,7 @@ void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 pat
int aspectRatio, 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, bool private_server, const char *ID);
void ExternalBooter_WiiGameSetup(bool wbfs, bool dvd, bool patchregion, bool private_server, bool patchFix480p, const char *ID);
void ShutdownBeforeExit(void);
#endif

View File

@ -6,7 +6,7 @@
#else
#define APP_NAME "WiiFlow Lite"
#endif
#define APP_VERSION "5.3.0 beta 7"
#define APP_VERSION "5.3.0 beta 8"
#define APP_DATA_DIR "wiiflow"
#ifdef APP_WIIFLOW

View File

@ -551,6 +551,9 @@ private:
s16 m_gameSettingsLblPrivateServer;
s16 m_gameSettingsBtnPrivateServer;
s16 m_gameSettingsLblFix480p;
s16 m_gameSettingsBtnFix480p;
s16 m_gameSettingsLblManage;
s16 m_gameSettingsBtnManage;

View File

@ -3,7 +3,7 @@
#include "channel/nand.hpp"
#include "loader/nk.h"
const int CMenu::_nbCfgPages = 12;
const int CMenu::_nbCfgPages = 13;
void CMenu::_hideConfigCommon(bool instant)
{

View File

@ -66,17 +66,17 @@ void CMenu::_showConfig7(int curPage)
if(m_config7LblUser[i] != -1)
m_btnMgr.show(m_config7LblUser[i]);
/*if(curPage == 12)
if(curPage == 13)
{
m_btnMgr.show(m_config7Lbl1);
m_btnMgr.show(m_config7Btn1);
m_btnMgr.show(m_config7Lbl2);
m_btnMgr.show(m_config7Btn2);
m_btnMgr.show(m_config7Lbl3);
m_btnMgr.show(m_config7Btn3);
//m_btnMgr.show(m_config7Lbl2);
//m_btnMgr.show(m_config7Btn2);
//m_btnMgr.show(m_config7Lbl3);
//m_btnMgr.show(m_config7Btn3);
}
else
{*/
{
m_btnMgr.show(m_config7Lbl1);
m_btnMgr.show(m_config7Btn1);
m_btnMgr.show(m_config7Lbl2);
@ -93,7 +93,7 @@ void CMenu::_showConfig7(int curPage)
m_btnMgr.show(m_config7Btn4M);
m_btnMgr.show(m_config7Btn4P);
}
//}
}
if(curPage == 7)
{
@ -150,16 +150,21 @@ void CMenu::_showConfig7(int curPage)
m_btnMgr.setText(m_config7Lbl4, _t("cfg721", L"Play GC default sound"));
m_btnMgr.setText(m_config7Btn4, m_cfg.getBool(GC_DOMAIN, "play_default_sound") ? _t("yes", L"Yes") : _t("no", L"No"));
}
else // page 12
else if(curPage == 12)
{
m_btnMgr.setText(m_config7Lbl1, _t("cfg722", L"Homebrew settings"));
m_btnMgr.setText(m_config7Btn1, _t("cfg14", L"Set"));
m_btnMgr.setText(m_config7Lbl2, _t("cfg723", L"Source menu settings"));
m_btnMgr.setText(m_config7Btn2, _t("cfg14", L"Set"));
m_btnMgr.setText(m_config7Lbl3, _t("cfg724", L"Lock coverflow layouts"));
m_btnMgr.setText(m_config7Btn3, m_cfg.getBool("general", "cf_locked") ? _t("yes", L"Yes") : _t("no", L"No"));
m_btnMgr.setText(m_config7Btn3, m_cfg.getBool("general", "cf_locked") ? _t("yes", L"Yes") : _t("no", L"No"));
m_btnMgr.setText(m_config7Lbl4, _t("cfg725", L"Shutdown to idle standby"));
m_btnMgr.setText(m_config7Btn4, m_cfg.getBool("general", "idle_standby", false) ? _t("yes", L"Yes") : _t("no", L"No"));
m_btnMgr.setText(m_config7Btn4, m_cfg.getBool("general", "idle_standby", false) ? _t("yes", L"Yes") : _t("no", L"No"));
}
else // page 13
{
m_btnMgr.setText(m_config7Lbl1, _t("cfgg49", L"480p Pixel Patch"));
m_btnMgr.setText(m_config7Btn1, m_cfg.getBool(WII_DOMAIN, "fix480p", false) ? _t("on", L"On") : _t("off", L"Off"));
}
}
@ -336,6 +341,15 @@ int CMenu::_config7(int curPage)
m_btnMgr.setText(m_config7Btn4, val ? _t("yes", L"Yes") : _t("no", L"No"));
}
}
if(curPage == 13)
{
if(m_btnMgr.selected(m_config7Btn1))
{
bool val = !m_cfg.getBool(WII_DOMAIN, "fix480p");
m_cfg.setBool(WII_DOMAIN, "fix480p", val);
m_btnMgr.setText(m_config7Btn1, val ? _t("on", L"On") : _t("off", L"Off"));
}
}
}
}
if(rand_music != m_cfg.getBool("GENERAL", "randomize_music"))

View File

@ -78,6 +78,8 @@ void CMenu::_hideGameSettingsPg(bool instant)
m_btnMgr.hide(m_gameSettingsBtnFlashSave, instant);
m_btnMgr.hide(m_gameSettingsLblPrivateServer, instant);
m_btnMgr.hide(m_gameSettingsBtnPrivateServer, instant);
m_btnMgr.hide(m_gameSettingsLblFix480p, instant);
m_btnMgr.hide(m_gameSettingsBtnFix480p, instant);
//All
m_btnMgr.hide(m_gameSettingsLblManage, instant);
m_btnMgr.hide(m_gameSettingsBtnManage, instant);
@ -399,6 +401,8 @@ void CMenu::_showGameSettings()
{
m_btnMgr.show(m_gameSettingsLblPrivateServer);
m_btnMgr.show(m_gameSettingsBtnPrivateServer);
m_btnMgr.show(m_gameSettingsLblFix480p);
m_btnMgr.show(m_gameSettingsBtnFix480p);
}
}
}
@ -452,6 +456,7 @@ void CMenu::_showGameSettings()
m_btnMgr.setText(m_gameSettingsBtnVipatch, _optBoolToString(m_gcfg2.getOptBool(id, "vipatch", 0)));
m_btnMgr.setText(m_gameSettingsBtnCountryPatch, _optBoolToString(m_gcfg2.getOptBool(id, "country_patch", 0)));
m_btnMgr.setText(m_gameSettingsBtnPrivateServer, _optBoolToString(m_gcfg2.getOptBool(id, "private_server", 0)));
m_btnMgr.setText(m_gameSettingsBtnFix480p, _optBoolToString(m_gcfg2.getOptBool(id, "fix480p", 2)));
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)));
@ -788,6 +793,11 @@ void CMenu::_gameSettings(const dir_discHdr *hdr, bool disc)
m_gcfg2.setBool(id, "private_server", !m_gcfg2.getBool(id, "private_server", 0));
_showGameSettings();
}
else if(m_btnMgr.selected(m_gameSettingsBtnFix480p))
{
m_gcfg2.setOptBool(id, "fix480p", loopNum(m_gcfg2.getOptBool(id, "fix480p") + 1, 3));
_showGameSettings();
}
else if(m_btnMgr.selected(m_gameSettingsBtnAdultOnly))
{
if(disc)
@ -956,6 +966,9 @@ void CMenu::_initGameSettingsMenu()
m_gameSettingsLblPrivateServer = _addLabel("GAME_SETTINGS/PRIVATE_SERVER", theme.lblFont, L"", 20, 185, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
m_gameSettingsBtnPrivateServer = _addButton("GAME_SETTINGS/PRIVATE_SERVER_BTN", theme.btnFont, L"", 420, 190, 200, 48, theme.btnFontColor);
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);
//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);
@ -1007,6 +1020,9 @@ void CMenu::_initGameSettingsMenu()
_setHideAnim(m_gameSettingsLblPrivateServer, "GAME_SETTINGS/PRIVATE_SERVER", 50, 0, -2.f, 0.f);
_setHideAnim(m_gameSettingsBtnPrivateServer, "GAME_SETTINGS/PRIVATE_SERVER_BTN", -50, 0, 1.f, 0.f);
_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_gameSettingsLblVipatch, "GAME_SETTINGS/VIPATCH", 50, 0, -2.f, 0.f);
_setHideAnim(m_gameSettingsBtnVipatch, "GAME_SETTINGS/VIPATCH_BTN", -50, 0, 1.f, 0.f);
@ -1159,6 +1175,7 @@ void CMenu::_textGameSettings(void)
m_btnMgr.setText(m_gameSettingsLblFlashSave, _t("cfgg32", L"Flash Save to NAND"));
m_btnMgr.setText(m_gameSettingsBtnFlashSave, _t("cfgg33", L"Flash"));
m_btnMgr.setText(m_gameSettingsLblPrivateServer, _t("cfgg45", L"Private Server (Wiimmfi)"));
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"));
}

View File

@ -871,6 +871,8 @@ void CMenu::_launchWii(dir_discHdr *hdr, bool dvd, bool disc_cfg)
bool vipatch = m_gcfg2.getBool(id, "vipatch", false);
bool countryPatch = m_gcfg2.getBool(id, "country_patch", false);
bool private_server = m_gcfg2.getBool(id, "private_server", false);
int fix480pVal = m_gcfg2.getOptBool(id, "fix480p", 2);
bool fix480p = fix480pVal == 0 ? false : (fix480pVal == 1 ? true : m_cfg.getBool(WII_DOMAIN, "fix480p", false));
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;
@ -1056,7 +1058,7 @@ void CMenu::_launchWii(dir_discHdr *hdr, bool dvd, bool disc_cfg)
free(gameconfig);
}
ExternalBooter_WiiGameSetup(wbfs_partition, dvd, patchregion, private_server, id.c_str());
ExternalBooter_WiiGameSetup(wbfs_partition, dvd, patchregion, private_server, fix480p, id.c_str());
WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, returnTo, TYPE_WII_GAME, use_led);
Sys_Exit();

View File

@ -150,6 +150,7 @@ cfgg45=Private Server (Wiimmfi)
cfgg46=WiiU Widescreen
cfgg47=Emulated MemCard
cfgg48=Triforce Arcade Mode
cfgg49=480p Pixel Patch
cfgg50=No save to extract!
cfgg51=No save to flash to real NAND!
cfgg52=Wiimote CC Rumble