summaryrefslogtreecommitdiff
path: root/tools/script_disassembler/split_script_data.py
diff options
context:
space:
mode:
authoroctorock <79596758+octorock@users.noreply.github.com>2021-03-06 18:32:11 +0100
committeroctorock <79596758+octorock@users.noreply.github.com>2021-03-06 18:49:02 +0100
commit2bcea72f4982efbcacf5af162b1a8af4f6c27ca3 (patch)
tree8253d031807c5362f7acbcc5a2f044b78b7d7c94 /tools/script_disassembler/split_script_data.py
parent15f480dc0f99437a5ff08c5a8c5c037107b89663 (diff)
Clean up script files
Diffstat (limited to 'tools/script_disassembler/split_script_data.py')
-rw-r--r--tools/script_disassembler/split_script_data.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/tools/script_disassembler/split_script_data.py b/tools/script_disassembler/split_script_data.py
new file mode 100644
index 00000000..58ffa5a0
--- /dev/null
+++ b/tools/script_disassembler/split_script_data.py
@@ -0,0 +1,118 @@
+from script_disassembler import disassemble_script, generate_macros
+import sys
+
+# Reads a section from the baserom, splits the residing scripts into seperate files and disassembles them
+# Should only be run before any manual changes to the script files are done!
+
+TMC_FOLDER = '../..'
+
+ROM_OFFSET = 0x08000000
+SCRIPTS_START = 0x08008B5C
+SCRIPTS_END = 0x08016984
+
+# Create labels for these additional script instructions
+# Currently done by splitting the script at that point
+LABEL_BREAKS = [0x0800A088, 0x0800ACE0, 0x0800AD54, 0x0800B41C, 0x0800B7C4, 0x0800C8C8, 0x0800D190, 0x800D3EC, 0x0800E9F4, 0x0800FD80,
+ 0x08012AC8, 0x08012F0C, 0x080130E4, 0x08013B70, 0x080142B0, 0x080147DC, 0x08014A80, 0x08014B10, 0x0801635C, 0x08016384, 0x080165D8]
+
+# Whether to output a label for every line
+PRINT_ALL_LABELS = False
+
+
+def read_baserom():
+ # read baserom data
+ with open(f'{TMC_FOLDER}/baserom.gba', 'rb') as baserom:
+ return bytearray(baserom.read())
+
+
+def get_label(addr):
+ return hex(addr).upper().replace('0X', 'script_0')
+
+
+def disassemble_scripts(baserom_data):
+ script_start = SCRIPTS_START-ROM_OFFSET
+
+ scripts = ''' .include "asm/macros.inc"
+ .include "constants/constants.inc"
+
+ .include "asm/macros/scripts.inc"
+
+ .syntax unified
+
+ .text
+
+'''
+ label_break = 0
+
+ while script_start < SCRIPTS_END-ROM_OFFSET:
+ if label_break < len(LABEL_BREAKS) and script_start + ROM_OFFSET >= LABEL_BREAKS[label_break]:
+ label_break += 1
+
+ label = get_label(script_start + ROM_OFFSET)
+ print(f"Disassembling \033[1;34m{label}\033[0m ({script_start} / { SCRIPTS_END-ROM_OFFSET} bytes converted)...")
+ # find end of the script signified by 0xffff0000
+ script_end = baserom_data.index(b'\xff\xff\x00\x00', script_start) + 4
+
+ if script_end > SCRIPTS_END-ROM_OFFSET:
+ script_end = SCRIPTS_END-ROM_OFFSET
+
+ # break at a predefined label into a new file
+ if label_break < len(LABEL_BREAKS) and script_end + ROM_OFFSET > LABEL_BREAKS[label_break]:
+ script_end = LABEL_BREAKS[label_break]-ROM_OFFSET
+
+ # read data from rom
+ data = baserom_data[script_start:script_end]
+
+ scripts += f' .include "data/scripts/{label}.inc"\n'
+ stdout = sys.stdout
+
+ with open(f'{TMC_FOLDER}/data/scripts/{label}.inc', 'w') as out:
+ sys.stdout = out
+
+ if script_start == 0x1637C: # This function is actually assembly
+ print('''thumb_func_start script_0801637C
+script_0801637C:
+ push {lr}
+ bl CreateDust
+ pop {pc}''')
+ sys.stdout = stdout
+ script_start = script_end
+ continue
+
+ print(f'SCRIPT_START {label}')
+ res = disassemble_script(data, script_start + ROM_OFFSET, PRINT_ALL_LABELS)
+ if res != 0:
+ # Script ended in the middle, need to create a new file
+ script_end = script_start + res
+ sys.stdout = stdout
+
+ script_start = script_end
+ return scripts
+
+
+def main():
+ baserom_data = read_baserom()
+
+ # Do two passes, in the first pass not all labels that are jumped to are known, so those labels are recorded in the first pass
+ # This is not necessary when all labels are printed
+ if not PRINT_ALL_LABELS:
+ print('Collecting labels...')
+ disassemble_scripts(baserom_data)
+ print('Writing scripts with labels...')
+ scripts = disassemble_scripts(baserom_data)
+
+ print('Writing scripts.s file...')
+ with open(f'{TMC_FOLDER}/data/scripts.s', 'w') as out:
+ out.write(scripts)
+ print('Generating asm macros...')
+ stdout = sys.stdout
+ with open(f'{TMC_FOLDER}/asm/macros/scripts.inc', 'w') as out:
+ sys.stdout = out
+ generate_macros()
+ sys.stdout = stdout
+
+ print('\033[1;92mDone\033[0m\n')
+
+
+if __name__ == '__main__':
+ main()