Boot: Clean up the boot code

* Move out boot parameters to a separate struct, which is not part
  of SConfig/ConfigManager because there is no reason for it to
  be there.

* Move out file name parsing and constructing the appropriate params
  from paths to a separate function that does that, and only that.

* For every different boot type we support, add a proper struct with
  only the required parameters, with descriptive names and use
  std::variant to only store what we need.

* Clean up the bHLE_BS2 stuff which made no sense sometimes. Now
  instead of using bHLE_BS2 for two different things, both for storing
  the user config setting and as a runtime boot parameter,
  we simply replace the Disc boot params with BootParameters::IPL.

* Const correctness so it's clear what can or cannot update the config.

* Drop unused parameters and unneeded checks.

* Make a few checks a lot more concise. (Looking at you, extension
  checks for disc images.)

* Remove a mildly terrible workaround where we needed to pass an empty
  string in order to boot the GC IPL without any game inserted.
  (Not required anymore thanks to std::variant and std::optional.)

The motivation for this are multiple: cleaning up and being able to add
support for booting an installed NAND title. Without this change, it'd
be pretty much impossible to implement that.

Also, using std::visit with std::variant makes the compiler do
additional type checks: now we're guaranteed that the boot code will
handle all boot types and no invalid boot type will be possible.
This commit is contained in:
Léo Lam
2017-05-27 15:43:40 +02:00
parent 4d2fb9b9ba
commit 22992ae41e
18 changed files with 468 additions and 440 deletions

View File

@ -10,6 +10,7 @@
#include <mutex>
#include <queue>
#include <utility>
#include <variant>
#ifdef _WIN32
#include <windows.h>
@ -122,7 +123,7 @@ static void InitIsCPUKey()
}
#endif
static void EmuThread();
static void EmuThread(std::unique_ptr<BootParameters> boot);
bool GetIsThrottlerTempDisabled()
{
@ -221,7 +222,7 @@ bool WantsDeterminism()
// This is called from the GUI thread. See the booting call schedule in
// BootManager.cpp
bool Init()
bool Init(std::unique_ptr<BootParameters> boot)
{
if (s_emu_thread.joinable())
{
@ -248,7 +249,7 @@ bool Init()
s_window_handle = Host_GetRenderHandle();
// Start the emu thread
s_emu_thread = std::thread(EmuThread);
s_emu_thread = std::thread(EmuThread, std::move(boot));
return true;
}
@ -412,21 +413,18 @@ static void FifoPlayerThread()
}
// Enter CPU run loop. When we leave it - we are done.
if (FifoPlayer::GetInstance().Open(_CoreParameter.m_strFilename))
if (auto cpu_core = FifoPlayer::GetInstance().GetCPUCore())
{
if (auto cpu_core = FifoPlayer::GetInstance().GetCPUCore())
{
PowerPC::InjectExternalCPUCore(cpu_core.get());
s_is_started = true;
PowerPC::InjectExternalCPUCore(cpu_core.get());
s_is_started = true;
CPUSetInitialExecutionState();
CPU::Run();
CPUSetInitialExecutionState();
CPU::Run();
s_is_started = false;
PowerPC::InjectExternalCPUCore(nullptr);
}
FifoPlayer::GetInstance().Close();
s_is_started = false;
PowerPC::InjectExternalCPUCore(nullptr);
}
FifoPlayer::GetInstance().Close();
// If we did not enter the CPU Run Loop above then run a fake one instead.
// We need to be IsRunningAndStarted() for DolphinWX to stop us.
@ -450,7 +448,7 @@ static void FifoPlayerThread()
// Initialize and create emulation thread
// Call browser: Init():s_emu_thread().
// See the BootManager.cpp file description for a complete call schedule.
static void EmuThread()
static void EmuThread(std::unique_ptr<BootParameters> boot)
{
const SConfig& core_parameter = SConfig::GetInstance();
s_is_booting.Set();
@ -474,12 +472,11 @@ static void EmuThread()
DisplayMessage("WARNING: running at non-native CPU clock! Game may not be stable.", 8000);
DisplayMessage(cpu_info.brand_string, 8000);
DisplayMessage(cpu_info.Summarize(), 8000);
DisplayMessage(core_parameter.m_strFilename, 3000);
// For a time this acts as the CPU thread...
DeclareAsCPUThread();
Movie::Init();
Movie::Init(*boot);
Common::ScopeGuard movie_guard{Movie::Shutdown};
HW::Init();
@ -560,7 +557,15 @@ static void EmuThread()
// Load GCM/DOL/ELF whatever ... we boot with the interpreter core
PowerPC::SetMode(PowerPC::CoreMode::Interpreter);
CBoot::BootUp();
// Determine the CPU thread function
void (*cpuThreadFunc)();
if (std::holds_alternative<BootParameters::DFF>(boot->parameters))
cpuThreadFunc = FifoPlayerThread;
else
cpuThreadFunc = CpuThread;
if (!CBoot::BootUp(std::move(boot)))
return;
// This adds the SyncGPU handler to CoreTiming, so now CoreTiming::Advance might block.
Fifo::Prepare();
@ -583,13 +588,6 @@ static void EmuThread()
Host_UpdateDisasmDialog();
Host_UpdateMainFrame();
// Determine the CPU thread function
void (*cpuThreadFunc)(void);
if (core_parameter.m_BootType == SConfig::BOOT_DFF)
cpuThreadFunc = FifoPlayerThread;
else
cpuThreadFunc = CpuThread;
// ENTER THE VIDEO THREAD LOOP
if (core_parameter.bCPUThread)
{