summaryrefslogtreecommitdiff
path: root/ips-patcher.lua
diff options
context:
space:
mode:
Diffstat (limited to 'ips-patcher.lua')
-rw-r--r--ips-patcher.lua48
1 files changed, 48 insertions, 0 deletions
diff --git a/ips-patcher.lua b/ips-patcher.lua
new file mode 100644
index 0000000..316f8da
--- /dev/null
+++ b/ips-patcher.lua
@@ -0,0 +1,48 @@
+-- based on http://zerosoft.zophar.net/ips.php (note the data is big endian - this isn't clear from the text)
+
+local function read_some_bytes(fin, siz)
+ local ret = 0
+
+ for _ = 1, siz do
+ ret = ret * 256 + fin:readU8()
+ end
+
+ return ret
+end
+
+function ips_patch(buffer, ips)
+ local header, offset, size, b = "", 0, 0
+
+ for _ = 1, 5 do
+ header = header .. string.char(ips:readU8())
+ end
+
+ if header ~= "PATCH" then error "Wrong IPS file format - bad header" end
+
+ while true do
+ offset = read_some_bytes(ips, 3)
+
+ -- that's one of the most stupid thing ever... you can NOT patch the offset
+ -- 0x454F46 since this is the end of the ips file marker... whomever came
+ -- with this brillant design needs a smack in the face.
+ if offset == 0x454F46 then
+ break
+ end
+
+ buffer:seek(offset)
+ if buffer.wseek then buffer:wseek(offset) end
+
+ size = read_some_bytes(ips, 2)
+
+ if size == 0 then
+ size = read_some_bytes(ips, 2)
+ b = ips:readU8()
+ for _ = 1, size do buffer:writeU8(b) end
+ else
+ ips:copyto(buffer, size)
+ end
+ end
+
+ buffer:seek(0)
+ if buffer.wseek then buffer:wseek(0) end
+end