23 if (target_version < 2 || target_version > 3) {
24 return absl::InvalidArgumentError(absl::StrFormat(
25 "Invalid target version: %d. Must be 2 or 3.", target_version));
29 return absl::FailedPreconditionError(
30 "This custom ZScream layout cannot be replaced with the bundled "
31 "ZSCustomOverworld ASM");
36 if (current_version != 0xFF && current_version >= target_version) {
37 return absl::AlreadyExistsError(absl::StrFormat(
38 "ROM is already version %d or higher", current_version));
42 "Applying ZSCustomOverworld ASM v%d to ROM...", target_version);
45 auto asar_wrapper = std::make_unique<core::AsarWrapper>();
49 std::vector<uint8_t> original_rom_data =
rom_.
vector();
50 std::vector<uint8_t> working_rom_data = original_rom_data;
54 std::string asm_file_name =
55 (target_version == 3) ?
"asm/yaze.asm" :
"asm/ZSCustomOverworld.asm";
59 LOG_DEBUG(
"OverworldUpgradeSystem",
"Using ASM file: %s",
60 asm_file_path.c_str());
62 if (!std::filesystem::exists(asm_file_path)) {
63 return absl::NotFoundError(
64 absl::StrFormat(
"ASM file not found at: %s\n\n"
65 "Expected location: assets/%s\n"
66 "Make sure the assets directory is accessible.",
67 asm_file_path, asm_file_name));
72 asar_wrapper->ApplyPatch(asm_file_path, working_rom_data);
73 if (!patch_result.ok()) {
74 return absl::InternalError(absl::StrFormat(
75 "Failed to apply ASM patch: %s", patch_result.status().message()));
78 const auto& result = patch_result.value();
79 if (!result.success) {
80 std::string error_details =
"ASM patch failed with errors:\n";
81 for (
const auto& error : result.errors) {
82 error_details +=
" - " + error +
"\n";
84 if (!result.warnings.empty()) {
85 error_details +=
"Warnings:\n";
86 for (
const auto& warning : result.warnings) {
87 error_details +=
" - " + warning +
"\n";
90 return absl::InternalError(error_details);
101 "ASM patch applied successfully. Found %zu symbols:",
102 result.symbols.size());
103 for (
const auto& symbol : result.symbols) {
104 LOG_DEBUG(
"OverworldUpgradeSystem",
" %s @ $%06X", symbol.name.c_str(),
109 "ZSCustomOverworld v%d successfully applied to ROM",
111 return absl::OkStatus();
113 }
catch (
const std::exception& e) {
116 if (!restore_result.ok()) {
117 LOG_ERROR(
"OverworldUpgradeSystem",
"Failed to restore ROM data: %s",
118 restore_result.message().data());
120 return absl::InternalError(
121 absl::StrFormat(
"Exception during ASM application: %s", e.what()));
126 int target_version) {
131 if (target_version >= 2) {
135 "Enabled v2+ features: Custom BG colors, Main palettes");
138 if (target_version >= 3) {
145 "Enabled v3+ features: Subscreen overlays, Animated GFX, Tile "
146 "GFX groups, Mosaic");
148 for (
int i = 0; i < 0xA0; i++) {
153 const std::vector<int> large_areas = {
154 0x00, 0x02, 0x05, 0x07, 0x0A, 0x0B, 0x0F, 0x10, 0x11, 0x12, 0x13,
155 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1D, 0x1E, 0x25,
156 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x30, 0x32, 0x33, 0x34,
157 0x35, 0x37, 0x3A, 0x40, 0x42, 0x45, 0x47, 0x4A, 0x4B, 0x4F, 0x50,
158 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
159 0x5D, 0x5E, 0x65, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6E, 0x6F, 0x70,
160 0x72, 0x73, 0x74, 0x75, 0x77, 0x7A, 0x80, 0x81};
161 for (
int area : large_areas) {
167 return absl::OkStatus();