Skip to content

Commit

Permalink
Merge pull request #6271 from JosJuice/load-state-at-boot
Browse files Browse the repository at this point in the history
Redesign the ability to load state at boot
  • Loading branch information
leoetlino committed Dec 26, 2017
2 parents c9b78e2 + 9dd88d7 commit 3bc61ed
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 81 deletions.
24 changes: 17 additions & 7 deletions Source/Core/Core/Boot/Boot.cpp
Expand Up @@ -48,11 +48,15 @@
#include "DiscIO/Enums.h"
#include "DiscIO/Volume.h"

BootParameters::BootParameters(Parameters&& parameters_) : parameters(std::move(parameters_))
BootParameters::BootParameters(Parameters&& parameters_,
const std::optional<std::string>& savestate_path_)
: parameters(std::move(parameters_)), savestate_path(savestate_path_)
{
}

std::unique_ptr<BootParameters> BootParameters::GenerateFromFile(const std::string& path)
std::unique_ptr<BootParameters>
BootParameters::GenerateFromFile(const std::string& path,
const std::optional<std::string>& savestate_path)
{
const bool is_drive = cdio_is_cdrom(path);
// Check if the file exist, we may have gotten it from a --elf command line
Expand All @@ -73,13 +77,19 @@ std::unique_ptr<BootParameters> BootParameters::GenerateFromFile(const std::stri
{
std::unique_ptr<DiscIO::Volume> volume = DiscIO::CreateVolumeFromFilename(path);
if (volume)
return std::make_unique<BootParameters>(Disc{path, std::move(volume)});
return std::make_unique<BootParameters>(Disc{path, std::move(volume)}, savestate_path);

if (extension == ".elf")
return std::make_unique<BootParameters>(Executable{path, std::make_unique<ElfReader>(path)});
{
return std::make_unique<BootParameters>(Executable{path, std::make_unique<ElfReader>(path)},
savestate_path);
}

if (extension == ".dol")
return std::make_unique<BootParameters>(Executable{path, std::make_unique<DolReader>(path)});
{
return std::make_unique<BootParameters>(Executable{path, std::make_unique<DolReader>(path)},
savestate_path);
}

if (is_drive)
{
Expand All @@ -97,10 +107,10 @@ std::unique_ptr<BootParameters> BootParameters::GenerateFromFile(const std::stri
}

if (extension == ".dff")
return std::make_unique<BootParameters>(DFF{path});
return std::make_unique<BootParameters>(DFF{path}, savestate_path);

if (extension == ".wad")
return std::make_unique<BootParameters>(DiscIO::WiiWAD{path});
return std::make_unique<BootParameters>(DiscIO::WiiWAD{path}, savestate_path);

PanicAlertT("Could not recognize file %s", path.c_str());
return {};
Expand Down
7 changes: 5 additions & 2 deletions Source/Core/Core/Boot/Boot.h
Expand Up @@ -67,12 +67,15 @@ struct BootParameters
std::string dff_path;
};

static std::unique_ptr<BootParameters> GenerateFromFile(const std::string& path);
static std::unique_ptr<BootParameters>
GenerateFromFile(const std::string& boot_path,
const std::optional<std::string>& savestate_path = {});

using Parameters = std::variant<Disc, Executable, DiscIO::WiiWAD, NANDTitle, IPL, DFF>;
BootParameters(Parameters&& parameters_);
BootParameters(Parameters&& parameters_, const std::optional<std::string>& savestate_path_ = {});

Parameters parameters;
std::optional<std::string> savestate_path;
};

class CBoot
Expand Down
6 changes: 4 additions & 2 deletions Source/Core/Core/BootManager.cpp
Expand Up @@ -382,8 +382,10 @@ bool BootCore(std::unique_ptr<BootParameters> boot)
std::holds_alternative<BootParameters::Disc>(boot->parameters);
if (load_ipl)
{
return Core::Init(std::make_unique<BootParameters>(BootParameters::IPL{
StartUp.m_region, std::move(std::get<BootParameters::Disc>(boot->parameters))}));
return Core::Init(std::make_unique<BootParameters>(
BootParameters::IPL{StartUp.m_region,
std::move(std::get<BootParameters::Disc>(boot->parameters))},
boot->savestate_path));
}
return Core::Init(std::move(boot));
}
Expand Down
44 changes: 15 additions & 29 deletions Source/Core/Core/Core.cpp
Expand Up @@ -96,7 +96,6 @@ static bool s_hardware_initialized = false;
static bool s_is_started = false;
static Common::Flag s_is_booting;
static void* s_window_handle = nullptr;
static std::string s_state_filename;
static std::thread s_emu_thread;
static StateChangedCallbackFunc s_on_state_changed_callback;

Expand Down Expand Up @@ -136,15 +135,6 @@ void SetIsThrottlerTempDisabled(bool disable)
s_is_throttler_temp_disabled = disable;
}

