From 9c2ad0c60bc565cfc9f7d675c76b1984ba66e738 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Thu, 14 Jan 2021 17:14:33 -0300 Subject: [PATCH] fixbaserom.py: Add support to v64 format and improve performance (#629) * Add byte swap for v64 files Signed-off-by: angie * Reduce `len` function calls Signed-off-by: angie * Optimze a bit the byte-swapped v64 format Signed-off-by: angie * Strip the overdump before doing the byte-swap The previous way wasted time by byte-swapping data that would be discarded anyway. Signed-off-by: angie * Swap twice the bytes per cycle to improve performance Signed-off-by: angie * Read and write 16 bytes at a time and specify explicit endianness Reading more bytes per cycle allow to speed up the swapping proccess Signed-off-by: angie * Add v64 compatibility in the Readme Signed-off-by: angie * Read whole file as little endian and write it as big endian without the loop Signed-off-by: angie --- README.md | 2 +- fixbaserom.py | 70 +++++++++++++++++++++++++++++---------------------- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 0430b5959e..755b2ee9a2 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ git clone https://github.com/zeldaret/oot.git #### 4. Prepare a base ROM Copy over your copy of the Master Quest (Debug) ROM inside the root of this new project directory. -Rename the file to "baserom_original.z64" or "baserom_original.n64", depending on the original extension. +Rename the file to "baserom_original.z64", "baserom_original.n64" or "baserom_original.v64", depending on the original extension. #### 5. Setup the ROM and build process diff --git a/fixbaserom.py b/fixbaserom.py index a2f2d1dbde..a9a21ab607 100644 --- a/fixbaserom.py +++ b/fixbaserom.py @@ -22,44 +22,54 @@ if path.exists("baserom_original.z64"): romFileName = "baserom_original.z64" elif path.exists("baserom_original.n64"): romFileName = "baserom_original.n64" +elif path.exists("baserom_original.v64"): + romFileName = "baserom_original.v64" +else: + print("Error: Could not find baserom_original.z64/baserom_original.n64/baserom_original.v64.") + sys.exit(1) # Read in the original ROM -if romFileName != "": - print("File '" + romFileName + "' found.") - with open(romFileName, mode="rb") as file: - fileContent = bytearray(file.read()) +print("File '" + romFileName + "' found.") +with open(romFileName, mode="rb") as file: + fileContent = bytearray(file.read()) - # Check if ROM needs to be byte swapped - if fileContent[0] == 0x40: - # Byte Swap ROM - # TODO: This is pretty slow at the moment. Look into optimizing it later... - print("ROM needs to be byte swapped...") - i = 0 - while i < len(fileContent): - tmp = struct.unpack_from("BBBB", fileContent, i) - struct.pack_into("BBBB", fileContent, i + 0, tmp[3], tmp[2], tmp[1], tmp[0]) - i += 4 - - perc = float(i) / float(len(fileContent)) - - if i % (1024 * 1024 * 4) == 0: - print(str(perc * 100) + "%") - - print("Byte swapping done.") -else: - print("Error: Could not find baserom_original.z64/baserom_original.n64.") - sys.exit(1) - # Strip the overdump print("Stripping overdump...") -strippedContent = list(fileContent[0:0x3600000]) +fileContent = fileContent[0:0x3600000] + +fileContentLen = len(fileContent) + +# Check if ROM needs to be byte/word swapped +# Little-endian +if fileContent[0] == 0x40: + # Word Swap ROM + print("ROM needs to be word swapped...") + words = str(int(fileContentLen/4)) + little_byte_format = "<" + words + "I" + big_byte_format = ">" + words + "I" + tmp = struct.unpack_from(little_byte_format, fileContent, 0) + struct.pack_into(big_byte_format, fileContent, 0, *tmp) + + print("Word swapping done.") + +# Byte-swapped +elif fileContent[0] == 0x37: + # Byte Swap ROM + print("ROM needs to be byte swapped...") + halfwords = str(int(fileContentLen/2)) + little_byte_format = "<" + halfwords + "H" + big_byte_format = ">" + halfwords + "H" + tmp = struct.unpack_from(little_byte_format, fileContent, 0) + struct.pack_into(big_byte_format, fileContent, 0, *tmp) + + print("Byte swapping done.") # Patch the header print("Patching header...") -strippedContent[0x3E] = 0x50 +fileContent[0x3E] = 0x50 # Check to see if the ROM is a "vanilla" Debug ROM -str_hash = get_str_hash(bytearray(strippedContent)) +str_hash = get_str_hash(bytearray(fileContent)) if str_hash != "f0b7f35375f9cc8ca1b2d59d78e35405": print("Error: Expected a hash of f0b7f35375f9cc8ca1b2d59d78e35405 but got " + str_hash + ". " + "The baserom has probably been tampered, find a new one") @@ -68,6 +78,6 @@ if str_hash != "f0b7f35375f9cc8ca1b2d59d78e35405": # Write out our new ROM print("Writing new ROM 'baserom.z64'.") with open("baserom.z64", mode="wb") as file: - file.write(bytes(strippedContent)) + file.write(bytes(fileContent)) -print("Done!") \ No newline at end of file +print("Done!")