mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 15:45:42 +00:00
Frontend: Support loading state while powered off
This commit is contained in:
parent
1b8b730f85
commit
6c73dc6efb
|
@ -30,15 +30,6 @@ static int Run(int argc, char* argv[])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create display and host interface
|
|
||||||
std::unique_ptr<SDLInterface> host_interface = SDLInterface::Create();
|
|
||||||
if (!host_interface)
|
|
||||||
{
|
|
||||||
Panic("Failed to create host interface");
|
|
||||||
SDL_Quit();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
const char* filename = nullptr;
|
const char* filename = nullptr;
|
||||||
const char* exp1_filename = nullptr;
|
const char* exp1_filename = nullptr;
|
||||||
|
@ -59,23 +50,16 @@ static int Run(int argc, char* argv[])
|
||||||
#undef CHECK_ARG_PARAM
|
#undef CHECK_ARG_PARAM
|
||||||
}
|
}
|
||||||
|
|
||||||
// create system
|
// create display and host interface
|
||||||
const bool boot = (filename != nullptr || exp1_filename != nullptr || !state_filename.IsEmpty());
|
std::unique_ptr<SDLInterface> host_interface =
|
||||||
if (boot)
|
SDLInterface::Create(filename, exp1_filename, state_filename.IsEmpty() ? nullptr : state_filename.GetCharArray());
|
||||||
|
if (!host_interface)
|
||||||
{
|
{
|
||||||
if (!host_interface->InitializeSystem(filename, exp1_filename))
|
Panic("Failed to create host interface");
|
||||||
{
|
|
||||||
host_interface.reset();
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
host_interface->ConnectDevices();
|
|
||||||
|
|
||||||
if (!state_filename.IsEmpty())
|
|
||||||
host_interface->LoadState(state_filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
// run
|
// run
|
||||||
host_interface->Run();
|
host_interface->Run();
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,30 @@ bool SDLInterface::CreateAudioStream()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<SDLInterface> SDLInterface::Create()
|
bool SDLInterface::InitializeSystem(const char* filename, const char* exp1_filename)
|
||||||
|
{
|
||||||
|
if (!HostInterface::InitializeSystem(filename, exp1_filename))
|
||||||
|
{
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "System initialization failed.", m_window);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectDevices();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDLInterface::ConnectDevices()
|
||||||
|
{
|
||||||
|
m_controller = DigitalController::Create();
|
||||||
|
m_system->SetController(0, m_controller);
|
||||||
|
|
||||||
|
m_memory_card = MemoryCard::Create();
|
||||||
|
m_system->SetMemoryCard(0, m_memory_card);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<SDLInterface> SDLInterface::Create(const char* filename /* = nullptr */,
|
||||||
|
const char* exp1_filename /* = nullptr */,
|
||||||
|
const char* save_state_filename /* = nullptr */)
|
||||||
{
|
{
|
||||||
std::unique_ptr<SDLInterface> intf = std::make_unique<SDLInterface>();
|
std::unique_ptr<SDLInterface> intf = std::make_unique<SDLInterface>();
|
||||||
if (!intf->CreateSDLWindow() || !intf->CreateGLContext() || !intf->CreateImGuiContext() ||
|
if (!intf->CreateSDLWindow() || !intf->CreateGLContext() || !intf->CreateImGuiContext() ||
|
||||||
|
@ -202,6 +225,16 @@ std::unique_ptr<SDLInterface> SDLInterface::Create()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool boot = (filename != nullptr || exp1_filename != nullptr || save_state_filename != nullptr);
|
||||||
|
if (boot)
|
||||||
|
{
|
||||||
|
if (!intf->InitializeSystem(filename, exp1_filename))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (save_state_filename)
|
||||||
|
intf->LoadState(save_state_filename);
|
||||||
|
}
|
||||||
|
|
||||||
return intf;
|
return intf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,7 +594,7 @@ void SDLInterface::DrawMainMenuBar()
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Save State"))
|
if (ImGui::BeginMenu("Save State"))
|
||||||
{
|
{
|
||||||
for (u32 i = 1; i <= 8; i++)
|
for (u32 i = 1; i <= NUM_QUICK_SAVE_STATES; i++)
|
||||||
{
|
{
|
||||||
if (ImGui::MenuItem(TinyString::FromFormat("State %u", i).GetCharArray()))
|
if (ImGui::MenuItem(TinyString::FromFormat("State %u", i).GetCharArray()))
|
||||||
DoSaveState(i);
|
DoSaveState(i);
|
||||||
|
@ -842,30 +875,23 @@ void SDLInterface::DoStartDisc()
|
||||||
|
|
||||||
AddOSDMessage(SmallString::FromFormat("Starting disc from '%s'...", path));
|
AddOSDMessage(SmallString::FromFormat("Starting disc from '%s'...", path));
|
||||||
if (!InitializeSystem(path, nullptr))
|
if (!InitializeSystem(path, nullptr))
|
||||||
{
|
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "System initialization failed.", m_window);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectDevices();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDLInterface::DoStartBIOS()
|
void SDLInterface::DoStartBIOS()
|
||||||
{
|
{
|
||||||
Assert(!m_system);
|
Assert(!m_system);
|
||||||
|
|
||||||
AddOSDMessage("Starting BIOS...");
|
AddOSDMessage("Starting BIOS...");
|
||||||
if (!InitializeSystem(nullptr, nullptr))
|
if (!InitializeSystem(nullptr, nullptr))
|
||||||
{
|
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "System initialization failed.", m_window);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectDevices();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDLInterface::DoLoadState(u32 index)
|
void SDLInterface::DoLoadState(u32 index)
|
||||||
{
|
{
|
||||||
|
if (!HasSystem() && !InitializeSystem(nullptr, nullptr))
|
||||||
|
return;
|
||||||
|
|
||||||
LoadState(GetSaveStateFilename(index));
|
LoadState(GetSaveStateFilename(index));
|
||||||
m_last_frame_number = m_system->GetFrameNumber();
|
m_last_frame_number = m_system->GetFrameNumber();
|
||||||
m_last_internal_frame_number = m_system->GetInternalFrameNumber();
|
m_last_internal_frame_number = m_system->GetInternalFrameNumber();
|
||||||
|
@ -875,18 +901,10 @@ void SDLInterface::DoLoadState(u32 index)
|
||||||
|
|
||||||
void SDLInterface::DoSaveState(u32 index)
|
void SDLInterface::DoSaveState(u32 index)
|
||||||
{
|
{
|
||||||
|
Assert(m_system);
|
||||||
SaveState(GetSaveStateFilename(index));
|
SaveState(GetSaveStateFilename(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLInterface::ConnectDevices()
|
|
||||||
{
|
|
||||||
m_controller = DigitalController::Create();
|
|
||||||
m_system->SetController(0, m_controller);
|
|
||||||
|
|
||||||
m_memory_card = MemoryCard::Create();
|
|
||||||
m_system->SetMemoryCard(0, m_memory_card);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDLInterface::Run()
|
void SDLInterface::Run()
|
||||||
{
|
{
|
||||||
m_audio_stream->PauseOutput(false);
|
m_audio_stream->PauseOutput(false);
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <mutex>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
class System;
|
class System;
|
||||||
class DigitalController;
|
class DigitalController;
|
||||||
|
@ -21,22 +21,24 @@ public:
|
||||||
SDLInterface();
|
SDLInterface();
|
||||||
~SDLInterface();
|
~SDLInterface();
|
||||||
|
|
||||||
static std::unique_ptr<SDLInterface> Create();
|
static std::unique_ptr<SDLInterface> Create(const char* filename = nullptr, const char* exp1_filename = nullptr,
|
||||||
|
const char* save_state_filename = nullptr);
|
||||||
|
|
||||||
static TinyString GetSaveStateFilename(u32 index);
|
static TinyString GetSaveStateFilename(u32 index);
|
||||||
|
|
||||||
void SetDisplayTexture(GL::Texture* texture, u32 offset_x, u32 offset_y, u32 width, u32 height, float aspect_ratio) override;
|
void SetDisplayTexture(GL::Texture* texture, u32 offset_x, u32 offset_y, u32 width, u32 height,
|
||||||
|
float aspect_ratio) override;
|
||||||
|
|
||||||
void ReportMessage(const char* message) override;
|
void ReportMessage(const char* message) override;
|
||||||
|
|
||||||
// Adds OSD messages, duration is in seconds.
|
// Adds OSD messages, duration is in seconds.
|
||||||
void AddOSDMessage(const char* message, float duration = 2.0f) override;
|
void AddOSDMessage(const char* message, float duration = 2.0f) override;
|
||||||
|
|
||||||
void ConnectDevices();
|
|
||||||
|
|
||||||
void Run();
|
void Run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr u32 NUM_QUICK_SAVE_STATES = 10;
|
||||||
|
|
||||||
struct OSDMessage
|
struct OSDMessage
|
||||||
{
|
{
|
||||||
String text;
|
String text;
|
||||||
|
@ -44,12 +46,17 @@ private:
|
||||||
float duration;
|
float duration;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool HasSystem() const { return static_cast<bool>(m_system); }
|
||||||
|
|
||||||
bool CreateSDLWindow();
|
bool CreateSDLWindow();
|
||||||
bool CreateGLContext();
|
bool CreateGLContext();
|
||||||
bool CreateImGuiContext();
|
bool CreateImGuiContext();
|
||||||
bool CreateGLResources();
|
bool CreateGLResources();
|
||||||
bool CreateAudioStream();
|
bool CreateAudioStream();
|
||||||
|
|
||||||
|
bool InitializeSystem(const char* filename = nullptr, const char* exp1_filename = nullptr);
|
||||||
|
void ConnectDevices();
|
||||||
|
|
||||||
// We only pass mouse input through if it's grabbed
|
// We only pass mouse input through if it's grabbed
|
||||||
bool IsWindowFullscreen() const;
|
bool IsWindowFullscreen() const;
|
||||||
void DrawImGui();
|
void DrawImGui();
|
||||||
|
|
Loading…
Reference in a new issue