mirror of https://github.com/zeldaret/oot.git
				
				
				
			
		
			
				
	
	
		
			116 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
| #!/usr/bin/env python3
 | |
| 
 | |
| # SPDX-FileCopyrightText: 2024 zeldaret
 | |
| # SPDX-License-Identifier: CC0-1.0
 | |
| 
 | |
| # Re-disassemble cutscene scripts part of the source tree,
 | |
| # using csdis.py and modifying files in-place
 | |
| 
 | |
| 
 | |
| import re
 | |
| from pathlib import Path
 | |
| import struct
 | |
| 
 | |
| import mapfile_parser
 | |
| 
 | |
| import csdis
 | |
| from overlayhelpers import filemap
 | |
| 
 | |
| 
 | |
| SRC_ENCODING = "UTF-8"
 | |
| 
 | |
| MAPFILE_P = Path("build/gc-eu-mq-dbg/oot-gc-eu-mq-dbg.map")
 | |
| BASEROM_SEGMENTS_P = Path("extracted/gc-eu-mq-dbg/baserom/")
 | |
| 
 | |
| HARDCODED_SYM_ROM = {
 | |
|     "gFireMedallionCs": 0xD25834,
 | |
|     "D_80AF0880": 0xEA6860,
 | |
|     "D_80AF10A4": 0xEA7084,
 | |
|     "D_80AF1728": 0xEA7708,
 | |
|     "D_808BCE20": 0xC8BB20,
 | |
|     "D_808BD2A0": 0xC8BFA0,
 | |
|     "D_808BD520": 0xC8C220,
 | |
|     "D_808BD790": 0xC8C490,
 | |
|     "gSpiritMedallionCs": 0xE6A38C,
 | |
|     "gShadowMedallionCs": 0xD40EFC,
 | |
|     "D_80B4C5D0": 0xF022D0,
 | |
|     "D_80ABF9D0": 0xE75A40,
 | |
|     "D_80ABFB40": 0xE75BB0,
 | |
|     "gWaterMedallionCs": 0xEAA0FC,
 | |
|     "D_80A88164": 0xE3ED34,
 | |
|     "D_808BB2F0": 0xC89FF0,
 | |
|     "D_808BB7A0": 0xC8A4A0,
 | |
|     "D_808BBD90": 0xC8AA90,
 | |
|     "gChildWarpInCS": 0xD45460,
 | |
|     "gAdultWarpOutToTCS": 0xD45340,
 | |
|     "gChildWarpOutToTCS": 0xD45840,
 | |
|     "gChildWarpInToTCS": 0xD45710,
 | |
|     "gAdultWarpInToTCS": 0xD45230,
 | |
|     "gAdultWarpInCS": 0xD44FA0,
 | |
|     "gChildWarpOutCS": 0xD45590,
 | |
|     "gAdultWarpOutCS": 0xD450B0,
 | |
|     "gForestMedallionCs": 0xD4974C,
 | |
| }
 | |
| 
 | |
| mapfile = mapfile_parser.MapFile()
 | |
| mapfile.readMapFile(MAPFILE_P)
 | |
| 
 | |
| pat_CutsceneData = re.compile(
 | |
|     r"""
 | |
|     CutsceneData
 | |
|     \s+
 | |
|     ( [^\s]* )  # symbol name
 | |
|     \s*
 | |
|     \[ \s* \]
 | |
|     \s* = \s*
 | |
|     \{
 | |
|         (?: [^}]* | \n )*
 | |
|     \} ;
 | |
|     """,
 | |
|     re.VERBOSE,
 | |
| )
 | |
| 
 | |
| 
 | |
| def get_sym_rom(sym_name: str):
 | |
|     rom = HARDCODED_SYM_ROM.get(sym_name)
 | |
|     if rom:
 | |
|         return rom
 | |
|     print(f"Trying to find {sym_name} from the map (assuming OK build)")
 | |
|     sym = mapfile.findSymbolByName(sym_name)
 | |
|     print(f'"{sym_name}": 0x{sym.symbol.vrom:X}')
 | |
|     return sym.symbol.vrom
 | |
| 
 | |
| 
 | |
| def repl(m: re.Match):
 | |
|     sym_name = m.group(1)
 | |
|     sym_rom = get_sym_rom(sym_name)
 | |
|     file_result = filemap.GetFromRom(sym_rom)
 | |
|     assert file_result is not None, (sym_name, sym_rom)
 | |
|     data = (BASEROM_SEGMENTS_P / file_result.name).read_bytes()
 | |
|     cs_data_bytes = data[file_result.offset :]
 | |
|     cs_data = [i[0] for i in struct.iter_unpack(">I", cs_data_bytes)]
 | |
|     return (
 | |
|         f"CutsceneData {sym_name}[] = "
 | |
|         + "{\n"
 | |
|         + (
 | |
|             "\n".join(
 | |
|                 f"    {line}"
 | |
|                 for line in csdis.disassemble_cutscene(cs_data).splitlines()
 | |
|             ).rstrip()
 | |
|         )
 | |
|         + "\n};"
 | |
|     )
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     for file_c in Path("src").glob("**/*.c"):
 | |
|         src = file_c.read_text(encoding=SRC_ENCODING)
 | |
|         src_new = pat_CutsceneData.sub(repl, src)
 | |
|         if src_new != src:
 | |
|             file_c.write_text(src_new, encoding=SRC_ENCODING)
 | |
|             print(file_c)
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     main()
 |