mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
VMManager: Improve error handling for initialization functions
This commit is contained in:
parent
eaa834d238
commit
2805bf376a
@ -221,9 +221,12 @@ void EmuThread::startVM(std::shared_ptr<VMBootParameters> boot_params)
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
auto done_callback = [](VMBootResult result) {
|
auto done_callback = [](VMBootResult result, const Error& error) {
|
||||||
if (result != VMBootResult::StartupSuccess)
|
if (result != VMBootResult::StartupSuccess)
|
||||||
|
{
|
||||||
|
Host::ReportErrorAsync(TRANSLATE_STR("QtHost", "Startup Error"), error.GetDescription());
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Host::GetBoolSettingValue("UI", "StartPaused", false))
|
if (!Host::GetBoolSettingValue("UI", "StartPaused", false))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -13,6 +13,8 @@
|
|||||||
#include "GS/GSLzma.h"
|
#include "GS/GSLzma.h"
|
||||||
#include "GS/GSExtra.h"
|
#include "GS/GSExtra.h"
|
||||||
|
|
||||||
|
#include "Host.h"
|
||||||
|
|
||||||
#include <Alloc.h>
|
#include <Alloc.h>
|
||||||
#include <7zCrc.h>
|
#include <7zCrc.h>
|
||||||
#include <Xz.h>
|
#include <Xz.h>
|
||||||
@ -73,14 +75,14 @@ bool GSDumpFile::ReadFile(Error* error)
|
|||||||
u32 ss;
|
u32 ss;
|
||||||
if (Read(&m_crc, sizeof(m_crc)) != sizeof(m_crc) || Read(&ss, sizeof(ss)) != sizeof(ss))
|
if (Read(&m_crc, sizeof(m_crc)) != sizeof(m_crc) || Read(&ss, sizeof(ss)) != sizeof(ss))
|
||||||
{
|
{
|
||||||
Error::SetString(error, "Failed to read header");
|
Error::SetString(error, TRANSLATE_STR("GSDumpFile", "Failed to read header."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_state_data.resize(ss);
|
m_state_data.resize(ss);
|
||||||
if (Read(m_state_data.data(), ss) != ss)
|
if (Read(m_state_data.data(), ss) != ss)
|
||||||
{
|
{
|
||||||
Error::SetString(error, "Failed to read state data");
|
Error::SetString(error, TRANSLATE_STR("GSDumpFile", "Failed to read state data."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +92,7 @@ bool GSDumpFile::ReadFile(Error* error)
|
|||||||
GSDumpHeader header;
|
GSDumpHeader header;
|
||||||
if (m_state_data.size() < sizeof(header))
|
if (m_state_data.size() < sizeof(header))
|
||||||
{
|
{
|
||||||
Error::SetString(error, "GSDump header is corrupted.");
|
Error::SetString(error, TRANSLATE_STR("GSDumpFile", "GSDump header is corrupted."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +104,7 @@ bool GSDumpFile::ReadFile(Error* error)
|
|||||||
{
|
{
|
||||||
if (header.serial_offset > ss || (static_cast<u64>(header.serial_offset) + header.serial_size) > ss)
|
if (header.serial_offset > ss || (static_cast<u64>(header.serial_offset) + header.serial_size) > ss)
|
||||||
{
|
{
|
||||||
Error::SetString(error, "GSDump header is corrupted.");
|
Error::SetString(error, TRANSLATE_STR("GSDumpFile", "GSDump header is corrupted."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +116,7 @@ bool GSDumpFile::ReadFile(Error* error)
|
|||||||
m_state_data.resize(header.state_size);
|
m_state_data.resize(header.state_size);
|
||||||
if (Read(m_state_data.data(), header.state_size) != header.state_size)
|
if (Read(m_state_data.data(), header.state_size) != header.state_size)
|
||||||
{
|
{
|
||||||
Error::SetString(error, "Failed to read real state data");
|
Error::SetString(error, TRANSLATE_STR("GSDumpFile", "Failed to read real state data"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,7 +124,7 @@ bool GSDumpFile::ReadFile(Error* error)
|
|||||||
m_regs_data.resize(8192);
|
m_regs_data.resize(8192);
|
||||||
if (Read(m_regs_data.data(), m_regs_data.size()) != m_regs_data.size())
|
if (Read(m_regs_data.data(), m_regs_data.size()) != m_regs_data.size())
|
||||||
{
|
{
|
||||||
Error::SetString(error, "Failed to read regs data");
|
Error::SetString(error, TRANSLATE_STR("GSDumpFile", "Failed to read regs data."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +141,7 @@ bool GSDumpFile::ReadFile(Error* error)
|
|||||||
{
|
{
|
||||||
if (!IsEof())
|
if (!IsEof())
|
||||||
{
|
{
|
||||||
Error::SetString(error, "Failed to read packet");
|
Error::SetString(error, TRANSLATE_STR("GSDumpFile", "Failed to read packet."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +159,7 @@ bool GSDumpFile::ReadFile(Error* error)
|
|||||||
{ \
|
{ \
|
||||||
if (remaining < sizeof(u8)) \
|
if (remaining < sizeof(u8)) \
|
||||||
{ \
|
{ \
|
||||||
Error::SetString(error, "Failed to read byte"); \
|
Error::SetString(error, TRANSLATE_STR("GSDumpFile", "Failed to read byte.")); \
|
||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
std::memcpy(dst, data, sizeof(u8)); \
|
std::memcpy(dst, data, sizeof(u8)); \
|
||||||
@ -169,7 +171,7 @@ bool GSDumpFile::ReadFile(Error* error)
|
|||||||
{ \
|
{ \
|
||||||
if (remaining < sizeof(u32)) \
|
if (remaining < sizeof(u32)) \
|
||||||
{ \
|
{ \
|
||||||
Error::SetString(error, "Failed to read word"); \
|
Error::SetString(error, TRANSLATE_STR("GSDumpFile", "Failed to read word.")); \
|
||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
std::memcpy(dst, data, sizeof(u32)); \
|
std::memcpy(dst, data, sizeof(u32)); \
|
||||||
@ -199,7 +201,8 @@ bool GSDumpFile::ReadFile(Error* error)
|
|||||||
packet.length = 8192;
|
packet.length = 8192;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Error::SetString(error, fmt::format("Unknown packet type {}", static_cast<u32>(packet.id)));
|
Error::SetStringFmt(error,
|
||||||
|
TRANSLATE_FS("GSDumpFile", "Unknown packet type {}"), static_cast<u32>(packet.id));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +334,7 @@ namespace
|
|||||||
look_stream.buf = static_cast<Byte*>(ISzAlloc_Alloc(&g_Alloc, kInputBufSize));
|
look_stream.buf = static_cast<Byte*>(ISzAlloc_Alloc(&g_Alloc, kInputBufSize));
|
||||||
if (!look_stream.buf)
|
if (!look_stream.buf)
|
||||||
{
|
{
|
||||||
Error::SetString(error, "Failed to allocate lookahead buffer");
|
Error::SetString(error, TRANSLATE_STR("GSDumpLzma", "Failed to allocate lookahead buffer."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ScopedGuard guard = [&look_stream]() {
|
ScopedGuard guard = [&look_stream]() {
|
||||||
@ -351,14 +354,14 @@ namespace
|
|||||||
SRes res = Xzs_ReadBackward(&xzs, &look_stream.vt, &start_pos, nullptr, &g_Alloc);
|
SRes res = Xzs_ReadBackward(&xzs, &look_stream.vt, &start_pos, nullptr, &g_Alloc);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
{
|
{
|
||||||
Error::SetString(error, fmt::format("Xzs_ReadBackward() failed: {}", res));
|
Error::SetStringFmt(error, TRANSLATE_FS("GSDumpLzma", "Xzs_ReadBackward() failed: {}."), res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t num_blocks = Xzs_GetNumBlocks(&xzs);
|
const size_t num_blocks = Xzs_GetNumBlocks(&xzs);
|
||||||
if (num_blocks == 0)
|
if (num_blocks == 0)
|
||||||
{
|
{
|
||||||
Error::SetString(error, "Stream has no blocks.");
|
Error::SetString(error, TRANSLATE_STR("GSDumpLzma", "Stream has no blocks."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -85,17 +85,17 @@ int GSDumpReplayer::GetLoopCount()
|
|||||||
return s_dump_loop_count;
|
return s_dump_loop_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSDumpReplayer::Initialize(const char* filename)
|
bool GSDumpReplayer::Initialize(const char* filename, Error* error)
|
||||||
{
|
{
|
||||||
Common::Timer timer;
|
Common::Timer timer;
|
||||||
Console.WriteLn("(GSDumpReplayer) Reading file '%s'...", filename);
|
Console.WriteLn("(GSDumpReplayer) Reading file '%s'...", filename);
|
||||||
|
|
||||||
Error error;
|
Error dump_error;
|
||||||
s_dump_file = GSDumpFile::OpenGSDump(filename, &error);
|
s_dump_file = GSDumpFile::OpenGSDump(filename, &dump_error);
|
||||||
if (!s_dump_file || !s_dump_file->ReadFile(&error))
|
if (!s_dump_file || !s_dump_file->ReadFile(&dump_error))
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("GSDumpReplayer", fmt::format("Failed to open or read '{}': {}",
|
Error::SetStringFmt(error, TRANSLATE_FS("GSDumpReplayer", "Failed to open or read '{}': {}"),
|
||||||
Path::GetFileName(filename), error.GetDescription()));
|
Path::GetFileName(filename), dump_error.GetDescription());
|
||||||
s_dump_file.reset();
|
s_dump_file.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/Error.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -16,7 +18,7 @@ namespace GSDumpReplayer
|
|||||||
bool IsRunner();
|
bool IsRunner();
|
||||||
void SetIsDumpRunner(bool is_runner);
|
void SetIsDumpRunner(bool is_runner);
|
||||||
|
|
||||||
bool Initialize(const char* filename);
|
bool Initialize(const char* filename, Error* error = nullptr);
|
||||||
bool ChangeDump(const char* filename);
|
bool ChangeDump(const char* filename);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
|
|||||||
@ -1461,11 +1461,19 @@ void FullscreenUI::DoVMInitialize(const VMBootParameters& boot_params, bool swit
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
auto done_callback = [switch_to_landing_on_failure](VMBootResult result) {
|
auto done_callback = [switch_to_landing_on_failure](VMBootResult result, const Error& error) {
|
||||||
if (result == VMBootResult::StartupSuccess)
|
if (result != VMBootResult::StartupSuccess)
|
||||||
VMManager::SetState(VMState::Running);
|
{
|
||||||
else if (switch_to_landing_on_failure)
|
ImGuiFullscreen::OpenInfoMessageDialog(
|
||||||
MTGS::RunOnGSThread(SwitchToLanding);
|
FSUI_ICONSTR(ICON_FA_TRIANGLE_EXCLAMATION, "Startup Error"), error.GetDescription());
|
||||||
|
|
||||||
|
if (switch_to_landing_on_failure)
|
||||||
|
MTGS::RunOnGSThread(SwitchToLanding);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VMManager::SetState(VMState::Running);
|
||||||
};
|
};
|
||||||
|
|
||||||
VMManager::InitializeAsync(boot_params, std::move(hardcore_disable_callback), std::move(done_callback));
|
VMManager::InitializeAsync(boot_params, std::move(hardcore_disable_callback), std::move(done_callback));
|
||||||
|
|||||||
@ -102,7 +102,7 @@ namespace VMManager
|
|||||||
static void LogUnsafeSettingsToConsole(const std::string& messages);
|
static void LogUnsafeSettingsToConsole(const std::string& messages);
|
||||||
static void WarnAboutUnsafeSettings();
|
static void WarnAboutUnsafeSettings();
|
||||||
|
|
||||||
static bool AutoDetectSource(const std::string& filename);
|
static bool AutoDetectSource(const std::string& filename, Error* error = nullptr);
|
||||||
static void UpdateDiscDetails(bool booting);
|
static void UpdateDiscDetails(bool booting);
|
||||||
static void ClearDiscDetails();
|
static void ClearDiscDetails();
|
||||||
static void HandleELFChange(bool verbose_patches_if_changed);
|
static void HandleELFChange(bool verbose_patches_if_changed);
|
||||||
@ -1197,20 +1197,20 @@ bool VMManager::HasBootedELF()
|
|||||||
return s_current_crc != 0 && s_elf_executed;
|
return s_current_crc != 0 && s_elf_executed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VMManager::AutoDetectSource(const std::string& filename)
|
bool VMManager::AutoDetectSource(const std::string& filename, Error* error)
|
||||||
{
|
{
|
||||||
if (!filename.empty())
|
if (!filename.empty())
|
||||||
{
|
{
|
||||||
if (!FileSystem::FileExists(filename.c_str()))
|
if (!FileSystem::FileExists(filename.c_str()))
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Error", fmt::format("Requested filename '{}' does not exist.", filename));
|
Error::SetStringFmt(error, TRANSLATE_FS("VMManager", "Requested filename '{}' does not exist."), filename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsGSDumpFileName(filename))
|
if (IsGSDumpFileName(filename))
|
||||||
{
|
{
|
||||||
CDVDsys_ChangeSource(CDVD_SourceType::NoDisc);
|
CDVDsys_ChangeSource(CDVD_SourceType::NoDisc);
|
||||||
return GSDumpReplayer::Initialize(filename.c_str());
|
return GSDumpReplayer::Initialize(filename.c_str(), error);
|
||||||
}
|
}
|
||||||
else if (IsElfFileName(filename))
|
else if (IsElfFileName(filename))
|
||||||
{
|
{
|
||||||
@ -1272,7 +1272,8 @@ void VMManager::InitializeAsync(
|
|||||||
VMBootHardcoreDisableCallback hardcore_disable_callback,
|
VMBootHardcoreDisableCallback hardcore_disable_callback,
|
||||||
VMBootDoneCallback done_callback)
|
VMBootDoneCallback done_callback)
|
||||||
{
|
{
|
||||||
VMBootResult result = VMManager::Initialize(boot_params);
|
Error error;
|
||||||
|
VMBootResult result = VMManager::Initialize(boot_params, &error);
|
||||||
|
|
||||||
if (result == VMBootResult::PromptDisableHardcoreMode)
|
if (result == VMBootResult::PromptDisableHardcoreMode)
|
||||||
{
|
{
|
||||||
@ -1286,21 +1287,24 @@ void VMManager::InitializeAsync(
|
|||||||
[boot_params, done_callback = std::move(done_callback)]() {
|
[boot_params, done_callback = std::move(done_callback)]() {
|
||||||
VMBootParameters new_boot_params = std::move(boot_params);
|
VMBootParameters new_boot_params = std::move(boot_params);
|
||||||
new_boot_params.disable_achievements_hardcore_mode = true;
|
new_boot_params.disable_achievements_hardcore_mode = true;
|
||||||
done_callback(VMManager::Initialize(new_boot_params));
|
|
||||||
|
Error error;
|
||||||
|
VMBootResult result = VMManager::Initialize(new_boot_params, &error);
|
||||||
|
done_callback(result, error);
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_callback(result);
|
done_callback(result, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
VMBootResult VMManager::Initialize(const VMBootParameters& boot_params, Error* error)
|
||||||
{
|
{
|
||||||
const Common::Timer init_timer;
|
const Common::Timer init_timer;
|
||||||
if (s_state.load(std::memory_order_acquire) != VMState::Shutdown)
|
if (s_state.load(std::memory_order_acquire) != VMState::Shutdown)
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Error", "The virtual machine is already running.");
|
Error::SetString(error, TRANSLATE_STR("VMManager", "The virtual machine is already running."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1344,24 +1348,22 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
{
|
{
|
||||||
if (boot_params.filename.empty())
|
if (boot_params.filename.empty())
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Error", "Cannot load an indexed save state without a boot filename.");
|
Error::SetString(error,
|
||||||
|
TRANSLATE_STR("VMManager", "Cannot load an indexed save state without a boot filename."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
state_to_load = GetSaveStateFileName(boot_params.filename.c_str(), boot_params.state_index.value());
|
state_to_load = GetSaveStateFileName(boot_params.filename.c_str(), boot_params.state_index.value());
|
||||||
if (state_to_load.empty())
|
if (state_to_load.empty())
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Error", "Could not resolve path indexed save state load.");
|
Error::SetString(error,
|
||||||
|
TRANSLATE_STR("VMManager", "Could not resolve path for indexed save state load."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Error cdvd_lock_error;
|
if (!cdvdLock(error))
|
||||||
if (!cdvdLock(&cdvd_lock_error))
|
|
||||||
{
|
|
||||||
Host::ReportErrorAsync("Startup Error", cdvd_lock_error.GetDescription());
|
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
|
||||||
|
|
||||||
ScopedGuard unlock_cdvd = &cdvdUnlock;
|
ScopedGuard unlock_cdvd = &cdvdUnlock;
|
||||||
|
|
||||||
@ -1371,8 +1373,8 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
if (boot_params.source_type.value() == CDVD_SourceType::Iso &&
|
if (boot_params.source_type.value() == CDVD_SourceType::Iso &&
|
||||||
!FileSystem::FileExists(boot_params.filename.c_str()))
|
!FileSystem::FileExists(boot_params.filename.c_str()))
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync(
|
Error::SetStringFmt(error,
|
||||||
"Error", fmt::format("Requested filename '{}' does not exist.", boot_params.filename));
|
TRANSLATE_FS("VMManager", "Requested filename '{}' does not exist."), boot_params.filename);
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1383,7 +1385,7 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Automatic type detection of boot parameter based on filename.
|
// Automatic type detection of boot parameter based on filename.
|
||||||
if (!AutoDetectSource(boot_params.filename))
|
if (!AutoDetectSource(boot_params.filename, error))
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1395,15 +1397,14 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
Console.WriteLn("Loading BIOS...");
|
Console.WriteLn("Loading BIOS...");
|
||||||
if (!LoadBIOS())
|
if (!LoadBIOS())
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync(TRANSLATE_SV("VMManager", "Error – No BIOS Present"),
|
Error::SetStringFmt(error,
|
||||||
fmt::format(
|
TRANSLATE_FS("VMManager",
|
||||||
TRANSLATE_FS("VMManager",
|
"PCSX2 requires a PlayStation 2 BIOS in order to run.\n\n"
|
||||||
"PCSX2 requires a PlayStation 2 BIOS in order to run.\n\n"
|
"For legal reasons, you will need to obtain this BIOS from a PlayStation 2 unit which you own.\n\n"
|
||||||
"For legal reasons, you will need to obtain this BIOS from a PlayStation 2 unit which you own.\n\n"
|
"For step-by-step help with this process, please consult the setup guide at {}.\n\n"
|
||||||
"For step-by-step help with this process, please consult the setup guide at {}.\n\n"
|
"PCSX2 will be able to run once you've placed your BIOS image inside the folder named \"bios\" within the data directory "
|
||||||
"PCSX2 will be able to run once you've placed your BIOS image inside the folder named \"bios\" within the data directory "
|
"(Tools Menu -> Open Data Directory)."),
|
||||||
"(Tools Menu -> Open Data Directory)."),
|
PCSX2_DOCUMENTATION_BIOS_URL_SHORTENED);
|
||||||
PCSX2_DOCUMENTATION_BIOS_URL_SHORTENED));
|
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1411,13 +1412,13 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
cdvdLoadNVRAM();
|
cdvdLoadNVRAM();
|
||||||
}
|
}
|
||||||
|
|
||||||
Error error;
|
Error cdvd_error;
|
||||||
Console.WriteLn("Opening CDVD...");
|
Console.WriteLn("Opening CDVD...");
|
||||||
if (!DoCDVDopen(&error))
|
if (!DoCDVDopen(&cdvd_error))
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Startup Error", fmt::format("Failed to open CDVD '{}': {}.",
|
Error::SetStringFmt(error, TRANSLATE_FS("VMManager", "Failed to open CDVD '{}': {}."),
|
||||||
Path::GetFileName(CDVDsys_GetFile(CDVDsys_GetSourceType())),
|
Path::GetFileName(CDVDsys_GetFile(CDVDsys_GetSourceType())),
|
||||||
error.GetDescription()));
|
cdvd_error.GetDescription());
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
ScopedGuard close_cdvd(&DoCDVDclose);
|
ScopedGuard close_cdvd(&DoCDVDclose);
|
||||||
@ -1438,7 +1439,8 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
{
|
{
|
||||||
if (!FileSystem::FileExists(s_elf_override.c_str()))
|
if (!FileSystem::FileExists(s_elf_override.c_str()))
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Error", fmt::format("Requested boot ELF '{}' does not exist.", s_elf_override));
|
Error::SetStringFmt(error,
|
||||||
|
TRANSLATE_FS("VMManager", "Requested boot ELF '{}' does not exist."), s_elf_override);
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1484,7 +1486,7 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
if (!s_gs_open_on_initialize && !MTGS::WaitForOpen())
|
if (!s_gs_open_on_initialize && !MTGS::WaitForOpen())
|
||||||
{
|
{
|
||||||
// we assume GS is going to report its own error
|
// we assume GS is going to report its own error
|
||||||
Console.WriteLn("Failed to open GS.");
|
Error::SetString(error, TRANSLATE_STR("VMManager", "Failed to initialize GS."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1496,7 +1498,7 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
Console.WriteLn("Opening SPU2...");
|
Console.WriteLn("Opening SPU2...");
|
||||||
if (!SPU2::Open())
|
if (!SPU2::Open())
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Startup Error", "Failed to initialize SPU2.");
|
Error::SetString(error, TRANSLATE_STR("VMManager", "Failed to initialize SPU2."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
ScopedGuard close_spu2(&SPU2::Close);
|
ScopedGuard close_spu2(&SPU2::Close);
|
||||||
@ -1505,7 +1507,7 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
Console.WriteLn("Initializing Pad...");
|
Console.WriteLn("Initializing Pad...");
|
||||||
if (!Pad::Initialize())
|
if (!Pad::Initialize())
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Startup Error", "Failed to initialize PAD");
|
Error::SetString(error, TRANSLATE_STR("VMManager", "Failed to initialize PAD."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
ScopedGuard close_pad = &Pad::Shutdown;
|
ScopedGuard close_pad = &Pad::Shutdown;
|
||||||
@ -1513,7 +1515,7 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
Console.WriteLn("Initializing SIO2...");
|
Console.WriteLn("Initializing SIO2...");
|
||||||
if (!g_Sio2.Initialize())
|
if (!g_Sio2.Initialize())
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Startup Error", "Failed to initialize SIO2");
|
Error::SetString(error, TRANSLATE_STR("VMManager", "Failed to initialize SIO2."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
ScopedGuard close_sio2 = []() {
|
ScopedGuard close_sio2 = []() {
|
||||||
@ -1523,7 +1525,7 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
Console.WriteLn("Initializing SIO0...");
|
Console.WriteLn("Initializing SIO0...");
|
||||||
if (!g_Sio0.Initialize())
|
if (!g_Sio0.Initialize())
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Startup Error", "Failed to initialize SIO0");
|
Error::SetString(error, TRANSLATE_STR("VMManager", "Failed to initialize SIO0."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
ScopedGuard close_sio0 = []() {
|
ScopedGuard close_sio0 = []() {
|
||||||
@ -1533,7 +1535,7 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
Console.WriteLn("Opening DEV9...");
|
Console.WriteLn("Opening DEV9...");
|
||||||
if (DEV9init() != 0 || DEV9open() != 0)
|
if (DEV9init() != 0 || DEV9open() != 0)
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Startup Error", "Failed to initialize DEV9.");
|
Error::SetString(error, TRANSLATE_STR("VMManager", "Failed to initialize DEV9."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
ScopedGuard close_dev9 = []() {
|
ScopedGuard close_dev9 = []() {
|
||||||
@ -1544,7 +1546,7 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
Console.WriteLn("Opening USB...");
|
Console.WriteLn("Opening USB...");
|
||||||
if (!USBopen())
|
if (!USBopen())
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Startup Error", "Failed to initialize USB.");
|
Error::SetString(error, TRANSLATE_STR("VMManager", "Failed to initialize USB."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
ScopedGuard close_usb = []() { USBclose(); };
|
ScopedGuard close_usb = []() { USBclose(); };
|
||||||
@ -1552,7 +1554,7 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
Console.WriteLn("Opening FW...");
|
Console.WriteLn("Opening FW...");
|
||||||
if (FWopen() != 0)
|
if (FWopen() != 0)
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync("Startup Error", "Failed to initialize FW.");
|
Error::SetString(error, TRANSLATE_STR("VMManager", "Failed to initialize FW."));
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
ScopedGuard close_fw = []() { FWclose(); };
|
ScopedGuard close_fw = []() { FWclose(); };
|
||||||
@ -1588,10 +1590,8 @@ VMBootResult VMManager::Initialize(const VMBootParameters& boot_params)
|
|||||||
// do we want to load state?
|
// do we want to load state?
|
||||||
if (!GSDumpReplayer::IsReplayingDump() && !state_to_load.empty())
|
if (!GSDumpReplayer::IsReplayingDump() && !state_to_load.empty())
|
||||||
{
|
{
|
||||||
Error state_error;
|
if (!DoLoadState(state_to_load.c_str(), error))
|
||||||
if (!DoLoadState(state_to_load.c_str(), &state_error))
|
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync(TRANSLATE_SV("VMManager", "Failed to load save state."), state_error.GetDescription());
|
|
||||||
Shutdown(false);
|
Shutdown(false);
|
||||||
return VMBootResult::StartupFailure;
|
return VMBootResult::StartupFailure;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,7 @@ using VMBootHardcoreDisableCallback = std::function<void(std::string reason, VMB
|
|||||||
|
|
||||||
/// Callback used when the VM boot process has finished. This may be called
|
/// Callback used when the VM boot process has finished. This may be called
|
||||||
/// asynchronously after the user has been prompted to disable hardcore mode.
|
/// asynchronously after the user has been prompted to disable hardcore mode.
|
||||||
using VMBootDoneCallback = std::function<void(VMBootResult result)>;
|
using VMBootDoneCallback = std::function<void(VMBootResult result, const Error& error)>;
|
||||||
|
|
||||||
namespace VMManager
|
namespace VMManager
|
||||||
{
|
{
|
||||||
@ -116,7 +116,7 @@ namespace VMManager
|
|||||||
VMBootDoneCallback done_callback);
|
VMBootDoneCallback done_callback);
|
||||||
|
|
||||||
/// Initializes all system components. Will not attempt to restart itself.
|
/// Initializes all system components. Will not attempt to restart itself.
|
||||||
VMBootResult Initialize(const VMBootParameters& boot_params);
|
VMBootResult Initialize(const VMBootParameters& boot_params, Error* error = nullptr);
|
||||||
|
|
||||||
/// Destroys all system components.
|
/// Destroys all system components.
|
||||||
void Shutdown(bool save_resume_state);
|
void Shutdown(bool save_resume_state);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user