109 lines
3.4 KiB
C++
109 lines
3.4 KiB
C++
#include <filesystem>
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
#include "app/rom.h"
|
|
#include "app/zelda3/overworld/overworld.h"
|
|
#include "app/zelda3/overworld/overworld_map.h"
|
|
|
|
using namespace yaze::zelda3;
|
|
using namespace yaze;
|
|
|
|
class ROMPatchUtility {
|
|
public:
|
|
static absl::Status CreateV3PatchedROM(const std::string& input_rom_path,
|
|
const std::string& output_rom_path) {
|
|
// Load the vanilla ROM
|
|
Rom rom;
|
|
RETURN_IF_ERROR(rom.LoadFromFile(input_rom_path));
|
|
|
|
// Apply ZSCustomOverworld v3 settings
|
|
RETURN_IF_ERROR(ApplyV3Patch(rom));
|
|
|
|
// Save the patched ROM
|
|
return rom.SaveToFile(Rom::SaveSettings{.filename = output_rom_path});
|
|
}
|
|
|
|
private:
|
|
static absl::Status ApplyV3Patch(Rom& rom) {
|
|
// Set ASM version to v3
|
|
rom.WriteByte(OverworldCustomASMHasBeenApplied, 0x03);
|
|
|
|
// Enable v3 features
|
|
rom.WriteByte(OverworldCustomAreaSpecificBGEnabled, 0x01);
|
|
rom.WriteByte(OverworldCustomSubscreenOverlayEnabled, 0x01);
|
|
rom.WriteByte(OverworldCustomAnimatedGFXEnabled, 0x01);
|
|
rom.WriteByte(OverworldCustomTileGFXGroupEnabled, 0x01);
|
|
rom.WriteByte(OverworldCustomMosaicEnabled, 0x01);
|
|
rom.WriteByte(OverworldCustomMainPaletteEnabled, 0x01);
|
|
|
|
// Apply v3 settings to first 10 maps for testing
|
|
for (int i = 0; i < 10; i++) {
|
|
// Set area sizes (mix of different sizes)
|
|
AreaSizeEnum area_size = static_cast<AreaSizeEnum>(i % 4);
|
|
rom.WriteByte(kOverworldScreenSize + i, static_cast<uint8_t>(area_size));
|
|
|
|
// Set main palettes
|
|
rom.WriteByte(OverworldCustomMainPaletteArray + i, i % 8);
|
|
|
|
// Set area-specific background colors
|
|
uint16_t bg_color = 0x0000 + (i * 0x1000);
|
|
rom.WriteByte(OverworldCustomAreaSpecificBGPalette + (i * 2),
|
|
bg_color & 0xFF);
|
|
rom.WriteByte(OverworldCustomAreaSpecificBGPalette + (i * 2) + 1,
|
|
(bg_color >> 8) & 0xFF);
|
|
|
|
// Set subscreen overlays
|
|
uint16_t overlay = 0x0090 + i;
|
|
rom.WriteByte(OverworldCustomSubscreenOverlayArray + (i * 2),
|
|
overlay & 0xFF);
|
|
rom.WriteByte(OverworldCustomSubscreenOverlayArray + (i * 2) + 1,
|
|
(overlay >> 8) & 0xFF);
|
|
|
|
// Set animated GFX
|
|
rom.WriteByte(OverworldCustomAnimatedGFXArray + i, 0x50 + i);
|
|
|
|
// Set custom tile GFX groups (8 bytes per map)
|
|
for (int j = 0; j < 8; j++) {
|
|
rom.WriteByte(OverworldCustomTileGFXGroupArray + (i * 8) + j,
|
|
0x20 + j + i);
|
|
}
|
|
|
|
// Set mosaic settings
|
|
rom.WriteByte(OverworldCustomMosaicArray + i, i % 16);
|
|
|
|
// Set expanded message IDs
|
|
uint16_t message_id = 0x1000 + i;
|
|
rom.WriteByte(kOverworldMessagesExpanded + (i * 2), message_id & 0xFF);
|
|
rom.WriteByte(kOverworldMessagesExpanded + (i * 2) + 1,
|
|
(message_id >> 8) & 0xFF);
|
|
}
|
|
|
|
return absl::OkStatus();
|
|
}
|
|
};
|
|
|
|
int main(int argc, char* argv[]) {
|
|
if (argc != 3) {
|
|
std::cerr << "Usage: " << argv[0] << " <input_rom> <output_rom>"
|
|
<< std::endl;
|
|
return 1;
|
|
}
|
|
|
|
std::string input_rom = argv[1];
|
|
std::string output_rom = argv[2];
|
|
|
|
auto status = ROMPatchUtility::CreateV3PatchedROM(input_rom, output_rom);
|
|
if (!status.ok()) {
|
|
std::cerr << "Failed to create patched ROM: " << status.message()
|
|
<< std::endl;
|
|
return 1;
|
|
}
|
|
|
|
std::cout << "Successfully created v3 patched ROM: " << output_rom
|
|
<< std::endl;
|
|
return 0;
|
|
}
|