mirror of
https://github.com/zeldaret/oot.git
synced 2024-11-25 09:45:02 +00:00
fixbaserom.py: Add support to v64 format and improve performance (#629)
* Add byte swap for v64 files Signed-off-by: angie <angheloalf95@gmail.com> * Reduce `len` function calls Signed-off-by: angie <angheloalf95@gmail.com> * Optimze a bit the byte-swapped v64 format Signed-off-by: angie <angheloalf95@gmail.com> * 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 <angheloalf95@gmail.com> * Swap twice the bytes per cycle to improve performance Signed-off-by: angie <angheloalf95@gmail.com> * 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 <angheloalf95@gmail.com> * Add v64 compatibility in the Readme Signed-off-by: angie <angheloalf95@gmail.com> * Read whole file as little endian and write it as big endian without the loop Signed-off-by: angie <angheloalf95@gmail.com>
This commit is contained in:
parent
65e956a272
commit
9c2ad0c60b
2 changed files with 41 additions and 31 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
||||
# 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)
|
||||
print("File '" + romFileName + "' found.")
|
||||
with open(romFileName, mode="rb") as file:
|
||||
fileContent = bytearray(file.read())
|
||||
|
||||
# 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!")
|
Loading…
Reference in a new issue