1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-12-26 22:56:20 +00:00

Added ability to provide ichaindis a symbol (#385)

* Added ability to provide ichaindis a symbol and gave it ability to look up actor var names

* Minor fixes

* Fixed bug with output of script

* Refactored the ROM lookup for ichaindis

* Switched ichaindis to use filemap for ROM address lookup

* Removed unused import and constant

* Minor improvements to ichaindis

* Updated help text

* ichaindis will now only calculate Actor vars if needed

* Changed no-names switch to names switch
This commit is contained in:
Darin 2020-09-20 08:16:00 -07:00 committed by GitHub
parent 7bd4686f1a
commit d61ae83df1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -4,6 +4,8 @@ import os
import sys import sys
import struct import struct
import argparse import argparse
import re
from overlayhelpers.filemap import FileResult, GetFromVRam, GetFromRom
ICHAIN_MACROS = [ ICHAIN_MACROS = [
'ICHAIN_U8', 'ICHAIN_U8',
@ -19,11 +21,55 @@ ICHAIN_MACROS = [
'ICHAIN_VEC3S', 'ICHAIN_VEC3S',
] ]
Z64_ACTOR_PATH = "../include/z64actor.h"
def get_rom_address(offset):
if offset.startswith("D_"):
offset = offset[2:]
offset = int(offset, 16)
if offset >= 0x80000000:
result = GetFromVRam(offset)
offset = result.vrom.start + result.offset
return hex(offset)
def get_actor_var_names():
in_actor = False
actor_vars = {}
with open(os.path.dirname(os.path.realpath(__file__)) + "/" + Z64_ACTOR_PATH) as actor_h:
for line in actor_h:
if in_actor:
if "}" in line:
# Reached the end of the actor struct so break out
break
# Parse out the memory address (from the comment) and the variable name
regex = r'.*\/\* (.*) \*\/\s+(struct)?\s*.+\s+(.+);.*'
actor_var_info = re.match(regex, line)
if actor_var_info:
# Strip off the 0x0* part and store it
new_var_index = re.sub('0x0*', '', actor_var_info[1])
actor_vars[new_var_index] = actor_var_info[3]
elif "typedef struct Actor {" in line:
# Found the Actor struct
in_actor = True
return actor_vars
def main(): def main():
parser = argparse.ArgumentParser(description='Decompiles an InitChain') parser = argparse.ArgumentParser(description='Decompiles an InitChain')
parser.add_argument('filename', help='ROM file path') parser.add_argument('filename', help='ROM file path')
parser.add_argument('offset', help='ROM offset to an InitChain') parser.add_argument('offset', help='ROM offset or symbol of an InitChain')
parser.add_argument('--names', action="store_true", help='Retrieve variable names from the actor struct')
args = parser.parse_args() args = parser.parse_args()
# Get the ROM address, if the offset is already a ROM address it will just be returned.
args.offset = get_rom_address(args.offset)
romOff = int(args.offset, 16) romOff = int(args.offset, 16)
try: try:
@ -34,6 +80,10 @@ def main():
sys.exit(1) sys.exit(1)
print ('static InitChainEntry sInitChain[] = {') print ('static InitChainEntry sInitChain[] = {')
if args.names:
actor_variable_names = get_actor_var_names()
while True: while True:
entry = struct.unpack('>I', romData[romOff:romOff+4])[0] entry = struct.unpack('>I', romData[romOff:romOff+4])[0]
romOff += 4 romOff += 4
@ -43,7 +93,14 @@ def main():
offset = ((entry) >> 16) & 0x7FF offset = ((entry) >> 16) & 0x7FF
value = (entry) & 0xFFFF value = (entry) & 0xFFFF
print(' {0}(unk_{1:X}, {2}, {3}),'.format(ICHAIN_MACROS[t], offset, value, ('ICHAIN_CONTINUE' if cont == 1 else 'ICHAIN_STOP'))) var_name = '{0:X}'.format(offset)
if args.names and var_name in actor_variable_names:
var_name = actor_variable_names[var_name]
else:
var_name = "unk_" + var_name
print(' {0}({1}, {2}, {3}),'.format(ICHAIN_MACROS[t], var_name, value, ('ICHAIN_CONTINUE' if cont == 1 else 'ICHAIN_STOP')))
if cont == 0: if cont == 0:
break break
print ('};') print ('};')