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;
|
||||
}
|
||||
|
||||
// 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
|
||||
const char* filename = nullptr;
|
||||
const char* exp1_filename = nullptr;
|
||||
|
@ -59,21 +50,14 @@ static int Run(int argc, char* argv[])
|
|||
#undef CHECK_ARG_PARAM
|
||||
}
|
||||
|
||||
// create system
|
||||
const bool boot = (filename != nullptr || exp1_filename != nullptr || !state_filename.IsEmpty());
|
||||
if (boot)
|
||||
// create display and host interface
|
||||
std::unique_ptr<SDLInterface> host_interface =
|
||||
SDLInterface::Create(filename, exp1_filename, state_filename.IsEmpty() ? nullptr : state_filename.GetCharArray());
|
||||
if (!host_interface)
|
||||
{
|
||||
if (!host_interface->InitializeSystem(filename, exp1_filename))
|
||||
{
|
||||
host_interface.reset();
|
||||
SDL_Quit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
host_interface->ConnectDevices();
|
||||
|
||||
if (!state_filename.IsEmpty())
|
||||
host_interface->LoadState(state_filename);
|
||||
Panic("Failed to create host interface");
|
||||
SDL_Quit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// run
|
||||
|
|
|
@ -193,7 +193,30 @@ bool SDLInterface::CreateAudioStream()
|
|||
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>();
|
||||
if (!intf->CreateSDLWindow() || !intf->CreateGLContext() || !intf->CreateImGuiContext() ||
|
||||
|
@ -202,6 +225,16 @@ std::unique_ptr<SDLInterface> SDLInterface::Create()
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -561,7 +594,7 @@ void SDLInterface::DrawMainMenuBar()
|
|||
|
||||
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()))
|
||||
DoSaveState(i);
|
||||
|
@ -842,12 +875,7 @@ void SDLInterface::DoStartDisc()
|
|||
|
||||
AddOSDMessage(SmallString::FromFormat("Starting disc from '%s'...", path));
|
||||
if (!InitializeSystem(path, nullptr))
|
||||
{
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "System initialization failed.", m_window);
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectDevices();
|
||||
}
|
||||
|
||||
void SDLInterface::DoStartBIOS()
|
||||
|
@ -856,16 +884,14 @@ void SDLInterface::DoStartBIOS()
|
|||
|
||||
AddOSDMessage("Starting BIOS...");
|
||||
if (!InitializeSystem(nullptr, nullptr))
|
||||
{
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "System initialization failed.", m_window);
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectDevices();
|
||||
}
|
||||
|
||||
void SDLInterface::DoLoadState(u32 index)
|
||||
{
|
||||
if (!HasSystem() && !InitializeSystem(nullptr, nullptr))
|
||||
return;
|
||||
|
||||
LoadState(GetSaveStateFilename(index));
|
||||
m_last_frame_number = m_system->GetFrameNumber();
|
||||
m_last_internal_frame_number = m_system->GetInternalFrameNumber();
|
||||
|
@ -875,18 +901,10 @@ void SDLInterface::DoLoadState(u32 index)
|
|||
|
||||
void SDLInterface::DoSaveState(u32 index)
|
||||
{
|
||||
Assert(m_system);
|
||||
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()
|
||||
{
|
||||
m_audio_stream->PauseOutput(false);
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#include <SDL.h>
|
||||
#include <array>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
class System;
|
||||
class DigitalController;
|
||||
|
@ -21,22 +21,24 @@ public:
|
|||
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);
|
||||
|
||||
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;
|
||||
|
||||
// Adds OSD messages, duration is in seconds.
|
||||
void AddOSDMessage(const char* message, float duration = 2.0f) override;
|
||||
|
||||
void ConnectDevices();
|
||||
|
||||
void Run();
|
||||
|
||||
private:
|
||||
static constexpr u32 NUM_QUICK_SAVE_STATES = 10;
|
||||
|
||||
struct OSDMessage
|
||||
{
|
||||
String text;
|
||||
|
@ -44,12 +46,17 @@ private:
|
|||
float duration;
|
||||
};
|
||||
|
||||
bool HasSystem() const { return static_cast<bool>(m_system); }
|
||||
|
||||
bool CreateSDLWindow();
|
||||
bool CreateGLContext();
|
||||
bool CreateImGuiContext();
|
||||
bool CreateGLResources();
|
||||
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
|
||||
bool IsWindowFullscreen() const;
|
||||
void DrawImGui();
|
||||
|
|
Loading…
Reference in a new issue