diff --git a/tools/gen_externs.py b/tools/gen_externs.py deleted file mode 100644 index 323c9282..00000000 --- a/tools/gen_externs.py +++ /dev/null @@ -1,132 +0,0 @@ -import argparse -import os -from pathlib import Path -import platform -import subprocess -import sys -import tempfile - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - -parser = argparse.ArgumentParser(description='Generates .inc files with external symbols used by Assembly code') -parser.add_argument('files', nargs='+', help='.s file to generate .inc file for') - -args = parser.parse_args() - -tools_dir = Path(os.path.dirname(os.path.realpath(__file__))) -as_path = tools_dir / 'mwccarm' / '2.0' / 'sp1p5' / 'mwasmarm.exe' -root_dir = tools_dir.parent -asm_dir = root_dir / 'asm' - -MSG_UNKNOWN_IDENTIFIER = 'Unknown identifier,' -MSG_DUPLICATE_DECLARATION = 'Incompatible duplicate declaration of' - -if platform.system() == 'Windows': as_cmd = [str(as_path)] -else: as_cmd = ['wine', str(as_path)] - -as_cmd.extend([ - '-nolink', - '-proc', 'arm5te', - '-msgstyle', 'gcc', - '-DEUR', '-DUSA', - f'-I{asm_dir}', -]) - -def get_unknown_symbols(file: Path): - with tempfile.NamedTemporaryFile(delete=True) as tmp_obj_file: - # Run assembler - cmd = as_cmd.copy() - cmd.extend(['-o', tmp_obj_file.name]) - cmd.append(str(file)) - try: - output = subprocess.check_output(cmd, stderr=subprocess.DEVNULL) - output = output.decode() - except subprocess.CalledProcessError as e: - output = e.stdout.decode() - - # Get unknown identifiers - lines = output.splitlines() - symbol = '' - symbols: set[str] = set() - skip = False - for line in lines: - # print(line) - if ':' not in line: continue - line = line.rsplit(':', 1)[-1].strip() - if line.startswith(MSG_DUPLICATE_DECLARATION): - symbols.add(symbol) - skip = True - elif line.startswith(MSG_UNKNOWN_IDENTIFIER): - symbols.add(symbol) - skip = False - symbol = line[len(MSG_UNKNOWN_IDENTIFIER):].strip() - elif not skip: - symbol += line.strip() - symbols.add(symbol) - if '' in symbols: symbols.remove('') - if len(symbols) == 0: - return [] - - return sorted(list(symbols)) - -files_updated = 0 -inc_files_created = 0 - -def generate_externs(file: Path): - global inc_files_created - - with tempfile.NamedTemporaryFile('w', suffix='.s', delete=True) as tmp_asm_file: - file_name = file.name.rsplit('.', 1)[0] - inc_file_name = f'{file_name}.inc' - inc_path = file.parent / inc_file_name - - # Comment out '.include ".../my_file.inc" - with open(file, 'r') as f: - contents = f.read() - lines = contents.splitlines() - has_inc_file = False - for i in range(len(lines)): - if not lines[i].strip().startswith('.include'): continue - if inc_file_name not in lines[i]: continue - lines[i] = f';{lines[i]}' - has_inc_file = True - break - - # Get unknown symbols - for line in lines: - tmp_asm_file.write(line) - tmp_asm_file.write('\n') - tmp_asm_file.flush() - symbols = get_unknown_symbols(tmp_asm_file.name) - - # Create inc file - with open(inc_path, 'w') as f: - f.write('#pragma once\n') - for i, symbol in enumerate(symbols): - # Skip duplicates - if symbol in symbols[:i]: continue - f.write(f'.extern {symbol}\n') - - # Add .include - if not has_inc_file: - relative_inc_path = inc_path.relative_to('asm/') - lines.insert(0, f' .include "{relative_inc_path}"') - with open(file, 'w') as f: - for line in lines: - f.write(line) - f.write('\n') - inc_files_created += 1 - - -for file in args.files: - if not file.endswith('.s'): continue - path = Path(file) - if len(args.files) > 1: - print(path) - generate_externs(path) - files_updated += 1 - -if len(args.files) > 1: - print(f"Updated {files_updated} file(s)") - print(f"Created {inc_files_created} .inc file(s)") diff --git a/tools/lcf.py b/tools/lcf.py deleted file mode 100644 index 7a37598e..00000000 --- a/tools/lcf.py +++ /dev/null @@ -1,435 +0,0 @@ -class Overlay: - def __init__(self, name: str = None, after = None, origin: int = None, objects: list[str] = None): - self.name = name - self.objects = objects - self.after = after - self.origin = origin - - def __str__(self) -> str: - return self.name - -def name(path: str): return path.split("/")[-1] - -ARM9_OBJECTS = [ - 'asm/main/main_02000000.s', - - 'src/Main/Actor/ActorType.cpp', - - 'asm/main/main_0203e8a0.s', - - 'libs/cpp/src/__register_global_object.c', - - 'asm/main/main_0204f8f4.s', -] - -ITCM_OBJECTS = [ - 'asm/itcm.s' -] - -DTCM_OBJECTS = [ - 'asm/dtcm.s' -] - -ov00 = Overlay(name='ov00', after='ARM9', objects=[ - 'asm/ov00/ov00_020773c0.s', - - 'asm/ov00/Player/TouchControl.s', - - 'asm/ov00/ov00_0207afa0.s', - - 'asm/ov00/Map/Course.s', - 'asm/ov00/Map/MapBase.s', - - 'asm/ov00/ov00_0207da38.s', - - 'asm/ov00/Map/MapManager.s', - - 'asm/ov00/ov00_02086cd0.s', - - 'asm/ov00/Save/AdventureFlags.s', - - 'asm/ov00/ov00_020980f4.s', - - 'asm/ov00/Player/PlayerBase.s', - 'asm/ov00/Player/LinkStateBase.s', - 'asm/ov00/Player/LinkStateMove.s', - 'asm/ov00/Player/LinkStateFollow.s', - 'asm/ov00/Player/TouchGesture.s', - - 'asm/ov00/ov00_020a8e04.s', - - 'asm/ov00/Player/LinkStateInteract.s', - 'asm/ov00/Player/LinkStateItem.s', - 'asm/ov00/Player/LinkStateDamage.s', - 'asm/ov00/Item/Item.s', - 'src/00_Core/Item/ItemManager.cpp', - 'asm/ov00/Player/LinkStateRoll.s', - 'asm/ov00/Player/PlayerControl.s', - - 'asm/ov00/ov00_020b1498.s', - - 'asm/ov00/Actor/Actor.s', - - 'asm/ov00/ov00_020c3348.s', - - 'asm/ov00/Actor/ActorManager.s', - - 'asm/ov00/ov00_020c3e54.s', -]) -ov01 = Overlay(name='ov01', after=[ov00], objects=[ - 'asm/ov01.s' -]) -ov02 = Overlay(name='ov02', after=[ov00], objects=[ - 'asm/ov02.s' -]) -ov03 = Overlay(name='ov03', after=[ov00], objects=[ - 'asm/ov03.s' -]) -ov04 = Overlay(name='ov04', after=[ov01, ov02, ov03], objects=[ - 'asm/ov04.s' -]) -ov05 = Overlay(name='ov05', after=[ov01, ov02, ov03], objects=[ - 'asm/ov05.s' -]) -ov06 = Overlay(name='ov06', after=[ov01, ov02, ov03], objects=[ - 'asm/ov06.s' -]) -ov07 = Overlay(name='ov07', after=[ov01, ov02, ov03], objects=[ - 'asm/ov07.s' -]) -ov08 = Overlay(name='ov08', after=[ov04, ov05, ov06, ov07], objects=[ - 'asm/ov08.s' -]) -ov09 = Overlay(name='ov09', after=[ov04, ov05, ov06, ov07], objects=[ - 'asm/ov09.s' -]) -ov10 = Overlay(name='ov10', after=[ov04, ov05, ov06, ov07], objects=[ - 'asm/ov10.s' -]) -ov11 = Overlay(name='ov11', after=[ov04, ov05, ov06, ov07], objects=[ - 'asm/ov11.s' -]) -ov12 = Overlay(name='ov12', after=[ov04, ov05, ov06, ov07], objects=[ - 'asm/ov12.s' -]) -ov13 = Overlay(name='ov13', after=[ov04, ov05, ov06, ov07], objects=[ - 'asm/ov13.s' -]) -ov14 = Overlay(name='ov14', after=[ov08, ov09, ov10, ov13], objects=[ - 'asm/ov14/ov14_0211f640.s', - - 'asm/ov14/Actor/ActorRupee.s', - - 'asm/ov14/ov14_0213b778.s', -]) -ov15 = Overlay(name='ov15', after=[ov08, ov09, ov10, ov13], objects=[ - 'asm/ov15.s' -]) -ov16 = Overlay(name='ov16', after=[ov08, ov09, ov10, ov13], objects=[ - 'asm/ov16.s' -]) -ov17 = Overlay(name='ov17', after=[ov14, ov16], objects=[ - 'asm/ov17.s' -]) -ov18 = Overlay(name='ov18', after=[ov14, ov16], objects=[ - 'asm/ov18.s' -]) -ov19 = Overlay(name='ov19', after=[ov17, ov18], objects=[ - 'asm/ov19.s' -]) -ov20 = Overlay(name='ov20', after=[ov17, ov18], objects=[ - 'asm/ov20.s' -]) -ov21 = Overlay(name='ov21', after=[ov17, ov18], objects=[ - 'asm/ov21.s' -]) -ov22 = Overlay(name='ov22', after=[ov17, ov18], objects=[ - 'asm/ov22.s' -]) -ov23 = Overlay(name='ov23', after=[ov17, ov18], objects=[ - 'asm/ov23.s' -]) -ov24 = Overlay(name='ov24', after=[ov17, ov18], objects=[ - 'asm/ov24.s' -]) -ov25 = Overlay(name='ov25', after=[ov17, ov18], objects=[ - 'asm/ov25.s' -]) -ov26 = Overlay(name='ov26', after=[ov17, ov18], objects=[ - 'asm/ov26.s' -]) -ov27 = Overlay(name='ov27', after=[ov17, ov18], objects=[ - 'asm/ov27.s' -]) -ov28 = Overlay(name='ov28', after=[ov17, ov18], objects=[ - 'asm/ov28.s' -]) -ov29 = Overlay(name='ov29', after=[ov17, ov18], objects=[ - 'asm/ov29.s' -]) -ov30 = Overlay(name='ov30', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov30.s' -]) -ov31 = Overlay(name='ov31', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov31.s' -]) -ov32 = Overlay(name='ov32', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov32.s' -]) -ov33 = Overlay(name='ov33', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov33.s' -]) -ov34 = Overlay(name='ov34', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov34.s' -]) -ov35 = Overlay(name='ov35', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov35.s' -]) -ov36 = Overlay(name='ov36', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov36.s' -]) -ov37 = Overlay(name='ov37', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov37.s' -]) -ov38 = Overlay(name='ov38', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov38.s' -]) -ov39 = Overlay(name='ov39', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov39.s' -]) -ov40 = Overlay(name='ov40', after=[ov19, ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29], objects=[ - 'asm/ov40.s' -]) -ov41 = Overlay(name='ov41', after=[ov30, ov31, ov32, ov33, ov34, ov35, ov36, ov37, ov38, ov39], objects=[ - 'asm/ov41.s' -]) -ov42 = Overlay(name='ov42', after=[ov30, ov31, ov32, ov33, ov34, ov35, ov36, ov37, ov38, ov39], objects=[ - 'asm/ov42.s' -]) -ov43 = Overlay(name='ov43', after=[ov30, ov31, ov32, ov33, ov34, ov35, ov36, ov37, ov38, ov39], objects=[ - 'asm/ov43.s' -]) -ov44 = Overlay(name='ov44', after=[ov30, ov31, ov32, ov33, ov34, ov35, ov36, ov37, ov38, ov39], objects=[ - 'asm/ov44.s' -]) -ov45 = Overlay(name='ov45', after=[ov30, ov31, ov32, ov33, ov34, ov35, ov36, ov37, ov38, ov39], objects=[ - 'asm/ov45.s' -]) -ov46 = Overlay(name='ov46', after=[ov41, ov42, ov43, ov44, ov45], objects=[ - 'asm/ov46.s' -]) -ov47 = Overlay(name='ov47', after=[ov41, ov42, ov43, ov44, ov45], objects=[ - 'asm/ov47.s' -]) -ov48 = Overlay(name='ov48', after=[ov41, ov42, ov43, ov44, ov45], objects=[ - 'asm/ov48.s' -]) -ov49 = Overlay(name='ov49', after=[ov46, ov47, ov48], objects=[ - 'asm/ov49.s' -]) -ov50 = Overlay(name='ov50', after=[ov46, ov47, ov48], objects=[ - 'asm/ov50.s' -]) -ov51 = Overlay(name='ov51', after=[ov46, ov47, ov48], objects=[ - 'asm/ov51.s' -]) -ov52 = Overlay(name='ov52', after=[ov46, ov47, ov48], objects=[ - 'asm/ov52.s' -]) -ov53 = Overlay(name='ov53', after=[ov49, ov50, ov51, ov52], objects=[ - 'asm/ov53.s' -]) -ov54 = Overlay(name='ov54', after=[ov49, ov50, ov51, ov52], objects=[ - 'asm/ov54.s' -]) -ov55 = Overlay(name='ov55', after=[ov49, ov50, ov51, ov52], objects=[ - 'asm/ov55.s' -]) -ov56 = Overlay(name='ov56', after=[ov49, ov50, ov51, ov52], objects=[ - 'asm/ov56.s' -]) -ov57 = Overlay(name='ov57', after=[ov49, ov50, ov51, ov52], objects=[ - 'asm/ov57.s' -]) -ov58 = Overlay(name='ov58', after=[ov49, ov50, ov51, ov52], objects=[ - 'asm/ov58.s' -]) -ov59 = Overlay(name='ov59', after=[ov49, ov50, ov51, ov52], objects=[ - 'asm/ov59.s' -]) -ov60 = Overlay(name='ov60', after=[ov11, ov12], objects=[ - 'asm/ov60.s' -]) -ov61 = Overlay(name='ov61', after=[ov11, ov12], objects=[ - 'asm/ov61.s' -]) - -OVERLAYS = [ - ov00, ov01, ov02, ov03, ov04, ov05, ov06, ov07, ov08, ov09, - ov10, ov11, ov12, ov13, ov14, ov15, ov16, ov17, ov18, ov19, - ov20, ov21, ov22, ov23, ov24, ov25, ov26, ov27, ov28, ov29, - ov30, ov31, ov32, ov33, ov34, ov35, ov36, ov37, ov38, ov39, - ov40, ov41, ov42, ov43, ov44, ov45, ov46, ov47, ov48, ov49, - ov50, ov51, ov52, ov53, ov54, ov55, ov56, ov57, ov58, ov59, - ov60, ov61 -] - -BUILD = 'build/' - -with open(f'{BUILD}arm9_linker_script.lcf', 'w') as file: - file.write('MEMORY {\n') - file.write(' ARM9 : ORIGIN = 0x2000000 > arm9.bin\n') - file.write(' ITCM : ORIGIN = 0x1ff8000 >> arm9.bin\n') - file.write(' DTCM : ORIGIN = 0x27e0000 >> arm9.bin\n') - file.write(' AUTOLOADS : ORIGIN = 0 >> arm9.bin\n') - file.write(' FOOTER : ORIGIN = 0 > arm9_footer.bin\n') - file.write(' METADATA : ORIGIN = 0 > arm9_metadata.bin\n') - file.write('\n') - file.write(' OV_TABLE : ORIGIN = 0 > arm9_ovt.bin\n') - file.write('\n') - for ov in OVERLAYS: - file.write(f' {ov.name} : ORIGIN = ') - if ov.origin is not None: - file.write(hex(ov.origin)) - elif type(ov.after) is list: - file.write('AFTER(') - file.write(','.join(map(str, ov.after))) - file.write(')') - else: - file.write(f'AFTER({str(ov.after)})') - - file.write(f' > overlays/{ov.name}.bin\n') - file.write('\n') - file.write(' HEAP : ORIGIN = AFTER(ARM9,') - file.write(','.join(map(str, OVERLAYS))) - file.write(')\n') - file.write('}\n') - file.write('\n') - file.write('SECTIONS {\n') - file.write(' .arm9 : {\n') - file.write(' gHeap = ADDR(HEAP);\n') - file.write(' . = ALIGN(32);\n') - for obj in ARM9_OBJECTS: file.write(f' {name(obj)}.o(.text)\n') - for obj in ARM9_OBJECTS: file.write(f' {name(obj)}.o(.init)\n') - for obj in ARM9_OBJECTS: file.write(f' {name(obj)}.o(.rodata)\n') - for obj in ARM9_OBJECTS: file.write(f' {name(obj)}.o(.ctor)\n') - file.write(' . = ALIGN(32);\n') - for obj in ARM9_OBJECTS: file.write(f' {name(obj)}.o(.data)\n') - file.write(' . = ALIGN(32);\n') - file.write(' arm9_bss_start = .;\n') - for obj in ARM9_OBJECTS: file.write(f' {name(obj)}.o(.bss)\n') - for obj in ARM9_OBJECTS: file.write(f' {name(obj)}.o(.sbss)\n') - file.write(' . = ALIGN(32);\n') - file.write(' arm9_bss_end = .;\n') - file.write(' . = ALIGN(32);\n') - file.write(' } > ARM9\n') - file.write('\n') - file.write(' .itcm : {\n') - file.write(' . = ALIGN(32);\n') - file.write(' itcm_start = .;\n') - for obj in ITCM_OBJECTS: file.write(f' {name(obj)}.o(.text)\n') - for obj in ITCM_OBJECTS: file.write(f' {name(obj)}.o(.rodata)\n') - file.write(' itcm_end = .;\n') - file.write(' itcm_size = itcm_end - itcm_start;\n') - file.write(' . = ALIGN(32);\n') - for obj in ITCM_OBJECTS: file.write(f' {name(obj)}.o(.bss)\n') - for obj in ITCM_OBJECTS: file.write(f' {name(obj)}.o(.sbss)\n') - file.write(' . = ALIGN(32);\n') - file.write(' } > ITCM\n') - file.write('\n') - file.write(' .dtcm : {\n') - file.write(' . = ALIGN(32);\n') - file.write(' dtcm_start = .;\n') - for obj in DTCM_OBJECTS: file.write(f' {name(obj)}.o(.data)\n') - file.write(' dtcm_end = .;\n') - file.write(' dtcm_size = dtcm_end - dtcm_start;\n') - file.write(' . = ALIGN(32);\n') - file.write(' dtcm_end = .;\n') - file.write(' dtcm_aligned_size = dtcm_end - dtcm_start;\n') - file.write(' . = ALIGN(32);\n') - for obj in DTCM_OBJECTS: file.write(f' {name(obj)}.o(.bss)\n') - for obj in DTCM_OBJECTS: file.write(f' {name(obj)}.o(.sbss)\n') - file.write(' . = ALIGN(32);\n') - file.write(' } > DTCM\n') - file.write('\n') - file.write(' .autoloads : {\n') - file.write(' autoloads_start = arm9_bss_start + itcm_size + dtcm_size;\n') - file.write(' WRITEW ADDR(ITCM); WRITEW itcm_size; WRITEW 0;\n') - file.write(' WRITEW ADDR(DTCM); WRITEW dtcm_size; WRITEW 0xec0;\n') - file.write(' autoloads_end = . + autoloads_start;\n') - file.write(' } > AUTOLOADS\n') - file.write('\n') - file.write(' .footer : {\n') - file.write(' WRITEW 0xdec00621;\n') - file.write(' WRITEW spAutoloadBlockInfosStart - ADDR(ARM9);\n') - file.write(' WRITEW 0;\n') - file.write(' } > FOOTER\n') - file.write('\n') - file.write(' .metadata : {\n') - file.write(' WRITEW AutoloadDoneCallback;\n') - file.write(' WRITEW spAutoloadBlockInfosStart - ADDR(ARM9);\n') - file.write(' WRITEW Entry;\n') - file.write(' WRITEW ADDR(ARM9);\n') - file.write(' WRITEW autoloads_start;\n') - file.write(' WRITEW autoloads_end;\n') - file.write(' WRITEW arm9_bss_start;\n') - file.write(' WRITEW arm9_bss_start;\n') - file.write(' WRITEW arm9_bss_end;\n') - file.write(' } > METADATA\n') - file.write('\n') - for ov in OVERLAYS: - file.write(f' .{ov.name} : ' + '{\n') - file.write(' . = ALIGN(32);\n') - file.write(f' {ov.name}_start = .;\n') - for obj in ov.objects: file.write(f' {name(obj)}.o(.text)\n') - for obj in ov.objects: file.write(f' {name(obj)}.o(.rodata)\n') - for obj in ov.objects: file.write(f' {name(obj)}.o(.init)\n') - file.write('\n') - file.write(f' {ov.name}_sinit_start = .;\n') - for obj in ov.objects: file.write(f' {name(obj)}.o(.ctor)\n') - file.write(' WRITEW 0;\n') - file.write(f' {ov.name}_sinit_end = .;\n') - file.write('\n') - file.write(' . = ALIGN(32);\n') - for obj in ov.objects: file.write(f' {name(obj)}.o(.data)\n') - file.write('\n') - file.write(' . = ALIGN(32);\n') - file.write(f' {ov.name}_end = .;\n') - file.write(f' {ov.name}_size = {ov.name}_end - {ov.name}_start;\n') - file.write('\n') - file.write(f' {ov.name}_bss_start = .;\n') - for obj in ov.objects: file.write(f' {name(obj)}.o(.bss)\n') - for obj in ov.objects: file.write(f' {name(obj)}.o(.sbss)\n') - file.write(f' {ov.name}_bss_end = .;\n') - file.write(f' {ov.name}_bss_size = {ov.name}_bss_end - {ov.name}_bss_start;\n') - file.write(' . = ALIGN(32);\n') - file.write(' } > ' + ov.name + '\n') - file.write('\n') - file.write(' .arm9_ovt : {\n') - for (index, ov) in enumerate(OVERLAYS): - file.write(' ') - file.write(f'WRITEW {index}; ') - file.write(f'WRITEW {ov.name}_start; ') - file.write(f'WRITEW {ov.name}_size; ') - file.write(f'WRITEW {ov.name}_bss_size; ') - file.write(f'WRITEW {ov.name}_sinit_start; ') - file.write(f'WRITEW {ov.name}_sinit_end; ') - file.write('WRITEW 0; ') # file id will be inserted later - file.write('WRITEW 0; ') # compression flags, overlay is compressed later - file.write('\n') - file.write(' } > OV_TABLE\n') - file.write('\n') - file.write(' .heap : {\n') - file.write(' gHeap = .;\n') - file.write(' } > HEAP\n') - file.write('}\n') - -with open(f'{BUILD}arm9_objects.txt', 'w') as file: - for obj in ARM9_OBJECTS: file.write(f'{obj}.o\n') - for obj in ITCM_OBJECTS: file.write(f'{obj}.o\n') - for obj in DTCM_OBJECTS: file.write(f'{obj}.o\n') - file.write('\n') - for ov in OVERLAYS: - file.write(f'-og {ov.name},0 -ol {ov.name}\n') - for obj in ov.objects: file.write(f' {obj}.o\n') - file.write('\n') diff --git a/tools/objdiff.py b/tools/objdiff.py deleted file mode 100644 index 16078798..00000000 --- a/tools/objdiff.py +++ /dev/null @@ -1,88 +0,0 @@ -import argparse -from pathlib import Path -import os -import json - -parser = argparse.ArgumentParser(description='Generates objdiff.json for configuring objdiff') -parser.add_argument('region', help='Game region, defaults to EUR', default='EUR') - -args = parser.parse_args() - -tools_dir = Path(os.path.dirname(os.path.realpath(__file__))) -root_dir = tools_dir.parent -config_path = root_dir / 'objdiff.json' -src_dir = root_dir / 'src' -asm_dir = root_dir / 'asm' - - -def find_asm_path(src_path: Path) -> Path | None: - first_dir = src_path.parents[-2] - subdirs = src_path.relative_to(first_dir) - if first_dir.name == 'Main': - asm_dir = 'main' - elif first_dir.name == 'ITCM': - asm_dir = 'itcm' - elif first_dir.name == 'DTCM': - asm_dir = 'dtcm' - else: - try: ov_num = int(first_dir.name[:2], 10) - except: return None - asm_dir = f'ov{ov_num:02d}' - - file_name, _ = src_path.name.rsplit('.', 1) - asm_file = file_name + '.s' - asm_path: Path = asm_dir / subdirs.parent / asm_file - return asm_path - - -def get_build_path(path: Path, extension='.o') -> Path: - region = args.region.lower() - return Path('build') / region / path.parent / (path.name + extension) - - -config = dict() -config["custom_make"] = "make" -config["custom_args"] = [ - "-B", - f"REGION={args.region}" -] -config["build_target"] = True -config["watch_patterns"] = [ - "*.c", - "*.cpp", - "*.h", - "*.hpp", - "*.s" -] -config["objects"] = [] - -for (root, dirs, files) in os.walk(src_dir): - for file in files: - if not file.endswith('.cpp') and not file.endswith('.c'): continue - src_path = Path(f'{root}/{file}') - src_path = src_path.relative_to(src_dir) - asm_path = find_asm_path(src_path) - src_path = 'src' / src_path - - if asm_path: asm_path = 'asm' / asm_path - - name, _ = str(src_path).rsplit('.', 1) - - obj = dict() - obj["name"] = name - if asm_path.exists(): obj["target_path"] = str(get_build_path(asm_path)) - obj["base_path"] = str(get_build_path(src_path)) - obj["reverse_fn_order"] = False - - scratch = dict() - scratch["platform"] = "nds_arm9" - scratch["compiler"] = "mwcc_30_131" - scratch["ctx_path"] = str(get_build_path(src_path, '.ctx')) - scratch["build_ctx"] = True - - obj["scratch"] = scratch - - config["objects"].append(obj) - -with open(config_path, 'w') as f: - f.write(json.dumps(config, indent=4)) diff --git a/tools/patch_mwcc.py b/tools/patch_mwcc.py deleted file mode 100644 index 199030d7..00000000 --- a/tools/patch_mwcc.py +++ /dev/null @@ -1,51 +0,0 @@ -import hashlib -import sys - -class Patch: - def __init__(self, name: str, version: str, sha1: str, desc: str, offset: int, write: list[int]) -> None: - self.name = name - self.version = version - self.sha1 = sha1 - self.desc = desc - self.offset = offset - self.write = write - -VERSION = '1.0' -PATCHES = [ - Patch( - 'mwasmarm', '2.0/sp1p5', '448cb0c7f1ace4393e9a9562f819f7a9f049be83', - 'Fix 2-aligned Thumb BLX where ARM call target was off by 1', - offset=0x1b45b, write=[0xc2] - ), -] - -if len(sys.argv) != 2: - print(f'patch_mwcc {VERSION}') - print() - print(f'Usage: {sys.argv[0]} ') - print(' \tPath to mwasmarm.exe') - exit() - -filename = sys.argv[1] - -with open(filename, 'rb', buffering=0) as file: - sha1 = hashlib.file_digest(file, 'sha1').hexdigest() - file.seek(0, 2) - length = file.tell() - file.seek(0, 0) - file_bytes = bytearray(file.read(length)) - -num_patches = 0 -for patch in PATCHES: - if sha1 == patch.sha1: - num_patches += 1 - print(f'{patch.name} version {patch.version}') - print(patch.desc) - for i in range(len(patch.write)): - file_bytes[patch.offset + i] = patch.write[i] - print() - -with open(filename, 'wb') as file: - file.write(file_bytes) - -print(f'Applied {num_patches} patch(es)') diff --git a/tools/rename_symbols.py b/tools/rename_symbols.py deleted file mode 100644 index c5f4a3a2..00000000 --- a/tools/rename_symbols.py +++ /dev/null @@ -1,65 +0,0 @@ -import sys -import os -from pathlib import Path - -tools_dir = Path(os.path.dirname(os.path.realpath(__file__))) -root_dir = tools_dir.parent -asm_dir = root_dir / 'asm' - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - -def read_lines() -> list[str]: - lines: list[str] = [] - while True: - line = sys.stdin.readline().strip() - if len(line) == 0: break - lines.append(line) - return lines - -eprint("Paste the current symbol names (empty line moves on to the next step):") -current_names = read_lines() - -eprint("Paste the new symbol names:") -new_names = read_lines() - -if len(current_names) != len(new_names): - eprint("Error: number of names must match") - eprint(f"Received {len(current_names)} current name(s)") - eprint(f"Received {len(new_names)} new name(s)") - exit(1) - -symbols_to_rename = {current: new for (current, new) in zip(current_names, new_names)} -files_updated = 0 -lines_updated = 0 - -def rename_in_file(file: Path): - global files_updated, lines_updated - with open(file, 'r') as f: - contents = f.read() - has_symbol = any(contents.find(symbol) >= 0 for symbol in symbols_to_rename.keys()) - if not has_symbol: return - print(f'{file}:') - lines = contents.splitlines() - for i in range(len(lines)): - for current, new in symbols_to_rename.items(): - if lines[i].find(current) < 0: continue - lines[i] = lines[i].replace(current, new) - print(f'\t{i + 1}: {lines[i]}') - lines_updated += 1 - print() - files_updated += 1 - with open(file, 'w') as f: - for line in lines: - f.write(line) - f.write('\n') - - -for (root, dirs, files) in os.walk(asm_dir): - for file in files: - if not file.endswith('.s') and not file.endswith('.inc'): continue - path = Path(f'{root}/{file}') - path = path.relative_to(root_dir) - rename_in_file(path) - -print(f'Updated {lines_updated} line(s) in {files_updated} file(s)')