Files
Diddy-Kong-Racing/tools/python/calc_func_checksums.py
T
Ryan MyersandGitHub 6db9a8d6ea Splat merge (#470)
* First pass

* Fix n64crc and add submodules properly

* Fix other versions

* Match func_8005B818 for v80 code.

* Formatting

* Fix build for JPN in last commit. Still broken in post v77 roms though.

* Fix builds for other versions.

* Match load_menu_text for other versions.

* Fix progress script

* update m2c

* Modify asset tools to remove the LD script code.

* Fix asm file macro inclue

* Get a working splat version for us_1.0 to build from the assets tool.

* update asm differ

* Update tools again

* Fix the makefile to only compile assets when requested. This will build all versions successfully, and compile assets for us_1.0 when requested.

* First round of suggestions

* Small cleanup

* Fix the gcc_generate.py path.

* Make entrypointThreadStack

* Small addition to the last commit

* "Fix" score script. Still need to fix the score values themselves, but at least it runs and is kind of close.

* Much closer matching score script

* Fix the splat version due to a breaking change in 0.33.0 for this repo for now.

* Fix the main function name

* Add gitignore entries

* Fix the padding problem to be handled by objcopy instead of a binary pad from splat.

* Update the README and change dependencies to setup.

* Have a hasm header that can be tweaked.

* Still calculate the checksum on no_verify builds or they won't work.

* Add support for boot_custom.bin

* Fix custom boot ld code.

* Fix score script

* Fix gcc building.

* Update m2c

* Fix warning, stop ignoring mod assets, and add some handy make rules.

* Uggh, serves me right for not testing.

* First stab at modifiable entrypoint.

* Fix typo, and small README change

* Stop n64crd from defaulting to returning 6105, so we can properly fail if the CIC checksum fails. Also, fix the

* Extract custom boot script

* Update automated scripts.

* Woops, fixed the MAXCONTROLLERS thing now.

* Add the method for building binutils back. Sorry!

* Only use -m32 when the longbit says we're on a 64 bit platform.

* Woops....

* Hopefully fix arm detection for raspi ido downloads.
2025-03-25 09:07:00 -04:00

86 lines
3.1 KiB
Python

import re
import os
import sys
from file_util import FileUtil
REGION = sys.argv[1]
VERSION = sys.argv[2]
MAP_FILEPATH = f'build/dkr.{REGION}.{VERSION}.map'
ROM_FILEPATH = f'build/dkr.{REGION}.{VERSION}.z64'
FUNCTIONS_TO_CALC = [
# function checksum variable func size variable
('func_80019808', 'gFunc80019808Checksum', 'gFunc80019808Length'),
('render_scene', 'gTractionTableChecksum', 'gTrackRenderFuncLength'),
('obj_loop_goldenballoon', 'gObjLoopGoldenBalloonChecksum', 'gObjLoopGoldenBalloonLength'),
('viewport_rsp_set', 'gViewportFuncChecksum', 'gViewportFuncLength')
]
def getMatches(string, regex):
out = []
matches = re.finditer(regex, string, re.MULTILINE)
for matchNum, match in enumerate(matches, start=1):
start = match.start()
end = match.end()
out.append((string[start:end], match.groups(), (start, end)))
return out
rom = FileUtil.get_bytes_from_file(ROM_FILEPATH)
mapFile = {}
RAM_TO_ROM = None
def write_word_to_rom(romOffset, value):
global rom
rom[romOffset + 0] = (value >> 24) & 0xFF
rom[romOffset + 1] = (value >> 16) & 0xFF
rom[romOffset + 2] = (value >> 8) & 0xFF
rom[romOffset + 3] = value & 0xFF
def calculate_checksum_for_function(funcLabel, varLabel, funcSizeLabel):
if funcLabel not in mapFile:
raise Exception('Label "' + funcLabel + '" does not exist in the map file!')
if varLabel not in mapFile:
raise Exception('Label "' + varLabel + '" does not exist in the map file!')
if funcSizeLabel not in mapFile:
raise Exception('Label "' + funcSizeLabel + '" does not exist in the map file!')
funcEntry = mapFile[funcLabel]
funcAddress = funcEntry['value']
funcLength = funcEntry['length']
funcRomOffset = funcAddress - RAM_TO_ROM
count = 0
for i in range(0, funcLength):
count += rom[funcRomOffset + i]
# Save function checksum.
varEntry = mapFile[varLabel]
varAddress = varEntry['value']
varRomOffset = varAddress - RAM_TO_ROM
write_word_to_rom(varRomOffset, count)
# Save function size.
sizeEntry = mapFile[funcSizeLabel]
sizeAddress = sizeEntry['value']
sizeRomOffset = sizeAddress - RAM_TO_ROM
write_word_to_rom(sizeRomOffset, funcLength)
def calculate_matches():
global mapFile, RAM_TO_ROM
REGEX_MAP_GET_LABEL = r"[ ]*?(?:0x[0-9A-Fa-f]{8})?([0-9A-Fa-f]{8})[ ]*?([_A-Za-z0-9]+)"
mapText = FileUtil.get_text_from_file(MAP_FILEPATH)
mapMatches = getMatches(mapText, REGEX_MAP_GET_LABEL)
for i in range(0, len(mapMatches) - 1):
match = mapMatches[i]
labelValue = match[1]
value = int(labelValue[0], 16)
length = int(mapMatches[i + 1][1][0], 16) - value
mapFile[labelValue[1]] = { "value": value, "length": length }
RAM_TO_ROM = mapFile['__RAM_TO_ROM']['value']
def main():
calculate_matches()
for entry in FUNCTIONS_TO_CALC:
calculate_checksum_for_function(entry[0], entry[1], entry[2])
FileUtil.write_bytes_to_file(ROM_FILEPATH, rom)
main()