Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Homebrew region inconsistency exposed by #2596. #2622

Merged
merged 2 commits into from Jun 20, 2015

Conversation

AdmiralCurtiss
Copy link
Contributor

Prior to #2596, Wii Homebrew would boot in either 50Hz or 60Hz depending on if the PAL60 option was ticked in Config -> Wii. This made some amount of sense if you weren't familiar with the internal boot logic, so no one noticed why or how that actually worked.
#2596 changed it so that NTSC games would always turn off the PAL60 setting because some NTSC games would read that setting and crash because they were never tested in that environment. This exposed an odd behavior: Wii Homebrew now always boots in 50Hz! How and why does that happen?

To find the answer to that, we have to look into the source code for libogc, which almost all homebrew uses, to figure out how they choose which video mode to use. The sample code suggests to select an appropriate video mode by calling VIDEO_GetPreferredMode(), which is defined in video.c. The relevant part is this:

u32 tvmode = CONF_GetVideo();
if (CONF_GetProgressiveScan() > 0 && VIDEO_HaveComponentCable()) {
    switch (tvmode) {
        case CONF_VIDEO_NTSC:
            rmode = &TVNtsc480Prog;
            break;
        case CONF_VIDEO_PAL:
            if (CONF_GetEuRGB60() > 0)
                rmode = &TVEurgb60Hz480Prog;
            else rmode = &TVPal576ProgScale;
            break;
        case CONF_VIDEO_MPAL:
            rmode = &TVMpal480Prog;
            break;
        default:
            rmode = &TVNtsc480Prog;
    }
} else {
    switch (tvmode) {
        case CONF_VIDEO_NTSC:
            rmode = &TVNtsc480IntDf;
            break;
        case CONF_VIDEO_PAL:
            if (CONF_GetEuRGB60() > 0)
                rmode = &TVEurgb60Hz480IntDf;
            else rmode = &TVPal576IntDfScale;
            break;
        case CONF_VIDEO_MPAL:
            rmode = &TVMpal480IntDf;
            break;
        default:
            rmode = &TVNtsc480IntDf;
    }
}

Most of this is pretty clear, but what exactly does CONF_GetVideo() (in conf.c) do? Let's see...

s32 CONF_GetVideo(void)
{
    int res;
    char buf[5];

    res = __CONF_GetTxt("VIDEO", buf, 5);
    if(res < 0) return res;
    if(!strcmp(buf, "NTSC")) return CONF_VIDEO_NTSC;
    if(!strcmp(buf, "PAL")) return CONF_VIDEO_PAL;
    if(!strcmp(buf, "MPAL")) return CONF_VIDEO_MPAL;
    return CONF_EBADVALUE;
}

Aha! __CONF_GetTxt() reads from the Wii's setting.txt file, so CONF_GetVideo() uses the VIDEO string from that to figure out the console region. From here we can work backwards to understand what this code does in Dolphin.

The setting.txt is generated in CBoot::SetupWiiMemory. Specifically, we decide which region to generate for with these lines:

auto entryPos = country_settings.find(country);
const CountrySetting& country_setting =
        (entryPos != country_settings.end()) ?
          entryPos->second :
          SETTING_EUROPE; //Default to EUROPE

Homebrew doesn't have a game ID to read a country from, so it will always be COUNTRY_UNKNOWN, which in turn sets SETTING_EUROPE. In other words, homebrew always boots in a European console environment.

Well, that explains why the PAL60 setting affects the refresh rate of homebrew (compare with the VIDEO_GetPreferredMode() code), but it doesn't explain why that stopped working in #2596. So let's dig further.

SConfig::AutoSetup runs before CBoot::SetupWiiMemory and sets up some boot parameters. For homebrew specifically, it sets:

set_region_dir = USA_DIR;
m_BootType = BOOT_ELF;
bNTSC = true;

Now hold on, we just established that homebrew runs in a European environment! This is inconsistent! But it explains what happens and why #2596 broke it:

SConfig::AutoSetup sets NTSC-U parameters, which in turn causes BootManager::BootCore() to turn off the PAL60 setting for compatibility reasons. Meanwhile, CBoot::SetupWiiMemory generates a European setting.txt. Then, in libogc, VIDEO_GetPreferredMode() sees the European setting.txt and the turned off PAL60 flag and selects a 50Hz video mode from that information.

This PR changes this so that a turned off PAL60 setting will boot Wii homebrew in a PAL/Europe environment at 50Hz, and a turned on PAL60 setting will boot Wii homebrew in a PAL/Europe environment at 60Hz. GameCube homebrew always boots in NTSC at 60Hz. This corresponds to how homebrew booted before #2596 and removes the odd regional inconsistency.

In the future we should maybe provide options to boot homebrew in any environment, and I've set it up so you'd only have to change the bNTSC flag appropriately in SConfig::AutoSetup() for the rest to set properly, but this is probably good enough for most use cases for now.

@Parlane
Copy link
Member

Parlane commented Jun 19, 2015

LGTM

@BhaaLseN
Copy link
Member

So, at the moment, running a Wii Homebrew forces NTSC off, while GC Homebrew forces NTSC on?
Maybe a TODO comment or smth should be left there, explaining that right now its on purpose until something better is implemented?

Also, I like your PRs, rarely ever see ones with that much information :)

@AdmiralCurtiss
Copy link
Contributor Author

Yeah okay, I'll document that. It is odd behavior.

And thank you.

…g instead of always using 50Hz.

This is a bit indirect, but since homebrew always boots in a European environment the framerate depends on the bPAL60 flag, which is always auto turned off if bNTSC is set to true as of 2e5e724. By actually indicating that we're PAL on homebrew boot, the rest just falls into place.
… mode when no valid country code is found rather than defaulting to Europe.
@BhaaLseN
Copy link
Member

LGTM

skidau added a commit that referenced this pull request Jun 20, 2015
Fix Homebrew region inconsistency exposed by #2596.
@skidau skidau merged commit c186624 into dolphin-emu:master Jun 20, 2015
@AdmiralCurtiss AdmiralCurtiss deleted the homebrew-video-modes branch June 20, 2015 01:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
4 participants