mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-09-27 17:31:35 -04:00
Allow RZD* and GZ2 save file interoperatibility (#2529)
* Allow RZD* and GZ2 save file interoperatibility Tested loading a wii save from Dusklight on a GC disk in dusklight, and a GC save from dusklight on a wii disk in dusklight. Saves from an actual wii are in .dat form and equivalent to the payload of a .gci, but with no headers. No support for those yet. * code styling
This commit is contained in:
@@ -905,18 +905,21 @@ ValueResult<GciHeader> parse_gci(const std::vector<uint8_t>& bytes) {
|
||||
|
||||
DiscCompatibility disc_compatibility(const GciHeader& header, const SaveIdentity& identity) {
|
||||
if (header.game.size() != 4 || identity.game.size() != 4 || header.maker.size() != 2 ||
|
||||
header.maker != identity.maker)
|
||||
{
|
||||
header.maker != identity.maker) {
|
||||
return DiscCompatibility::Incompatible;
|
||||
}
|
||||
if (header.game == identity.game) {
|
||||
return DiscCompatibility::Exact;
|
||||
}
|
||||
if (std::string_view{header.game}.substr(0, 3) == std::string_view{identity.game}.substr(0, 3))
|
||||
{
|
||||
if (std::string_view{header.game}.substr(0, 3) == std::string_view{identity.game}.substr(0, 3)) {
|
||||
return DiscCompatibility::RegionChange;
|
||||
}
|
||||
return DiscCompatibility::Incompatible;
|
||||
if ((std::string_view{header.game}.substr(0, 3) == "RZD" &&
|
||||
std::string_view{identity.game}.substr(0, 3) == "GZ2") ||
|
||||
std::string_view{header.game}.substr(0, 3) == "GZ2" &&
|
||||
std::string_view{identity.game}.substr(0, 3) == "RZD") {
|
||||
return DiscCompatibility::PlatformChange;
|
||||
}
|
||||
}
|
||||
|
||||
ValueResult<Artifact> read_artifact(std::string_view location) {
|
||||
|
||||
@@ -35,6 +35,7 @@ enum class ModDataAction {
|
||||
enum class DiscCompatibility {
|
||||
Exact,
|
||||
RegionChange,
|
||||
PlatformChange,
|
||||
Incompatible,
|
||||
};
|
||||
|
||||
|
||||
@@ -290,7 +290,8 @@ void confirm_import(Artifact artifact) {
|
||||
const auto compatibility =
|
||||
raw ? save_manager::DiscCompatibility::Exact :
|
||||
save_manager::disc_compatibility(artifact.header, context.value.identity);
|
||||
const bool changingRegion = compatibility == save_manager::DiscCompatibility::RegionChange;
|
||||
const bool changingVersion = (compatibility == save_manager::DiscCompatibility::RegionChange ||
|
||||
compatibility == save_manager::DiscCompatibility::PlatformChange);
|
||||
if (compatibility == save_manager::DiscCompatibility::Incompatible) {
|
||||
show_message("Import Failed", "This save does not match the configured disc.", true,
|
||||
&finish_import_flow);
|
||||
@@ -344,7 +345,7 @@ void confirm_import(Artifact artifact) {
|
||||
{
|
||||
{.label = "Cancel", .onPressed = cancel},
|
||||
{
|
||||
.label = changingRegion ? "Import Anyway" : "Import",
|
||||
.label = changingVersion ? "Import Anyway" : "Import",
|
||||
.onPressed =
|
||||
[items, keepModData, hasBundledModData](Modal& modal) {
|
||||
const auto action = hasBundledModData ? ModDataAction::Replace :
|
||||
@@ -354,7 +355,7 @@ void confirm_import(Artifact artifact) {
|
||||
},
|
||||
.isDisabled =
|
||||
[items] { return std::ranges::none_of(*items, &ImportItem::selected); },
|
||||
.icon = changingRegion ? "warning" : "",
|
||||
.icon = changingVersion ? "warning" : "",
|
||||
},
|
||||
},
|
||||
.onDismiss = cancel,
|
||||
@@ -374,9 +375,10 @@ void confirm_import(Artifact artifact) {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const auto* regionMessage = changingRegion ?
|
||||
" This save is from a different region than the "
|
||||
"configured disc and may not work correctly." :
|
||||
const auto* regionMessage = changingVersion ?
|
||||
" This save is from a different region or "
|
||||
"platform than the configured disc and may "
|
||||
"not work correctly." :
|
||||
"";
|
||||
modal->set_body(
|
||||
fmt::format("{} the <b>{}</b> save?{}{}", replacingSave ? "Replace" : "Import",
|
||||
|
||||
Reference in New Issue
Block a user