static void _ApplySettings( const Pcsx2Config& src, Pcsx2Config& fixup ) { Threading::ScopedLock lock(mtx__ApplySettings); // 'fixup' is the EmuConfig we're going to upload to the emulator, which very well may // differ from the user-configured EmuConfig settings. So we make a copy here and then // we apply the commandline overrides and database gamefixes, and then upload 'fixup' // to the global EmuConfig. // // Note: It's important that we apply the commandline overrides *before* database fixes. // The database takes precedence (if enabled). fixup = src; const CommandlineOverrides& overrides( wxGetApp().Overrides ); if( overrides.DisableSpeedhacks || !g_Conf->EnableSpeedHacks ) fixup.Speedhacks.DisableAll(); if( overrides.ApplyCustomGamefixes ) { for (GamefixId id=GamefixId_FIRST; id < pxEnumEnd; ++id) fixup.Gamefixes.Set( id, overrides.Gamefixes.Get(id) ); } else if( !g_Conf->EnableGameFixes ) fixup.Gamefixes.DisableAll(); if( overrides.ProfilingMode ) { fixup.GS.FrameLimitEnable = false; fixup.GS.VsyncEnable = false; } wxString gameCRC; wxString gameSerial; wxString gamePatch; wxString gameFixes; wxString gameCheats; wxString gameWsHacks; wxString gameName; wxString gameCompat; wxString gameMemCardFilter; // The CRC can be known before the game actually starts (at the bios), so when // we have the CRC but we're still at the bios and the settings are changed // (e.g. the user presses TAB to speed up emulation), we don't want to apply the // settings as if the game is already running (title, loadeding patches, etc). bool ingame = (ElfCRC && (g_GameLoading || g_GameStarted)); if (ingame) gameCRC.Printf( L"%8.8x", ElfCRC ); if (ingame && !DiscSerial.IsEmpty()) gameSerial = L" [" + DiscSerial + L"]"; const wxString newGameKey(ingame ? SysGetDiscID() : SysGetBiosDiscID()); const bool verbose( newGameKey != curGameKey && ingame ); //Console.WriteLn(L"------> patches verbose: %d prev: '%s' new: '%s'", (int)verbose, WX_STR(curGameKey), WX_STR(newGameKey)); SetupPatchesCon(verbose); curGameKey = newGameKey; ForgetLoadedPatches(); if (!curGameKey.IsEmpty()) { if (IGameDatabase* GameDB = AppHost_GetGameDatabase() ) { Game_Data game; if (GameDB->findGame(game, curGameKey)) { int compat = game.getInt("Compat"); gameName = game.getString("Name"); gameName += L" (" + game.getString("Region") + L")"; gameCompat = L" [Status = "+compatToStringWX(compat)+L"]"; gameMemCardFilter = game.getString("MemCardFilter"); } if (fixup.EnablePatches) { if (int patches = LoadPatchesFromGamesDB(gameCRC, game)) { gamePatch.Printf(L" [%d Patches]", patches); PatchesCon->WriteLn(Color_Green, "(GameDB) Patches Loaded: %d", patches); } if (int fixes = loadGameSettings(fixup, game)) gameFixes.Printf(L" [%d Fixes]", fixes); } } } if (!gameMemCardFilter.IsEmpty()) sioSetGameSerial(gameMemCardFilter); else sioSetGameSerial(curGameKey); if (gameName.IsEmpty() && gameSerial.IsEmpty() && gameCRC.IsEmpty()) { // if all these conditions are met, it should mean that we're currently running BIOS code. // Chances are the BiosChecksum value is still zero or out of date, however -- because // the BIos isn't loaded until after initial calls to ApplySettings. gameName = L"Booting PS2 BIOS... "; } //Till the end of this function, entry CRC will be 00000000 if (!gameCRC.Length()) { Console.WriteLn(Color_Gray, "Patches: No CRC found, using 00000000 instead."); gameCRC = L"00000000"; } // regular cheat patches if (fixup.EnableCheats) gameCheats.Printf(L" [%d Cheats]", LoadPatchesFromDir(gameCRC, GetCheatsFolder(), L"Cheats")); // wide screen patches if (fixup.EnableWideScreenPatches) { if (int numberLoadedWideScreenPatches = LoadPatchesFromDir(gameCRC, GetCheatsWsFolder(), L"Widescreen hacks")) { gameWsHacks.Printf(L" [%d widescreen hacks]", numberLoadedWideScreenPatches); Console.WriteLn(Color_Gray, "Found widescreen patches in the cheats_ws folder --> skipping cheats_ws.zip"); } else { // No ws cheat files found at the cheats_ws folder, try the ws cheats zip file. wxString cheats_ws_archive = Path::Combine(PathDefs::GetProgramDataDir(), wxFileName(L"cheats_ws.zip")); int numberDbfCheatsLoaded = LoadPatchesFromZip(gameCRC, cheats_ws_archive); PatchesCon->WriteLn(Color_Green, "(Wide Screen Cheats DB) Patches Loaded: %d", numberDbfCheatsLoaded); gameWsHacks.Printf(L" [%d widescreen hacks]", numberDbfCheatsLoaded); } } wxString consoleTitle = gameName + gameSerial; consoleTitle += L" [" + gameCRC.MakeUpper() + L"]" + gameCompat + gameFixes + gamePatch + gameCheats + gameWsHacks; if (ingame) Console.SetTitle(consoleTitle); // When we're booting, the bios loader will set a a title which would be more interesting than this // to most users - with region, version, etc, so don't overwrite it with patch info. That's OK. Those // users which want to know the status of the patches at the bios can check the console content. }
// Load Game Settings found in database // (game fixes, round modes, clamp modes, etc...) // Returns number of gamefixes set static int loadGameSettings(Pcsx2Config& dest, const Game_Data& game) { if( !game.IsOk() ) return 0; int gf = 0; if (game.keyExists("eeRoundMode")) { SSE_RoundMode eeRM = (SSE_RoundMode)game.getInt("eeRoundMode"); if (EnumIsValid(eeRM)) { PatchesCon->WriteLn("(GameDB) Changing EE/FPU roundmode to %d [%s]", eeRM, EnumToString(eeRM)); dest.Cpu.sseMXCSR.SetRoundMode(eeRM); ++gf; } } if (game.keyExists("vuRoundMode")) { SSE_RoundMode vuRM = (SSE_RoundMode)game.getInt("vuRoundMode"); if (EnumIsValid(vuRM)) { PatchesCon->WriteLn("(GameDB) Changing VU0/VU1 roundmode to %d [%s]", vuRM, EnumToString(vuRM)); dest.Cpu.sseVUMXCSR.SetRoundMode(vuRM); ++gf; } } if (game.keyExists("eeClampMode")) { int clampMode = game.getInt("eeClampMode"); PatchesCon->WriteLn("(GameDB) Changing EE/FPU clamp mode [mode=%d]", clampMode); dest.Cpu.Recompiler.fpuOverflow = (clampMode >= 1); dest.Cpu.Recompiler.fpuExtraOverflow = (clampMode >= 2); dest.Cpu.Recompiler.fpuFullMode = (clampMode >= 3); gf++; } if (game.keyExists("vuClampMode")) { int clampMode = game.getInt("vuClampMode"); PatchesCon->WriteLn("(GameDB) Changing VU0/VU1 clamp mode [mode=%d]", clampMode); dest.Cpu.Recompiler.vuOverflow = (clampMode >= 1); dest.Cpu.Recompiler.vuExtraOverflow = (clampMode >= 2); dest.Cpu.Recompiler.vuSignOverflow = (clampMode >= 3); gf++; } if (game.keyExists("mvuFlagSpeedHack")) { bool vuFlagHack = game.getInt("mvuFlagSpeedHack") ? 1 : 0; PatchesCon->WriteLn("(GameDB) Changing mVU flag speed hack [mode=%d]", vuFlagHack); dest.Speedhacks.vuFlagHack = vuFlagHack; gf++; } for( GamefixId id=GamefixId_FIRST; id<pxEnumEnd; ++id ) { wxString key( EnumToString(id) ); key += L"Hack"; if (game.keyExists(key)) { bool enableIt = game.getBool(key); dest.Gamefixes.Set(id, enableIt); PatchesCon->WriteLn(L"(GameDB) %s Gamefix: " + key, enableIt ? L"Enabled" : L"Disabled"); gf++; // The LUT is only used for 1 game so we allocate it only when the gamefix is enabled (save 4MB) if (id == Fix_GoemonTlbMiss && enableIt) vtlb_Alloc_Ppmap(); } } return gf; }
int _doCompare( const Game_Data& g1, const Game_Data& g2 ) { return g1.getInt("Compat") - g2.getInt("Compat"); }
void AppCoreThread::ApplySettings( const Pcsx2Config& src ) { // Used to track the current game serial/id, and used to disable verbose logging of // applied patches if the game info hasn't changed. (avoids spam when suspending/resuming // or using TAB or other things). static wxString curGameKey; // 'fixup' is the EmuConfig we're going to upload to the emulator, which very well may // differ from the user-configured EmuConfig settings. So we make a copy here and then // we apply the commandline overrides and database gamefixes, and then upload 'fixup' // to the global EmuConfig. // // Note: It's important that we apply the commandline overrides *before* database fixes. // The database takes precedence (if enabled). Pcsx2Config fixup( src ); const CommandlineOverrides& overrides( wxGetApp().Overrides ); if( overrides.DisableSpeedhacks || !g_Conf->EnableSpeedHacks ) fixup.Speedhacks.DisableAll(); if( overrides.ApplyCustomGamefixes ) { for (GamefixId id=GamefixId_FIRST; id < pxEnumEnd; ++id) fixup.Gamefixes.Set( id, overrides.Gamefixes.Get(id) ); } else if( !g_Conf->EnableGameFixes ) fixup.Gamefixes.DisableAll(); wxString gameCRC; wxString gameSerial; wxString gamePatch; wxString gameFixes; wxString gameCheats; wxString gameWsHacks; wxString gameName; wxString gameCompat; int numberLoadedCheats; int numberLoadedWideScreenPatches; int numberDbfCheatsLoaded; if (ElfCRC) gameCRC.Printf( L"%8.8x", ElfCRC ); if (!DiscSerial.IsEmpty()) gameSerial = L" [" + DiscSerial + L"]"; const wxString newGameKey( SysGetDiscID() ); const bool verbose( newGameKey != curGameKey ); curGameKey = newGameKey; if (!curGameKey.IsEmpty()) { if (IGameDatabase* GameDB = AppHost_GetGameDatabase() ) { Game_Data game; if (GameDB->findGame(game, curGameKey)) { int compat = game.getInt("Compat"); gameName = game.getString("Name"); gameName += L" (" + game.getString("Region") + L")"; gameCompat = L" [Status = "+compatToStringWX(compat)+L"]"; } if (EmuConfig.EnablePatches) { if (int patches = InitPatches(gameCRC, game)) { gamePatch.Printf(L" [%d Patches]", patches); if (verbose) Console.WriteLn(Color_Green, "(GameDB) Patches Loaded: %d", patches); } if (int fixes = loadGameSettings(fixup, game, verbose)) { gameFixes.Printf(L" [%d Fixes]", fixes); } } } } if (gameName.IsEmpty() && gameSerial.IsEmpty() && gameCRC.IsEmpty()) { // if all these conditions are met, it should mean that we're currently running BIOS code. // Chances are the BiosChecksum value is still zero or out of date, however -- because // the BIos isn't loaded until after initial calls to ApplySettings. gameName = L"Booting PS2 BIOS... "; } ResetCheatsCount(); //Till the end of this function, entry CRC will be 00000000 if (!gameCRC.Length()) { if (EmuConfig.EnableWideScreenPatches || EmuConfig.EnableCheats) { Console.WriteLn(Color_Gray, "Patches: No CRC, using 00000000 instead."); } gameCRC = L"00000000"; } // regular cheat patches if (EmuConfig.EnableCheats) { if (numberLoadedCheats = LoadCheats(gameCRC, GetCheatsFolder(), L"Cheats")) { gameCheats.Printf(L" [%d Cheats]", numberLoadedCheats); } } // wide screen patches if (EmuConfig.EnableWideScreenPatches) { if (numberLoadedWideScreenPatches = LoadCheats(gameCRC, GetCheatsWsFolder(), L"Widescreen hacks")) { gameWsHacks.Printf(L" [%d widescreen hacks]", numberLoadedWideScreenPatches); } else { // No ws cheat files found at the cheats_ws folder, try the ws cheats zip file. wxString cheats_ws_archive = Path::Combine(PathDefs::GetProgramDataDir(), wxFileName(L"cheats_ws.zip")); if (numberDbfCheatsLoaded = LoadCheatsFromZip(gameCRC, cheats_ws_archive)) { Console.WriteLn(Color_Green, "(Wide Screen Cheats DB) Patches Loaded: %d", numberDbfCheatsLoaded); gameWsHacks.Printf(L" [%d widescreen hacks]", numberDbfCheatsLoaded); } } } wxString consoleTitle = gameName + gameSerial; if (!gameSerial.IsEmpty()) { consoleTitle += L" [" + gameCRC.MakeUpper() + L"]"; } consoleTitle += gameCompat + gameFixes + gamePatch + gameCheats + gameWsHacks; Console.SetTitle(consoleTitle); // Re-entry guard protects against cases where code wants to manually set core settings // which are not part of g_Conf. The subsequent call to apply g_Conf settings (which is // usually the desired behavior) will be ignored. static int localc = 0; RecursionGuard guard( localc ); if( guard.IsReentrant() ) return; if( fixup == EmuConfig ) return; if( m_ExecMode >= ExecMode_Opened ) { ScopedCoreThreadPause paused_core; _parent::ApplySettings( fixup ); paused_core.AllowResume(); } else { _parent::ApplySettings( fixup ); } }
// Load Game Settings found in database // (game fixes, round modes, clamp modes, etc...) // Returns number of gamefixes set static int loadGameSettings(Pcsx2Config& dest, const Game_Data& game, bool verbose = true) { if( !game.IsOk() ) return 0; int gf = 0; if (game.keyExists("eeRoundMode")) { SSE_RoundMode eeRM = (SSE_RoundMode)game.getInt("eeRoundMode"); if (EnumIsValid(eeRM)) { if(verbose) Console.WriteLn("(GameDB) Changing EE/FPU roundmode to %d [%s]", eeRM, EnumToString(eeRM)); dest.Cpu.sseMXCSR.SetRoundMode(eeRM); ++gf; } } if (game.keyExists("vuRoundMode")) { SSE_RoundMode vuRM = (SSE_RoundMode)game.getInt("vuRoundMode"); if (EnumIsValid(vuRM)) { if(verbose) Console.WriteLn("(GameDB) Changing VU0/VU1 roundmode to %d [%s]", vuRM, EnumToString(vuRM)); dest.Cpu.sseVUMXCSR.SetRoundMode(vuRM); ++gf; } } if (game.keyExists("eeClampMode")) { int clampMode = game.getInt("eeClampMode"); if(verbose) Console.WriteLn("(GameDB) Changing EE/FPU clamp mode [mode=%d]", clampMode); dest.Cpu.Recompiler.fpuOverflow = (clampMode >= 1); dest.Cpu.Recompiler.fpuExtraOverflow = (clampMode >= 2); dest.Cpu.Recompiler.fpuFullMode = (clampMode >= 3); gf++; } if (game.keyExists("vuClampMode")) { int clampMode = game.getInt("vuClampMode"); if(verbose) Console.WriteLn("(GameDB) Changing VU0/VU1 clamp mode [mode=%d]", clampMode); dest.Cpu.Recompiler.vuOverflow = (clampMode >= 1); dest.Cpu.Recompiler.vuExtraOverflow = (clampMode >= 2); dest.Cpu.Recompiler.vuSignOverflow = (clampMode >= 3); gf++; } if (game.keyExists("mvuFlagSpeedHack")) { bool vuFlagHack = game.getInt("mvuFlagSpeedHack") ? 1 : 0; if(verbose) Console.WriteLn("(GameDB) Changing mVU flag speed hack [mode=%d]", vuFlagHack); dest.Speedhacks.vuFlagHack = vuFlagHack; gf++; } for( GamefixId id=GamefixId_FIRST; id<pxEnumEnd; ++id ) { wxString key( EnumToString(id) ); key += L"Hack"; if (game.keyExists(key)) { bool enableIt = game.getBool(key); dest.Gamefixes.Set(id, enableIt); if(verbose) Console.WriteLn(L"(GameDB) %s Gamefix: " + key, enableIt ? L"Enabled" : L"Disabled" ); gf++; } } return gf; }