DacoTaco / priiloader

A Wii homebrew application that can prevent and fix some user level bricks
GNU General Public License v2.0
546 stars 102 forks source link

vWii - Booting some Japanese games causes system to freeze #343

Open adamsousa opened 1 year ago

adamsousa commented 1 year ago

Describe the bug When booting some Japanese disc games, the system freezes before the game can start. This has happened to me reliably for Kirby Returns to Dreamland (Kirby Wii) and Pikmin 1 (Wii edition). Both hang before getting to the title screen, but usually the system warnings do show before. No error messages are shown, just stays on a white or black screen forever.

Other Japanese games like Rhythm Heaven Fever and Taiko Wii boot just fine.

To Reproduce Steps to reproduce the behavior: -Insert disc version of affected game -Click on disc channel and press start -Note game does not boot to title screen and freezes system

Version 0.10.0

Expected behavior The game boots!

Screenshots [If applicable, add screenshots to help explain your problem.]

Additional context Worth noting my system does contain save data for the English version of both games, not sure if that would cause issues.

Ingunar commented 1 year ago
adamsousa commented 1 year ago

Console Region: US

Cheats enabled: Region free and Deflicker filter

DacoTaco commented 1 year ago

does it boot the game if you try and boot it from priiloader using the new boot disc option?

adamsousa commented 1 year ago

I assume this is the "Launch Disc" option in priiloader. Tried this with Kirby Wii and same result. Loads the initial safety warning screen, then shows controller message, and fades to white where it never boots to the title screen. I'm not able to force shutdown the system either when this happens, by holding the power button, I have to unplug it manually.

DacoTaco commented 1 year ago

if it actually shows the warning screen then im scared to say this is out of the control of priiloader and the hack. its possible its trying to load content from the wii that it can't find because its a different region :/

what i can try, is see if i can get priiloader to load the game. but with the region free hack, its as good as it can get.

@vaguerant : got an idea how usbloaders get past this?

vaguerant commented 1 year ago

@vaguerant : got an idea how usbloaders get past this?

USB loaders can/do patch the DOL to force languages, video modes, etc. to improve compatibility. In theory, it would be possible to patch games using a patcher resident in memory similar to how the priiloader Wiimmfi patch works (i.e. patch a patcher into the System Menu which in turn patches the software it launches). But USB loaders also get the benefit of per-title settings, so you can force one game to look for Japanese text and use NTSC, then force a different game to look for German text and use PAL, but still have all your other games boot normally without forcing anything. A one-size solution that makes all out-of-region games work without breaking any in-region games would probably be quite difficult.

It's kind of a disappointing answer, but I think using an external app which supports disc launching (e.g. USB loader GX) is always going to be more practical than trying to do it from priiloader.

DacoTaco commented 1 year ago

@vaguerant : got an idea how usbloaders get past this?

USB loaders can/do patch the DOL to force languages, video modes, etc. to improve compatibility. In theory, it would be possible to patch games using a patcher resident in memory similar to how the priiloader Wiimmfi patch works (i.e. patch a patcher into the System Menu which in turn patches the software it launches). But USB loaders also get the benefit of per-title settings, so you can force one game to look for Japanese text and use NTSC, then force a different game to look for German text and use PAL, but still have all your other games boot normally without forcing anything. A one-size solution that makes all out-of-region games work without breaking any in-region games would probably be quite difficult.

It's kind of a disappointing answer, but I think using an external app which supports disc launching (e.g. USB loader GX) is always going to be more practical than trying to do it from priiloader.

thanks for the informative explanation. a SM patch might be very hard just by finding memory you can use for it. i was mostly asking to see if a general patch can be created for priiloader to apply to games when it loads the disc. a patch it can apply to all games if the regions don't match. you think thats possible, or does usbloader apply those patches only for certain games?

vaguerant commented 1 year ago

USB loaders have a couple of hardcoded per-game patches, but for the most part something generic should be doable, free memory aside. You'd basically check the gameID of the software and if the fourth character matches the console region, the patch returns doing nothing, otherwise run patches to language, country strings, video modes and anything else that might break an out-of-region game. There may be edge cases this breaks instead though, like prototype dumps often have incorrect gameIDs that would trip the patcher when it's not actually needed and there might be some games where you need to patch one thing but not the other to make them work, etc. Still, I think it would be possible.

