1
0
mirror of https://github.com/zeldaret/oot.git synced 2024-09-21 04:24:43 +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:
Anghelo Carvajal 2021-01-14 17:14:33 -03:00 committed by GitHub
parent 65e956a272
commit 9c2ad0c60b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 31 deletions

View File

@ -94,7 +94,7 @@ git clone https://github.com/zeldaret/oot.git
#### 4. Prepare a base ROM #### 4. Prepare a base ROM
Copy over your copy of the Master Quest (Debug) ROM inside the root of this new project directory. 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 #### 5. Setup the ROM and build process

View File

@ -22,44 +22,54 @@ if path.exists("baserom_original.z64"):
romFileName = "baserom_original.z64" romFileName = "baserom_original.z64"
elif path.exists("baserom_original.n64"): elif path.exists("baserom_original.n64"):
romFileName = "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 # Read in the original ROM
if romFileName != "": print("File '" + romFileName + "' found.")
print("File '" + romFileName + "' found.") with open(romFileName, mode="rb") as file:
with open(romFileName, mode="rb") as file: fileContent = bytearray(file.read())
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 # Strip the overdump
print("Stripping 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 # Patch the header
print("Patching header...") print("Patching header...")
strippedContent[0x3E] = 0x50 fileContent[0x3E] = 0x50
# Check to see if the ROM is a "vanilla" Debug ROM # 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": if str_hash != "f0b7f35375f9cc8ca1b2d59d78e35405":
print("Error: Expected a hash of f0b7f35375f9cc8ca1b2d59d78e35405 but got " + str_hash + ". " + print("Error: Expected a hash of f0b7f35375f9cc8ca1b2d59d78e35405 but got " + str_hash + ". " +
"The baserom has probably been tampered, find a new one") "The baserom has probably been tampered, find a new one")
@ -68,6 +78,6 @@ if str_hash != "f0b7f35375f9cc8ca1b2d59d78e35405":
# Write out our new ROM # Write out our new ROM
print("Writing new ROM 'baserom.z64'.") print("Writing new ROM 'baserom.z64'.")
with open("baserom.z64", mode="wb") as file: with open("baserom.z64", mode="wb") as file:
file.write(bytes(strippedContent)) file.write(bytes(fileContent))
print("Done!") print("Done!")