2015-05-24 06:55:12 +02:00
|
|
|
// Copyright 2011 Dolphin Emulator Project
|
2021-07-05 03:22:19 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2011-02-12 22:31:57 +00:00
|
|
|
|
|
|
|
// File description
|
|
|
|
// -------------
|
|
|
|
// Purpose of this file: Collect boot settings for Core::Init()
|
|
|
|
|
|
|
|
// Call sequence: This file has one of the first function called when a game is booted,
|
|
|
|
// the boot sequence in the code is:
|
2013-10-29 01:23:17 -04:00
|
|
|
|
2011-03-03 04:35:03 +00:00
|
|
|
// DolphinWX: FrameTools.cpp StartGame
|
|
|
|
// Core BootManager.cpp BootCore
|
|
|
|
// Core.cpp Init Thread creation
|
2011-02-12 22:31:57 +00:00
|
|
|
// EmuThread Calls CBoot::BootUp
|
|
|
|
// Boot.cpp CBoot::BootUp()
|
|
|
|
// CBoot::EmulatedBS2_Wii() / GC() or Load_BS2()
|
|
|
|
|
2017-02-24 22:56:33 -05:00
|
|
|
#include "Core/BootManager.h"
|
|
|
|
|
2016-01-26 20:22:43 -05:00
|
|
|
#include <algorithm>
|
|
|
|
#include <array>
|
2011-02-12 22:31:57 +00:00
|
|
|
#include <string>
|
|
|
|
|
2019-10-20 07:35:11 -04:00
|
|
|
#include <fmt/format.h>
|
|
|
|
|
2014-02-19 13:09:14 -05:00
|
|
|
#include "Common/CommonTypes.h"
|
2017-05-13 22:29:55 +01:00
|
|
|
#include "Common/Config/Config.h"
|
2016-01-17 16:54:31 -05:00
|
|
|
#include "Common/FileUtil.h"
|
2014-02-17 05:18:15 -05:00
|
|
|
#include "Common/IniFile.h"
|
2016-10-07 21:57:07 +02:00
|
|
|
#include "Common/Logging/Log.h"
|
2016-12-23 21:53:36 +01:00
|
|
|
|
2023-04-11 00:04:08 -04:00
|
|
|
#include "Core/AchievementManager.h"
|
2017-05-27 15:43:40 +02:00
|
|
|
#include "Core/Boot/Boot.h"
|
2017-08-03 16:42:18 +08:00
|
|
|
#include "Core/Config/MainSettings.h"
|
2017-08-01 22:37:42 +08:00
|
|
|
#include "Core/Config/SYSCONFSettings.h"
|
|
|
|
#include "Core/ConfigLoaders/BaseConfigLoader.h"
|
2017-05-13 22:29:55 +01:00
|
|
|
#include "Core/ConfigLoaders/NetPlayConfigLoader.h"
|
2014-02-17 05:18:15 -05:00
|
|
|
#include "Core/ConfigManager.h"
|
|
|
|
#include "Core/Core.h"
|
2017-01-20 15:33:43 -05:00
|
|
|
#include "Core/HW/EXI/EXI.h"
|
2017-01-20 18:45:11 -05:00
|
|
|
#include "Core/HW/SI/SI.h"
|
2019-06-07 18:25:32 -04:00
|
|
|
#include "Core/HW/SI/SI_Device.h"
|
2015-06-14 13:59:41 +02:00
|
|
|
#include "Core/HW/Sram.h"
|
2014-02-17 05:18:15 -05:00
|
|
|
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
|
|
|
#include "Core/Movie.h"
|
|
|
|
#include "Core/NetPlayProto.h"
|
2018-06-15 08:11:18 -04:00
|
|
|
#include "Core/PowerPC/PowerPC.h"
|
2022-01-07 03:50:18 +01:00
|
|
|
#include "Core/System.h"
|
2020-03-16 13:02:35 +01:00
|
|
|
#include "Core/WiiRoot.h"
|
2016-12-23 21:53:36 +01:00
|
|
|
|
|
|
|
#include "DiscIO/Enums.h"
|
|
|
|
|
2014-02-17 05:18:15 -05:00
|
|
|
#include "VideoCommon/VideoBackendBase.h"
|
2011-02-12 22:31:57 +00:00
|
|
|
|
|
|
|
namespace BootManager
|
|
|
|
{
|
|
|
|
// Boot the ISO or file
|
2018-10-03 23:03:22 +10:00
|
|
|
bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
|
2011-02-12 22:31:57 +00:00
|
|
|
{
|
2017-05-27 15:43:40 +02:00
|
|
|
if (!boot)
|
|
|
|
return false;
|
|
|
|
|
2015-06-12 13:56:53 +02:00
|
|
|
SConfig& StartUp = SConfig::GetInstance();
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2017-05-27 15:43:40 +02:00
|
|
|
if (!StartUp.SetPathsAndGameMetadata(*boot))
|
2011-02-12 22:31:57 +00:00
|
|
|
return false;
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2014-01-02 13:13:36 -05:00
|
|
|
// Movie settings
|
2013-05-19 19:44:37 +02:00
|
|
|
if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
|
|
|
|
{
|
2022-01-11 11:17:47 -08:00
|
|
|
for (ExpansionInterface::Slot slot : ExpansionInterface::MEMCARD_SLOTS)
|
2013-05-19 19:44:37 +02:00
|
|
|
{
|
2022-01-11 11:17:47 -08:00
|
|
|
if (Movie::IsUsingMemcard(slot) && Movie::IsStartingFromClearSave() && !StartUp.bWii)
|
2014-07-02 21:45:59 -04:00
|
|
|
{
|
2019-10-20 07:35:11 -04:00
|
|
|
const auto raw_path =
|
2022-01-11 11:17:47 -08:00
|
|
|
File::GetUserPath(D_GCUSER_IDX) +
|
|
|
|
fmt::format("Movie{}.raw", slot == ExpansionInterface::Slot::A ? 'A' : 'B');
|
2019-10-20 07:35:11 -04:00
|
|
|
if (File::Exists(raw_path))
|
|
|
|
File::Delete(raw_path);
|
|
|
|
|
|
|
|
const auto movie_path = File::GetUserPath(D_GCUSER_IDX) + "Movie";
|
|
|
|
if (File::Exists(movie_path))
|
|
|
|
File::DeleteDirRecursively(movie_path);
|
2013-05-19 19:44:37 +02:00
|
|
|
}
|
|
|
|
}
|
2016-06-24 10:43:46 +02:00
|
|
|
}
|
|
|
|
|
2013-08-05 04:56:30 -04:00
|
|
|
if (NetPlay::IsNetPlayRunning())
|
2013-07-19 18:48:27 -04:00
|
|
|
{
|
2022-09-11 03:55:30 +02:00
|
|
|
const NetPlay::NetSettings* netplay_settings = boot->boot_session_data.GetNetplaySettings();
|
|
|
|
if (!netplay_settings)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Config::AddLayer(ConfigLoaders::GenerateNetPlayConfigLoader(*netplay_settings));
|
2022-09-11 02:35:20 +02:00
|
|
|
StartUp.bCopyWiiSaveNetplay = netplay_settings->savedata_load;
|
2013-07-19 18:48:27 -04:00
|
|
|
}
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2019-06-30 12:44:38 +02:00
|
|
|
// Override out-of-region languages/countries to prevent games from crashing or behaving oddly
|
2022-01-03 07:07:32 +01:00
|
|
|
if (!Config::Get(Config::MAIN_OVERRIDE_REGION_SETTINGS))
|
2015-06-14 17:03:45 +02:00
|
|
|
{
|
2022-01-03 07:07:32 +01:00
|
|
|
Config::SetCurrent(
|
|
|
|
Config::MAIN_GC_LANGUAGE,
|
|
|
|
DiscIO::ToGameCubeLanguage(StartUp.GetLanguageAdjustedForRegion(false, StartUp.m_region)));
|
2019-06-30 11:48:49 +02:00
|
|
|
|
|
|
|
if (StartUp.bWii)
|
|
|
|
{
|
|
|
|
const u32 wii_language =
|
|
|
|
static_cast<u32>(StartUp.GetLanguageAdjustedForRegion(true, StartUp.m_region));
|
2020-09-16 12:44:32 +02:00
|
|
|
if (wii_language != Config::Get(Config::SYSCONF_LANGUAGE))
|
|
|
|
Config::SetCurrent(Config::SYSCONF_LANGUAGE, wii_language);
|
2019-06-30 12:44:38 +02:00
|
|
|
|
|
|
|
const u8 country_code = static_cast<u8>(Config::Get(Config::SYSCONF_COUNTRY));
|
|
|
|
if (StartUp.m_region != DiscIO::SysConfCountryToRegion(country_code))
|
|
|
|
{
|
|
|
|
switch (StartUp.m_region)
|
|
|
|
{
|
|
|
|
case DiscIO::Region::NTSC_J:
|
|
|
|
Config::SetCurrent(Config::SYSCONF_COUNTRY, 0x01); // Japan
|
|
|
|
break;
|
|
|
|
case DiscIO::Region::NTSC_U:
|
|
|
|
Config::SetCurrent(Config::SYSCONF_COUNTRY, 0x31); // United States
|
|
|
|
break;
|
|
|
|
case DiscIO::Region::PAL:
|
|
|
|
Config::SetCurrent(Config::SYSCONF_COUNTRY, 0x6c); // Switzerland
|
|
|
|
break;
|
|
|
|
case DiscIO::Region::NTSC_K:
|
|
|
|
Config::SetCurrent(Config::SYSCONF_COUNTRY, 0x88); // South Korea
|
|
|
|
break;
|
2019-12-27 19:17:56 +01:00
|
|
|
case DiscIO::Region::Unknown:
|
|
|
|
break;
|
2019-06-30 12:44:38 +02:00
|
|
|
}
|
|
|
|
}
|
2019-06-30 11:48:49 +02:00
|
|
|
}
|
2015-06-14 17:03:45 +02:00
|
|
|
}
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2016-12-23 21:53:36 +01:00
|
|
|
// Some NTSC Wii games such as Doc Louis's Punch-Out!! and
|
|
|
|
// 1942 (Virtual Console) crash if the PAL60 option is enabled
|
2020-09-16 12:44:32 +02:00
|
|
|
if (StartUp.bWii && DiscIO::IsNTSC(StartUp.m_region) && Config::Get(Config::SYSCONF_PAL60))
|
2017-08-01 22:37:42 +08:00
|
|
|
Config::SetCurrent(Config::SYSCONF_PAL60, false);
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2021-10-10 23:23:20 +02:00
|
|
|
// Disable loading time emulation for Riivolution-patched games until we have proper emulation.
|
|
|
|
if (!boot->riivolution_patches.empty())
|
2022-01-06 01:33:46 +01:00
|
|
|
Config::SetCurrent(Config::MAIN_FAST_DISC_SPEED, true);
|
2021-10-10 23:23:20 +02:00
|
|
|
|
2022-01-07 03:50:18 +01:00
|
|
|
Core::System::GetInstance().Initialize();
|
|
|
|
|
2021-03-18 22:59:59 +01:00
|
|
|
Core::UpdateWantDeterminism(/*initial*/ true);
|
|
|
|
|
2016-09-25 13:45:07 +02:00
|
|
|
if (StartUp.bWii)
|
2020-03-16 13:02:35 +01:00
|
|
|
{
|
2021-03-18 22:59:59 +01:00
|
|
|
Core::InitializeWiiRoot(Core::WantsDeterminism());
|
2021-03-06 19:14:18 +01:00
|
|
|
|
|
|
|
// Ensure any new settings are written to the SYSCONF
|
2021-03-18 22:59:59 +01:00
|
|
|
if (!Core::WantsDeterminism())
|
2021-03-06 19:14:18 +01:00
|
|
|
{
|
|
|
|
Core::BackupWiiSettings();
|
|
|
|
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta, [](const Config::Location& location) {
|
|
|
|
return Config::GetActiveLayerForConfig(location) >= Config::LayerType::Movie;
|
|
|
|
});
|
|
|
|
}
|
2020-03-16 13:02:35 +01:00
|
|
|
}
|
2016-09-25 13:45:07 +02:00
|
|
|
|
2023-04-11 00:04:08 -04:00
|
|
|
#ifdef USE_RETRO_ACHIEVEMENTS
|
|
|
|
std::string path = "";
|
|
|
|
if (std::holds_alternative<BootParameters::Disc>(boot->parameters))
|
|
|
|
{
|
|
|
|
path = std::get<BootParameters::Disc>(boot->parameters).path;
|
|
|
|
}
|
|
|
|
AchievementManager::GetInstance()->LoadGameByFilenameAsync(
|
|
|
|
path, [](AchievementManager::ResponseType r_type) {});
|
|
|
|
#endif // USE_RETRO_ACHIEVEMENTS
|
|
|
|
|
2022-01-03 07:07:32 +01:00
|
|
|
const bool load_ipl = !StartUp.bWii && !Config::Get(Config::MAIN_SKIP_IPL) &&
|
2017-05-27 15:43:40 +02:00
|
|
|
std::holds_alternative<BootParameters::Disc>(boot->parameters);
|
|
|
|
if (load_ipl)
|
2011-02-12 22:31:57 +00:00
|
|
|
{
|
2018-10-03 23:03:22 +10:00
|
|
|
return Core::Init(
|
|
|
|
std::make_unique<BootParameters>(
|
|
|
|
BootParameters::IPL{StartUp.m_region,
|
|
|
|
std::move(std::get<BootParameters::Disc>(boot->parameters))},
|
2021-11-20 19:38:09 +01:00
|
|
|
std::move(boot->boot_session_data)),
|
2018-10-03 23:03:22 +10:00
|
|
|
wsi);
|
2011-02-12 22:31:57 +00:00
|
|
|
}
|
2018-10-03 23:03:22 +10:00
|
|
|
return Core::Init(std::move(boot), wsi);
|
2011-02-12 22:31:57 +00:00
|
|
|
}
|
|
|
|
|
2017-08-01 22:37:42 +08:00
|
|
|
// SYSCONF can be modified during emulation by the user and internally, which makes it
|
|
|
|
// a bad idea to just always overwrite it with the settings from the base layer.
|
|
|
|
//
|
2017-11-19 17:15:50 -08:00
|
|
|
// Conversely, we also shouldn't just accept any changes to SYSCONF, as it may cause
|
2017-08-01 22:37:42 +08:00
|
|
|
// temporary settings (from Movie, Netplay, game INIs, etc.) to stick around.
|
|
|
|
//
|
2017-11-19 17:15:50 -08:00
|
|
|
// To avoid inconveniences in most cases, we accept changes that aren't being overriden by a
|
|
|
|
// non-base layer, and restore only the overriden settings.
|
2017-08-01 22:37:42 +08:00
|
|
|
static void RestoreSYSCONF()
|
|
|
|
{
|
|
|
|
// This layer contains the new SYSCONF settings (including any temporary settings).
|
2017-11-19 17:15:50 -08:00
|
|
|
Config::Layer temp_layer(Config::LayerType::Base);
|
|
|
|
// Use a separate loader so the temp layer doesn't automatically save
|
|
|
|
ConfigLoaders::GenerateBaseConfigLoader()->Load(&temp_layer);
|
|
|
|
|
2017-08-01 22:37:42 +08:00
|
|
|
for (const auto& setting : Config::SYSCONF_SETTINGS)
|
|
|
|
{
|
|
|
|
std::visit(
|
2020-09-20 19:11:20 +02:00
|
|
|
[&](auto* info) {
|
2017-08-01 22:37:42 +08:00
|
|
|
// If this setting was overridden, then we copy the base layer value back to the SYSCONF.
|
|
|
|
// Otherwise we leave the new value in the SYSCONF.
|
2020-09-20 19:11:20 +02:00
|
|
|
if (Config::GetActiveLayerForConfig(*info) == Config::LayerType::Base)
|
|
|
|
Config::SetBase(*info, temp_layer.Get(*info));
|
2017-08-01 22:37:42 +08:00
|
|
|
},
|
|
|
|
setting.config_info);
|
|
|
|
}
|
|
|
|
// Save the SYSCONF.
|
2017-11-19 17:15:50 -08:00
|
|
|
Config::GetLayer(Config::LayerType::Base)->Save();
|
2017-08-01 22:37:42 +08:00
|
|
|
}
|
|
|
|
|
2016-10-07 21:57:07 +02:00
|
|
|
void RestoreConfig()
|
|
|
|
{
|
2021-03-06 19:14:18 +01:00
|
|
|
Core::ShutdownWiiRoot();
|
|
|
|
|
|
|
|
if (!Core::WiiRootIsTemporary())
|
|
|
|
{
|
|
|
|
Core::RestoreWiiSettings(Core::RestoreReason::EmulationEnd);
|
|
|
|
RestoreSYSCONF();
|
|
|
|
}
|
|
|
|
|
2017-05-13 23:34:49 +01:00
|
|
|
Config::ClearCurrentRunLayer();
|
2017-05-13 22:29:55 +01:00
|
|
|
Config::RemoveLayer(Config::LayerType::Movie);
|
|
|
|
Config::RemoveLayer(Config::LayerType::Netplay);
|
|
|
|
Config::RemoveLayer(Config::LayerType::GlobalGame);
|
|
|
|
Config::RemoveLayer(Config::LayerType::LocalGame);
|
2017-03-09 09:47:43 +01:00
|
|
|
SConfig::GetInstance().ResetRunningGameMetadata();
|
2011-02-12 22:31:57 +00:00
|
|
|
}
|
|
|
|
|
2018-07-19 18:10:37 -04:00
|
|
|
} // namespace BootManager
|