DacoTaco commented 1 year ago

USB loaders have a couple of hardcoded per-game patches, but for the most part something generic should be doable, free memory aside. You'd basically check the gameID of the software and if the fourth character matches the console region, the patch returns doing nothing, otherwise run patches to language, country strings, video modes and anything else that might break an out-of-region game. There may be edge cases this breaks instead though, like prototype dumps often have incorrect gameIDs that would trip the patcher when it's not actually needed and there might be some games where you need to patch one thing but not the other to make them work, etc. Still, I think it would be possible.

thats good to hear. priiloader already has a function to set video mode depending on the gameID, but maybe that can be extended to patch the other stuff too. do you know where in the code of usbloader gx i can find these patches? i will probably have to analyze and rewrite these patches from scratch but it would improve comparability

vaguerant commented 1 year ago

Here's where the assembly patches for language are set up, which find where language is set then apply the selected language:

https://github.com/wiidev/usbloadergx/blob/e25c4e96430524c080767679b0c4a0d7595412a8/source/patches/patchhook.S#L165-L187

Then they call the langpatcher() function with a specific language set:

https://github.com/wiidev/usbloadergx/blob/e25c4e96430524c080767679b0c4a0d7595412a8/source/patches/patchcode.c#L634-L682

I suspect language is probably the one most likely to cause issues, so implementing just that might be enough for most cases.

Then there's patchcountrystrings() as well:

https://github.com/wiidev/usbloadergx/blob/e25c4e96430524c080767679b0c4a0d7595412a8/source/usbloader/disc.c#L451-L532

DacoTaco commented 1 year ago

... why the asm code...? anyway, this is why i wanted to analyze an create the patching code myself. i expected things to be that... eug

EDIT: oh lord, this code is such a mess

DacoTaco commented 1 year ago
void langvipatch(uint *addr,int lenght,int langCode)

{
  do {
    if (*addr == 0x88610008) {
      *addr = langCode + 0x38600000;
      dataCacheBlockFlush(addr);
      instructionCacheBlockInvalidate(addr);
      return;
    }
    addr = addr + 1;
    lenght = lenght + -1;
  } while (lenght != 0);
  return;
}

thanks ghidra

wiidev commented 1 year ago

Then there's patchcountrystrings() as well:

I believe that patch is supposed to fix the font in Japanese games if it's not displayed correctly. I've never had to use it though and it's disabled by default.

... why the asm code...?

Someone called fishears wrote the code that way back in 2009 and most of the loaders devs have had an "if it ain't broke, don't fix it" approach, so it's remained the way it is.

In January of this year I added automatic language selection, which applies the language patch when a games language setting is set to "console default" but the game doesn't support your language. So for example, Horse Life Adventures (RH5EVN) won't work on a German PAL console without the language being patched to English, French or Spanish.

I'm not entirely sure if the language patch alone would help in this case.

DacoTaco commented 1 year ago

thanks for that info @wiidev ! how does it detect if the game needs the language patch? its not just a 'attempt to patch all games if region isn't the same' kind of thing?

wiidev commented 1 year ago

how does it detect if the game needs the language patch? its not just a 'attempt to patch all games if region isn't the same' kind of thing?

The loader already makes use of WiiTDB, so I'm using that to get the supported languages for each game. Then if a game doesn't support your consoles language it'll get patched to the first supported language.

To date I haven't received a single complaint and compatibility was improved, but if there was an error or something missing in their database then that's easily corrected via their website.

DacoTaco commented 1 year ago

thats kinda problematic though. priiloader should not be reliant to such a database or external source. i fear it can't reach the comparability loaders have, but there has to be another way :/

wiidev commented 1 year ago

I'd like to be wrong, but unfortunately I don't think there's any other way to automatically handle it.

I guess you could read the discs header and then ask the user what language to use if the games region doesn't match their consoles? It'd be slightly annoying, but it'd get more games booting.

EDIT: If you go this route then I'd also suggest adding a setting to always ask what language to use, since you'd need that for some problematic PAL games.