Remove redundant Python scripts

This commit is contained in:
Aetias
2024-09-10 20:19:12 +02:00
parent fb63b9271d
commit a1fdc1b546
5 changed files with 0 additions and 771 deletions
-132
View File
@@ -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)")
-435
View File
@@ -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')
-88
View File
@@ -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))
-51
View File
@@ -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]} <exe>')
print(' <exe>\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)')
-65
View File
@@ -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)')