mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-05-12 15:49:39 -06:00
ui: Made rom loading errors more clear and user friendly (#2097)
This commit is contained in:
parent
b540725090
commit
921ea178b9
@ -465,26 +465,51 @@ object NativeLibrary {
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
emulationActivity = requireActivity() as EmulationActivity
|
||||
|
||||
val result = requireArguments().getInt(RESULT_CODE)
|
||||
var captionString = getString(R.string.loader_error_invalid_format)
|
||||
if (result == CoreError.ErrorLoader_ErrorEncrypted.value) {
|
||||
captionString = getString(R.string.loader_error_encrypted)
|
||||
}
|
||||
if (result == CoreError.ErrorArticDisconnected.value) {
|
||||
captionString = getString(R.string.artic_base)
|
||||
var coreError = CoreError.fromInt(requireArguments().getInt(RESULT_CODE))
|
||||
val title: String
|
||||
val message: String
|
||||
when (coreError) {
|
||||
CoreError.ErrorGetLoader, CoreError.ErrorLoader_ErrorInvalidFormat, CoreError.ErrorSystemMode -> {
|
||||
title = getString(R.string.loader_error_invalid_format)
|
||||
message = getString(R.string.loader_error_invalid_format_description)
|
||||
}
|
||||
|
||||
CoreError.ErrorLoader_ErrorEncrypted -> {
|
||||
title = getString(R.string.loader_error_encrypted)
|
||||
message = getString(R.string.loader_error_encrypted_description)
|
||||
}
|
||||
|
||||
CoreError.ErrorArticDisconnected -> {
|
||||
title = getString(R.string.artic_base)
|
||||
message = getString(R.string.artic_server_comm_error)
|
||||
}
|
||||
|
||||
CoreError.ErrorN3DSApplication -> {
|
||||
title = getString(R.string.loader_error_invalid_system_mode)
|
||||
message = getString(R.string.loader_error_invalid_system_mode_description)
|
||||
}
|
||||
|
||||
CoreError.ErrorLoader_ErrorPatches -> {
|
||||
title = getString(R.string.loader_error_applying_patches)
|
||||
message = getString(R.string.loader_error_applying_patches_description)
|
||||
}
|
||||
|
||||
CoreError.ErrorLoader_ErrorPatchesInvalidTitle -> {
|
||||
title = getString(R.string.loader_error_applying_patches)
|
||||
message = getString(R.string.loader_error_patch_wrong_application)
|
||||
}
|
||||
|
||||
else -> {
|
||||
title = getString(R.string.loader_error_generic_title)
|
||||
message = getString(R.string.loader_error_generic,
|
||||
getString(coreError.stringRes), coreError.value)
|
||||
}
|
||||
}
|
||||
|
||||
val alert = MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(captionString)
|
||||
.setTitle(title)
|
||||
.setMessage(
|
||||
Html.fromHtml(
|
||||
if (result == CoreError.ErrorArticDisconnected.value)
|
||||
getString(R.string.artic_server_comm_error)
|
||||
else if (result == CoreError.ErrorLoader_ErrorEncrypted.value)
|
||||
getString(R.string.loader_error_encrypted_desc)
|
||||
else
|
||||
getString(R.string.loader_error_generic,
|
||||
getString(CoreError.fromInt(result).stringRes), result),
|
||||
Html.fromHtml(message,
|
||||
Html.FROM_HTML_MODE_LEGACY
|
||||
)
|
||||
)
|
||||
@ -861,14 +886,16 @@ object NativeLibrary {
|
||||
ErrorLoader_ErrorEncrypted(5, R.string.core_error_loader_encrypted),
|
||||
ErrorLoader_ErrorInvalidFormat(6, R.string.core_error_loader_invalid_format),
|
||||
ErrorLoader_ErrorGBATitle(7, R.string.core_error_loader_gba_title),
|
||||
ErrorSystemFiles(8, R.string.core_error_system_files),
|
||||
ErrorSavestate(9, R.string.core_error_savestate),
|
||||
ErrorArticDisconnected(10, R.string.core_error_artic_disconnected),
|
||||
ErrorN3DSApplication(11, R.string.core_error_n3ds_application),
|
||||
ErrorCoreExceptionRaised(12, R.string.core_error_core_exception_raised),
|
||||
ErrorMemoryExceptionRaised(13, R.string.core_error_memory_exception_raised),
|
||||
ShutdownRequested(14, R.string.core_error_shutdown_requested),
|
||||
ErrorUnknown(15, R.string.core_error_unknown);
|
||||
ErrorLoader_ErrorPatches(8, R.string.core_error_loader_error_patches),
|
||||
ErrorLoader_ErrorPatchesInvalidTitle(9, R.string.core_error_loader_patches_invalid_title),
|
||||
ErrorSystemFiles(10, R.string.core_error_system_files),
|
||||
ErrorSavestate(11, R.string.core_error_savestate),
|
||||
ErrorArticDisconnected(12, R.string.core_error_artic_disconnected),
|
||||
ErrorN3DSApplication(13, R.string.core_error_n3ds_application),
|
||||
ErrorCoreExceptionRaised(14, R.string.core_error_core_exception_raised),
|
||||
ErrorMemoryExceptionRaised(15, R.string.core_error_memory_exception_raised),
|
||||
ShutdownRequested(16, R.string.core_error_shutdown_requested),
|
||||
ErrorUnknown(17, R.string.core_error_unknown);
|
||||
|
||||
companion object {
|
||||
fun fromInt(value: Int): CoreError {
|
||||
|
||||
@ -435,11 +435,19 @@
|
||||
<string name="preferences_layout">Layout</string>
|
||||
|
||||
<!-- ROM loading errors -->
|
||||
<string name="loader_error_generic_title">Error loading application</string>
|
||||
<string name="loader_error_invalid_format">Invalid application format</string>
|
||||
<string name="loader_error_invalid_format_description"><![CDATA[The application file format not supported.<br>Please make sure you are using one of the compatible file formats:<ul><li>Cartridge images: <b>.cci/.zcci/.3ds</b></li><li>Installable archives: <b>.cia/.zcia</b></li><li>Homebrew titles: <b>.3dsx/.z3dsx</b></li><li>NCCH containers: <b>.cxi/.zcxi/.app</b></li><li>ELF files: <b>.elf/.axf</b></li></ul>]]></string>
|
||||
<string name="loader_error_invalid_system_mode">Invalid system mode</string>
|
||||
<string name="loader_error_invalid_system_mode_description">New 3DS exclusive applications cannot be loaded without enabling the New 3DS mode.</string>
|
||||
<string name="loader_error_applying_patches">Error applying patches</string>
|
||||
<string name="loader_error_applying_patches_description">A generic error occurred while applying a patch to the application. Please check the log for more details.</string>
|
||||
<string name="loader_error_patch_wrong_application">Failed to apply a patch because it is designed for a different application. Please make sure you are using the patches for the right application, region and version.</string>
|
||||
<string name="loader_error_encrypted">Your ROM is Encrypted</string>
|
||||
<string name="loader_error_encrypted_desc"><![CDATA[Azahar does not support encrypted ROMS. Read our <a href="https://azahar-emu.org/blog/game-loading-changes/">blog post</a> for more information.]]></string>
|
||||
<string name="loader_error_invalid_format">Invalid ROM format</string>
|
||||
<string name="loader_error_encrypted_description"><![CDATA[Azahar does not support encrypted applications. Read our <a href="https://azahar-emu.org/blog/game-loading-changes/">blog post</a> for more information.]]></string>
|
||||
<string name="loader_error_file_not_found">ROM file does not exist</string>
|
||||
<string name="no_game_present">No bootable game present!</string>
|
||||
|
||||
<string name="loader_error_generic">An error occurred while loading ROM: \"%s (%d)\"</string>
|
||||
<string name="core_error_success">Success</string>
|
||||
<string name="core_error_not_initialized">Not initialized</string>
|
||||
@ -449,6 +457,8 @@
|
||||
<string name="core_error_loader_encrypted">Encrypted file</string>
|
||||
<string name="core_error_loader_invalid_format">Corrupted file</string>
|
||||
<string name="core_error_loader_gba_title">File is GBA title</string>
|
||||
<string name="core_error_loader_error_patches">Error applying patches</string>
|
||||
<string name="core_error_loader_patches_invalid_title">Patches are for a different application</string>
|
||||
<string name="core_error_system_files">Missing system files</string>
|
||||
<string name="core_error_savestate">Savestate failed</string>
|
||||
<string name="core_error_artic_disconnected">Artic Base disconnected</string>
|
||||
|
||||
@ -1366,61 +1366,39 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
||||
system.Load(*render_window, filename.toStdString(), secondary_window)};
|
||||
|
||||
if (result != Core::System::ResultStatus::Success) {
|
||||
QString invalid_format = tr("Invalid application format");
|
||||
QString invalid_format_description =
|
||||
tr("The application file format not supported.<br>Please make sure you are using one "
|
||||
"of the compatible file formats:<ul><li>Cartridge images: "
|
||||
"<b>.cci/.zcci/.3ds</b></li><li>Installable archives: "
|
||||
"<b>.cia/.zcia</b></li><li>Homebrew titles: <b>.3dsx/.z3dsx</b></li><li>NCCH "
|
||||
"containers: <b>.cxi/.zcxi/.app</b></li><li>ELF files: <b>.elf/.axf</b></li></ul>");
|
||||
|
||||
switch (result) {
|
||||
case Core::System::ResultStatus::ErrorGetLoader:
|
||||
LOG_CRITICAL(Frontend, "Failed to obtain loader for {}", filename.toStdString());
|
||||
QMessageBox::critical(
|
||||
this, tr("Invalid App Format"),
|
||||
tr("Your app format is not supported.<br/>Please follow the guides to redump your "
|
||||
"<a "
|
||||
"href='https://web.archive.org/web/20240304210021/https://citra-emu.org/wiki/"
|
||||
"dumping-game-cartridges/'>game "
|
||||
"cartridges</a> or "
|
||||
"<a "
|
||||
"href='https://web.archive.org/web/20240304210011/https://citra-emu.org/wiki/"
|
||||
"dumping-installed-titles/'>installed "
|
||||
"titles</a>."));
|
||||
QMessageBox::critical(this, invalid_format, invalid_format_description);
|
||||
break;
|
||||
|
||||
case Core::System::ResultStatus::ErrorSystemMode:
|
||||
LOG_CRITICAL(Frontend, "Failed to load App!");
|
||||
QMessageBox::critical(
|
||||
this, tr("App Corrupted"),
|
||||
tr("Your app is corrupted. <br/>Please follow the guides to redump your "
|
||||
"<a "
|
||||
"href='https://web.archive.org/web/20240304210021/https://citra-emu.org/wiki/"
|
||||
"dumping-game-cartridges/'>game "
|
||||
"cartridges</a> or "
|
||||
"<a "
|
||||
"href='https://web.archive.org/web/20240304210011/https://citra-emu.org/wiki/"
|
||||
"dumping-installed-titles/'>installed "
|
||||
"titles</a>."));
|
||||
LOG_CRITICAL(Frontend, "Failed to load application!");
|
||||
QMessageBox::critical(this, invalid_format, invalid_format_description);
|
||||
break;
|
||||
|
||||
case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: {
|
||||
QMessageBox::critical(this, tr("App Encrypted"),
|
||||
tr("Your app is encrypted. <br/>"
|
||||
QMessageBox::critical(this, tr("Encrypted application"),
|
||||
tr("Encrypted applications are not supported.<br/>"
|
||||
"<a "
|
||||
"href='https://azahar-emu.org/blog/game-loading-changes/'>"
|
||||
"Please check our blog for more info.</a>"));
|
||||
break;
|
||||
}
|
||||
case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat:
|
||||
QMessageBox::critical(
|
||||
this, tr("Invalid App Format"),
|
||||
tr("Your app format is not supported.<br/>Please follow the guides to redump your "
|
||||
"<a "
|
||||
"href='https://web.archive.org/web/20240304210021/https://citra-emu.org/wiki/"
|
||||
"dumping-game-cartridges/'>game "
|
||||
"cartridges</a> or "
|
||||
"<a "
|
||||
"href='https://web.archive.org/web/20240304210011/https://citra-emu.org/wiki/"
|
||||
"dumping-installed-titles/'>installed "
|
||||
"titles</a>."));
|
||||
QMessageBox::critical(this, invalid_format, invalid_format_description);
|
||||
break;
|
||||
|
||||
case Core::System::ResultStatus::ErrorLoader_ErrorGbaTitle:
|
||||
QMessageBox::critical(this, tr("Unsupported App"),
|
||||
QMessageBox::critical(this, tr("Unsupported application"),
|
||||
tr("GBA Virtual Console is not supported by Azahar."));
|
||||
break;
|
||||
|
||||
@ -1437,10 +1415,27 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
||||
tr("New 3DS exclusive applications cannot be loaded without "
|
||||
"enabling the New 3DS mode."));
|
||||
break;
|
||||
case Core::System::ResultStatus::ErrorLoader:
|
||||
QMessageBox::critical(this, tr("Generic load error"),
|
||||
tr("An generic load error occurred while loading the "
|
||||
"application.<br/>Please check the log for more details."));
|
||||
break;
|
||||
case Core::System::ResultStatus::ErrorLoader_ErrorPatches:
|
||||
QMessageBox::critical(this, tr("Error applying patches"),
|
||||
tr("A generic error occurred while applying a patch to the "
|
||||
"application.<br/>Please check the log for more details."));
|
||||
break;
|
||||
case Core::System::ResultStatus::ErrorLoader_ErrorPatchesInvalidTitle:
|
||||
QMessageBox::critical(
|
||||
this, tr("Error applying patches"),
|
||||
tr("Failed to apply a patch because it is designed for a different "
|
||||
"application.<br/>Please make sure you are using the patches for "
|
||||
"the right application, region and version."));
|
||||
break;
|
||||
default:
|
||||
QMessageBox::critical(
|
||||
this, tr("Error while loading App!"),
|
||||
tr("An unknown error occurred. Please see the log for more details."));
|
||||
this, tr("Error while loading application"),
|
||||
tr("An unknown error occurred.<br/>Please see the log for more details."));
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@ -1499,7 +1494,8 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||
auto loader = Loader::GetLoader(path);
|
||||
|
||||
u64 title_id{0};
|
||||
Loader::ResultStatus res = loader->ReadProgramId(title_id);
|
||||
Loader::ResultStatus res =
|
||||
loader ? loader->ReadProgramId(title_id) : Loader::ResultStatus::Error;
|
||||
|
||||
if (Loader::ResultStatus::Success == res) {
|
||||
// Load per game settings
|
||||
@ -1512,7 +1508,7 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||
|
||||
// Artic Server cannot accept a client multiple times, so multiple loaders are not
|
||||
// possible. Instead register the app loader early and do not create it again on system load.
|
||||
if (!loader->SupportsMultipleInstancesForSameFile()) {
|
||||
if (loader && !loader->SupportsMultipleInstancesForSameFile()) {
|
||||
system.RegisterAppLoaderEarly(loader);
|
||||
}
|
||||
|
||||
|
||||
@ -434,6 +434,10 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
|
||||
return ResultStatus::ErrorLoader_ErrorInvalidFormat;
|
||||
case Loader::ResultStatus::ErrorGbaTitle:
|
||||
return ResultStatus::ErrorLoader_ErrorGbaTitle;
|
||||
case Loader::ResultStatus::ErrorPatches:
|
||||
return ResultStatus::ErrorLoader_ErrorPatches;
|
||||
case Loader::ResultStatus::ErrorPatchesInvalidTitle:
|
||||
return ResultStatus::ErrorLoader_ErrorPatchesInvalidTitle;
|
||||
case Loader::ResultStatus::ErrorArtic:
|
||||
return ResultStatus::ErrorArticDisconnected;
|
||||
default:
|
||||
|
||||
@ -99,11 +99,13 @@ public:
|
||||
/// invalid format
|
||||
ErrorLoader_ErrorGbaTitle, ///< Error loading the specified application as it is GBA Virtual
|
||||
///< Console
|
||||
ErrorSystemFiles, ///< Error in finding system files
|
||||
ErrorSavestate, ///< Error saving or loading
|
||||
ErrorArticDisconnected, ///< Error when artic base disconnects
|
||||
ErrorN3DSApplication, ///< Error launching New 3DS application in Old 3DS mode
|
||||
ErrorCoreExceptionRaised, ///< The CPU emulation raised an exception
|
||||
ErrorLoader_ErrorPatches, ///< Generic error while loading patches for an application
|
||||
ErrorLoader_ErrorPatchesInvalidTitle, ///< A patch was loaded for the incorrect application
|
||||
ErrorSystemFiles, ///< Error in finding system files
|
||||
ErrorSavestate, ///< Error saving or loading
|
||||
ErrorArticDisconnected, ///< Error when artic base disconnects
|
||||
ErrorN3DSApplication, ///< Error launching New 3DS application in Old 3DS mode
|
||||
ErrorCoreExceptionRaised, ///< The CPU emulation raised an exception
|
||||
ErrorMemoryExceptionRaised, ///< Unmmaped memory was accessed
|
||||
ShutdownRequested, ///< Emulated program requested a system shutdown
|
||||
ErrorUnknown ///< Any other error
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@ -247,14 +247,14 @@ void LayeredFS::LoadExtRelocations() {
|
||||
std::vector<u8> buffer(file.relocation.size); // Original size
|
||||
romfs->ReadFile(file.relocation.original_offset, buffer.size(), buffer.data());
|
||||
|
||||
bool ret = false;
|
||||
Loader::ResultStatus ret{};
|
||||
if (extension == ".ips") {
|
||||
ret = Patch::ApplyIpsPatch(patch, buffer);
|
||||
} else {
|
||||
ret = Patch::ApplyBpsPatch(patch, buffer);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
if (ret == Loader::ResultStatus::Success) {
|
||||
LOG_INFO(Service_FS, "LayeredFS patched file {}", file_path);
|
||||
|
||||
file.relocation.type = 2;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
||||
@ -518,7 +518,7 @@ Loader::ResultStatus NCCHContainer::LoadSectionExeFS(const char* name, std::vect
|
||||
Loader::ResultStatus NCCHContainer::ApplyCodePatch(std::vector<u8>& code) const {
|
||||
struct PatchLocation {
|
||||
std::string path;
|
||||
bool (*patch_fn)(const std::vector<u8>& patch, std::vector<u8>& code);
|
||||
Loader::ResultStatus (*patch_fn)(const std::vector<u8>& patch, std::vector<u8>& code);
|
||||
};
|
||||
|
||||
const auto mods_path =
|
||||
@ -555,11 +555,12 @@ Loader::ResultStatus NCCHContainer::ApplyCodePatch(std::vector<u8>& code) const
|
||||
|
||||
std::vector<u8> patch(patch_file.GetSize());
|
||||
if (patch_file.ReadBytes(patch.data(), patch.size()) != patch.size())
|
||||
return Loader::ResultStatus::Error;
|
||||
return Loader::ResultStatus::ErrorPatches;
|
||||
|
||||
LOG_INFO(Service_FS, "File {} patching code.bin", info.path);
|
||||
if (!info.patch_fn(patch, code))
|
||||
return Loader::ResultStatus::Error;
|
||||
auto patch_result = info.patch_fn(patch, code);
|
||||
if (patch_result != Loader::ResultStatus::Success)
|
||||
return patch_result;
|
||||
|
||||
return Loader::ResultStatus::Success;
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@ -14,21 +14,21 @@
|
||||
|
||||
namespace FileSys::Patch {
|
||||
|
||||
bool ApplyIpsPatch(const std::vector<u8>& ips, std::vector<u8>& buffer) {
|
||||
Loader::ResultStatus ApplyIpsPatch(const std::vector<u8>& ips, std::vector<u8>& buffer) {
|
||||
std::size_t cursor = 5;
|
||||
std::size_t patch_length = ips.size() - 3;
|
||||
std::string ips_header(ips.begin(), ips.begin() + 5);
|
||||
|
||||
if (ips_header != "PATCH") {
|
||||
LOG_INFO(Service_FS, "Attempted to load invalid IPS");
|
||||
return false;
|
||||
return Loader::ResultStatus::ErrorPatches;
|
||||
}
|
||||
|
||||
while (cursor < patch_length) {
|
||||
std::string eof_check(ips.begin() + cursor, ips.begin() + cursor + 3);
|
||||
|
||||
if (eof_check == "EOF")
|
||||
return false;
|
||||
break;
|
||||
|
||||
std::size_t offset = ips[cursor] << 16 | ips[cursor + 1] << 8 | ips[cursor + 2];
|
||||
std::size_t length = ips[cursor + 3] << 8 | ips[cursor + 4];
|
||||
@ -38,7 +38,7 @@ bool ApplyIpsPatch(const std::vector<u8>& ips, std::vector<u8>& buffer) {
|
||||
length = ips[cursor + 5] << 8 | ips[cursor + 6];
|
||||
|
||||
if (buffer.size() < offset + length)
|
||||
return false;
|
||||
return Loader::ResultStatus::ErrorPatches;
|
||||
|
||||
for (u32 i = 0; i < length; ++i)
|
||||
buffer[offset + i] = ips[cursor + 7];
|
||||
@ -49,12 +49,12 @@ bool ApplyIpsPatch(const std::vector<u8>& ips, std::vector<u8>& buffer) {
|
||||
}
|
||||
|
||||
if (buffer.size() < offset + length)
|
||||
return false;
|
||||
return Loader::ResultStatus::ErrorPatches;
|
||||
|
||||
std::memcpy(&buffer[offset], &ips[cursor + 5], length);
|
||||
cursor += length + 5;
|
||||
}
|
||||
return true;
|
||||
return Loader::ResultStatus::Success;
|
||||
}
|
||||
|
||||
namespace Bps {
|
||||
@ -149,11 +149,11 @@ public:
|
||||
PatchApplier(Stream<const u8> source, Stream<u8> target, Stream<const u8> patch)
|
||||
: m_source{source}, m_target{target}, m_patch{patch} {}
|
||||
|
||||
bool Apply() {
|
||||
Loader::ResultStatus Apply() {
|
||||
const auto magic = *m_patch.Read<std::array<char, MagicSize>>();
|
||||
if (std::string_view(magic.data(), magic.size()) != "BPS1") {
|
||||
LOG_ERROR(Service_FS, "Invalid BPS magic");
|
||||
return false;
|
||||
return Loader::ResultStatus::ErrorPatches;
|
||||
}
|
||||
|
||||
const Bps::Number source_size = m_patch.ReadNumber();
|
||||
@ -161,7 +161,7 @@ public:
|
||||
const Bps::Number metadata_size = m_patch.ReadNumber();
|
||||
if (source_size > m_source.size() || target_size > m_target.size() || metadata_size != 0) {
|
||||
LOG_ERROR(Service_FS, "Invalid sizes");
|
||||
return false;
|
||||
return Loader::ResultStatus::ErrorPatches;
|
||||
}
|
||||
|
||||
const std::size_t command_start_offset = m_patch.Tell();
|
||||
@ -173,22 +173,22 @@ public:
|
||||
|
||||
if (crc32(m_source.data(), source_size) != source_crc32) {
|
||||
LOG_ERROR(Service_FS, "Unexpected source hash");
|
||||
return false;
|
||||
return Loader::ResultStatus::ErrorPatchesInvalidTitle;
|
||||
}
|
||||
|
||||
// Process all patch commands.
|
||||
std::memset(m_target.data(), 0, m_target.size());
|
||||
while (m_patch.Tell() < command_end_offset) {
|
||||
if (!HandleCommand())
|
||||
return false;
|
||||
return Loader::ResultStatus::ErrorPatches;
|
||||
}
|
||||
|
||||
if (crc32(m_target.data(), target_size) != target_crc32) {
|
||||
LOG_ERROR(Service_FS, "Unexpected target hash");
|
||||
return false;
|
||||
return Loader::ResultStatus::ErrorPatches;
|
||||
}
|
||||
|
||||
return true;
|
||||
return Loader::ResultStatus::Success;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -257,7 +257,7 @@ private:
|
||||
|
||||
} // namespace Bps
|
||||
|
||||
bool ApplyBpsPatch(const std::vector<u8>& patch, std::vector<u8>& buffer) {
|
||||
Loader::ResultStatus ApplyBpsPatch(const std::vector<u8>& patch, std::vector<u8>& buffer) {
|
||||
Bps::Stream patch_stream{patch.data(), patch.size()};
|
||||
|
||||
// Move the offset past the file format marker (i.e. "BPS1")
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@ -7,11 +7,12 @@
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/loader/loader.h"
|
||||
|
||||
namespace FileSys::Patch {
|
||||
|
||||
bool ApplyIpsPatch(const std::vector<u8>& patch, std::vector<u8>& buffer);
|
||||
Loader::ResultStatus ApplyIpsPatch(const std::vector<u8>& patch, std::vector<u8>& buffer);
|
||||
|
||||
bool ApplyBpsPatch(const std::vector<u8>& patch, std::vector<u8>& buffer);
|
||||
Loader::ResultStatus ApplyBpsPatch(const std::vector<u8>& patch, std::vector<u8>& buffer);
|
||||
|
||||
} // namespace FileSys::Patch
|
||||
|
||||
@ -76,6 +76,8 @@ enum class ResultStatus {
|
||||
ErrorGbaTitle,
|
||||
ErrorArtic,
|
||||
ErrorNotFound,
|
||||
ErrorPatches,
|
||||
ErrorPatchesInvalidTitle,
|
||||
};
|
||||
|
||||
constexpr u32 MakeMagic(char a, char b, char c, char d) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user