from os import path import sys import struct import hashlib def get_str_hash(byte_array): return str(hashlib.md5(byte_array).hexdigest()) # If the baserom exists and is correct, we don't need to change anything if path.exists("baserom_non_mq.z64"): with open("baserom_non_mq.z64", mode="rb") as file: fileContent = bytearray(file.read()) if get_str_hash(fileContent) == "9c1d795429220f5389045693a011b8f6": print("Found valid baserom - exiting early") sys.exit(0) # Determine if we have a ROM file romFileExtensions = ["z64", "n64", "v64"] def find_baserom_original(): for romFileExtLower in romFileExtensions: for romFileExt in (romFileExtLower, romFileExtLower.upper()): romFileNameCandidate = "baserom_original_non_mq." + romFileExt if path.exists(romFileNameCandidate): return romFileNameCandidate return None romFileName = find_baserom_original() if romFileName is None: print("Error: Could not find baserom_original_non_mq.z64/baserom_original_non_mq.n64/baserom_original_non_mq.v64.") sys.exit(1) # Read in the original ROM print("File '" + romFileName + "' found.") with open(romFileName, mode="rb") as file: fileContent = bytearray(file.read()) # Strip the overdump print("Stripping overdump...") 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...") fileContent[0x3E] = 0x50 for i in range(0x35CF000, len(fileContent)): fileContent[i] = 0xFF # Check to see if the ROM is a "vanilla" Debug ROM str_hash = get_str_hash(bytearray(fileContent)) if str_hash != "9c1d795429220f5389045693a011b8f6": print("Error: Expected a hash of 9c1d795429220f5389045693a011b8f6 but got " + str_hash + ". " + "The baserom has probably been tampered, find a new one") if str_hash == "32fe2770c0f9b1a9cd2a4d449348c1cb": print("The provided baserom is a rom which has been edited with ZeldaEdit and is not suitable for use with decomp. " + "Find a new one.") sys.exit(1) # Write out our new ROM print("Writing new ROM 'baserom_non_mq.z64'.") with open("baserom_non_mq.z64", mode="wb") as file: file.write(bytes(fileContent)) print("Done!")