std::string GetStateFileName()
{
return s_state_filename;
}
void SetStateFileName(const std::string& val)
{
s_state_filename = val;
}

void FrameUpdateOnCPUThread()
{
if (NetPlay::IsNetPlayRunning())
Expand Down Expand Up @@ -328,7 +318,7 @@ static void CPUSetInitialExecutionState()
}

// Create the CPU thread, which is a CPU + Video thread in Single Core mode.
static void CpuThread()
static void CpuThread(const std::optional<std::string>& savestate_path)
{
DeclareAsCPUThread();

Expand All @@ -351,17 +341,8 @@ static void CpuThread()
if (_CoreParameter.bFastmem)
EMM::InstallExceptionHandler(); // Let's run under memory watch

if (!s_state_filename.empty())
{
// Needs to PauseAndLock the Core
// NOTE: EmuThread should have left us in State::Stepping so nothing will happen
// until after the job is serviced.
QueueHostJob([] {
// Recheck in case Movie cleared it since.
if (!s_state_filename.empty())
::State::LoadAs(s_state_filename);
});
}
if (savestate_path)
QueueHostJob([&savestate_path] { ::State::LoadAs(*savestate_path); });

s_is_started = true;
CPUSetInitialExecutionState();
Expand Down Expand Up @@ -399,7 +380,7 @@ static void CpuThread()
EMM::UninstallExceptionHandler();
}

static void FifoPlayerThread()
static void FifoPlayerThread(const std::optional<std::string>& savestate_path)
{
DeclareAsCPUThread();
const SConfig& _CoreParameter = SConfig::GetInstance();
Expand Down Expand Up @@ -535,15 +516,20 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
Keyboard::LoadConfig();
}

const std::optional<std::string> savestate_path = boot->savestate_path;

// Load and Init Wiimotes - only if we are booting in Wii mode
if (core_parameter.bWii && !SConfig::GetInstance().m_bt_passthrough_enabled)
{
if (init_controllers)
Wiimote::Initialize(!s_state_filename.empty() ?
Wiimote::InitializeMode::DO_WAIT_FOR_WIIMOTES :
Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES);
{
Wiimote::Initialize(savestate_path ? Wiimote::InitializeMode::DO_WAIT_FOR_WIIMOTES :
Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES);
}
else
{
Wiimote::LoadConfig();
}
}

