Module: Ips::Patcher
- Defined in:
- lib/ips/patcher.rb,
lib/ips/patcher/version.rb
Overview
IPS (International Patching System) patcher module for applying binary patches to ROM files.
Defined Under Namespace
Classes: Error
Constant Summary collapse
- VERSION =
Current version of the ips-patcher gem
"0.1.1"
Class Method Summary collapse
-
.apply(rom_path, patch_path, output: nil) ⇒ void
Applies an IPS patch file to a ROM file.
Class Method Details
.apply(rom_path, patch_path, output: nil) ⇒ void
Note:
The original ROM file is not modified; a new patched file is created
This method returns an undefined value.
Applies an IPS patch file to a ROM file.
This method reads both the ROM and patch files, validates the patch format, and applies all patch records to create a new patched ROM file. If no output path is specified, the output file is named with ".patched" inserted before the file extension.
The IPS format supports two types of records:
- Standard records: Replace bytes at a specific offset
- RLE records: Fill bytes with a repeated value (when size is 0)
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/ips/patcher.rb', line 51 def self.apply(rom_path, patch_path, output: nil) rom = File.binread(rom_path) patch = File.binread(patch_path) reader = Ips::BinaryReader.new(patch) writer = Ips::BinaryWriter.new(rom) header = reader.read_string(5) if header != 'PATCH' raise Error, "Invalid patch file" end loop do eof = reader.read_string(3) break if eof == 'EOF' reader.go_back(3) offset = reader.read_int24 size = reader.read_int16 if size == 0 rle_size = reader.read_int16 rle_value = reader.read_bytes(1) writer.set_bytes(offset, rle_value * rle_size) next end bytes = reader.read_bytes(size) writer.set_bytes(offset, bytes) end output_path = output unless output_path rom_dir = File.dirname(rom_path) filename = File.basename(rom_path, File.extname(rom_path)) extension = File.extname(rom_path) output_path = File.join(rom_dir, "#{filename}.patched#{extension}") end writer.save_to_file(output_path) end |