From 36b71ca2de3a02673210d1ed7ea686d92a086090 Mon Sep 17 00:00:00 2001 From: Dragorn421 Date: Sun, 9 Feb 2025 22:42:39 +0100 Subject: [PATCH] Update csdis.py (#2459) * csdis: move filemap import to main() as it is only needed there * csdis: fix CS_TIME macro * csdis: make `disassemble_cutscene` return cutscene size in words * add comment on why total_entries+1 --- tools/csdis.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/tools/csdis.py b/tools/csdis.py index 1d96c48e4..f83efd3aa 100755 --- a/tools/csdis.py +++ b/tools/csdis.py @@ -2,8 +2,6 @@ # Disassemble a cutscene script -from overlayhelpers import filemap - import argparse, os, struct import math @@ -506,7 +504,7 @@ cutscene_command_macros = { "CS_RUMBLE_CONTROLLER(%h2:1:x, %h1:1:s, %h2:2:s, %b2:2:x, %b1:2:x, %b4:3:x, %b3:3:x, %h1:3:x)", 3), 140: ("CS_TIME_LIST(%w1:1:s)", 2, None, 0, - "CS_TIME(%h2:1:x, %h1:1:s, %h2:2:s, %b2:2:x, %b1:2:x, %w1:3:x)", 3), + "CS_TIME(%h2:1:x, %h1:1:s, %h2:2:s, %b2:2:x, %b1:2:x)", 3), 10: ("CS_PLAYER_CUE_LIST(%w1:1:s)", 2, None, 0, "CS_PLAYER_CUE(%h2:1:e6, %h1:1:s, %h2:2:s, %h1:2:x, %h2:3:x, %h1:3:x, %w1:4:s, %w1:5:s, %w1:6:s, %w1:7:s, %w1:8:s, %w1:9:s, %w1:10:f, %w1:11:f, %w1:12:f)", 12), @@ -711,7 +709,12 @@ Note that this isn't protected against indexing errors since a cutscene should a end before the end of the file it's in. """ -def disassemble_cutscene(cs_in): +def disassemble_cutscene(cs_in) -> tuple[int, str]: + """ + Takes a sequence of words cs_in + + Returns a tuple (cutscene_size_in_words, cutscene_macros_source) + """ i = 0 total_entries = cs_in[i] i+=1 @@ -720,12 +723,14 @@ def disassemble_cutscene(cs_in): if (total_entries < 0 or cutscene_end_frame < 0): print("This cutscene would abort if played in-engine") if total_entries < 0: - return "Could not disassemble cutscene: Number of commands is negative" + raise Exception("Could not disassemble cutscene: Number of commands is negative") macros = format_cmd(begin_cutscene_entry[0], [total_entries, cutscene_end_frame])+line_end + # iterate total_entries+1 times to also parse the CS_END_OF_SCRIPT command, + # which is not included in the count for k in range(0,total_entries+1): cmd_type = cs_in[i] if (cmd_type == 0xFFFFFFFF): - return macros + multi_key(-1)[0]+line_end + return (i+2), (macros + multi_key(-1)[0]+line_end) entry = multi_key(cmd_type) if entry is None: entry = unk_data_entry @@ -758,12 +763,14 @@ def disassemble_cutscene(cs_in): else: i += n_words print("Warning: cutscene reached maximum entries without encountering a CS_END_SCRIPT command") - return macros + return i, macros def hex_parse(s): return int(s, 16) def main(): + from overlayhelpers import filemap + parser = argparse.ArgumentParser(description="Disassembles cutscenes for OoT") parser.add_argument('address', help="VRAM or ROM address to disassemble at", type=hex_parse) args = parser.parse_args() @@ -785,7 +792,7 @@ def main(): ovl_file.seek(file_result.offset) cs_data = [i[0] for i in struct.iter_unpack(">I", bytearray(ovl_file.read()))] if cs_data is not None: - print("static CutsceneData D_" + hex(args.address).replace("0x","").upper() + "[] = {\n" + indent+disassemble_cutscene(cs_data).replace(linesep,linesep+indent).rstrip()+"\n};") + print("static CutsceneData D_" + hex(args.address).replace("0x","").upper() + "[] = {\n" + indent+disassemble_cutscene(cs_data)[1].replace(linesep,linesep+indent).rstrip()+"\n};") if __name__ == "__main__": main()