Common::ScopeGuard controller_guard{[init_controllers] {
Expand All @@ -570,7 +556,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
PowerPC::SetMode(PowerPC::CoreMode::Interpreter);

// Determine the CPU thread function
void (*cpuThreadFunc)();
void (*cpuThreadFunc)(const std::optional<std::string>& savestate_path);
if (std::holds_alternative<BootParameters::DFF>(boot->parameters))
cpuThreadFunc = FifoPlayerThread;
else
Expand Down Expand Up @@ -611,7 +597,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
Host_Message(WM_USER_CREATE);

// Spawn the CPU thread
s_cpu_thread = std::thread(cpuThreadFunc);
s_cpu_thread = std::thread(cpuThreadFunc, savestate_path);

// become the GPU thread
Fifo::RunGpuLoop();
Expand All @@ -629,7 +615,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
Common::SetCurrentThreadName("Emuthread - Idle");

// Spawn the CPU+GPU thread
s_cpu_thread = std::thread(cpuThreadFunc);
s_cpu_thread = std::thread(cpuThreadFunc, savestate_path);

while (CPU::GetState() != CPU::State::PowerDown)
{
Expand Down
3 changes: 0 additions & 3 deletions Source/Core/Core/Core.h
Expand Up @@ -64,9 +64,6 @@ void Callback_WiimoteInterruptChannel(int _number, u16 _channelID, const void* _
// This displays messages in a user-visible way.
void DisplayMessage(const std::string& message, int time_in_ms);

std::string GetStateFileName();
void SetStateFileName(const std::string& val);

void FrameUpdateOnCPUThread();

bool ShouldSkipFrame(int skipped);
Expand Down
24 changes: 11 additions & 13 deletions Source/Core/Core/Movie.cpp
Expand Up @@ -232,8 +232,6 @@ void Init(const BootParameters& boot)
}

memset(&s_padState, 0, sizeof(s_padState));
if (!tmpHeader.bFromSaveState || !IsPlayingInput())
Core::SetStateFileName("");

for (auto& disp : s_InputDisplay)
disp.clear();
Expand Down Expand Up @@ -865,12 +863,12 @@ void ReadHeader()
}

// NOTE: Host Thread
bool PlayInput(const std::string& filename)
bool PlayInput(const std::string& movie_path, std::optional<std::string>* savestate_path)
{
if (s_playMode != MODE_NONE)
return false;

File::IOFile recording_file(filename, "rb");
File::IOFile recording_file(movie_path, "rb");
if (!recording_file.ReadArray(&tmpHeader, 1))
return false;

Expand Down Expand Up @@ -902,13 +900,13 @@ bool PlayInput(const std::string& filename)
recording_file.Close();

// Load savestate (and skip to frame data)
if (tmpHeader.bFromSaveState)
if (tmpHeader.bFromSaveState && savestate_path)
{
const std::string stateFilename = filename + ".sav";
if (File::Exists(stateFilename))
Core::SetStateFileName(stateFilename);
const std::string savestate_path_temp = movie_path + ".sav";
if (File::Exists(savestate_path_temp))
*savestate_path = savestate_path_temp;
s_bRecordingFromSaveState = true;
Movie::LoadInput(filename);
Movie::LoadInput(movie_path);
}

return true;
Expand All @@ -928,12 +926,12 @@ void DoState(PointerWrap& p)
}

// NOTE: Host Thread
void LoadInput(const std::string& filename)
void LoadInput(const std::string& movie_path)
{
File::IOFile t_record;
if (!t_record.Open(filename, "r+b"))
if (!t_record.Open(movie_path, "r+b"))
{
PanicAlertT("Failed to read %s", filename.c_str());
PanicAlertT("Failed to read %s", movie_path.c_str());
EndPlayInput(false);
return;
}
Expand All @@ -942,7 +940,7 @@ void LoadInput(const std::string& filename)

if (!IsMovieHeader(tmpHeader.filetype))
{
PanicAlertT("Savestate movie %s is corrupted, movie recording stopping...", filename.c_str());
PanicAlertT("Savestate movie %s is corrupted, movie recording stopping...", movie_path.c_str());
EndPlayInput(false);
return;
}
Expand Down
5 changes: 3 additions & 2 deletions Source/Core/Core/Movie.h
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include <functional>
#include <optional>
#include <string>

#include "Common/CommonTypes.h"
Expand Down Expand Up @@ -157,8 +158,8 @@ bool BeginRecordingInput(int controllers);
void RecordInput(GCPadStatus* PadStatus, int controllerID);
void RecordWiimote(int wiimote, u8* data, u8 size);

bool PlayInput(const std::string& filename);
void LoadInput(const std::string& filename);
bool PlayInput(const std::string& movie_path, std::optional<std::string>* savestate_path);
void LoadInput(const std::string& movie_path);
void ReadHeader();
void PlayController(GCPadStatus* PadStatus, int controllerID);
bool PlayWiimote(int wiimote, u8* data, const struct WiimoteEmu::ReportFeatures& rptf, int ext,
Expand Down

0 comments on commit 3bc61ed

Please sign in to comment.