mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 05:32:07 -04:00
62 lines
3.1 KiB
Python
62 lines
3.1 KiB
Python
"""Generate LeafGreen 1.0 address metadata from matching pret ELF builds."""
|
|
import subprocess,bisect,re,sys,hashlib
|
|
from pathlib import Path
|
|
B=0x8000000
|
|
def symbols(path):
|
|
out=[]; obj=''
|
|
for line in subprocess.check_output(['arm-none-eabi-readelf','-sW',str(path)],text=True).splitlines():
|
|
p=line.split()
|
|
if len(p)<8 or not p[0][:-1].isdigit():continue
|
|
_,v,size,typ,bind,vis,ndx,name=p[:8]
|
|
if typ=='FILE':obj=name;continue
|
|
a=int(v,16)
|
|
if typ not in ('SECTION','FILE') and not name.startswith(('$','.')) and B<=a<B+0x1000000:
|
|
# Function symbols carry Thumb bit; anchor their actual first byte.
|
|
out.append((a&~1 if typ=='FUNC' else a, (obj if bind=='LOCAL' else '',name),int(size)))
|
|
return sorted(out)
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
pret = Path(sys.argv[1] if len(sys.argv) > 1 else ROOT.parent / "pokefirered")
|
|
for filename, expected in {
|
|
"pokefirered": "41cb23d8dccc8ebd7c649cd8fbb58eeace6e2fdc",
|
|
"pokeleafgreen": "574fa542ffebb14be69902d1d36f1ec0a4afd71e",
|
|
}.items():
|
|
digest = hashlib.sha1((pret / (filename + ".gba")).read_bytes()).hexdigest()
|
|
if digest != expected:
|
|
raise SystemExit(f"{filename} is not the matching USA 1.0 build")
|
|
a = symbols(pret / "pokefirered.elf")
|
|
b = symbols(pret / "pokeleafgreen.elf")
|
|
bd = {name: (addr, size) for addr, name, size in b}
|
|
starts = [row[0] for row in a]
|
|
aliases = {"sFlames_Pal": "sLeaves_Pal", "sFlames_Gfx": "sLeaves_Gfx", "sBlankFlames_Gfx": "sStreak_Gfx"}
|
|
# Only literal ROM addresses; comments, strings, masks and sizes are excluded.
|
|
files = [ROOT / "src/import/gba/versions.lua", ROOT / "src/import/gba/versions_text.lua"]
|
|
files += [ROOT / ("src/import/gba/" + f + ".lua") for f in (
|
|
"tileset_anim_pack", "battle_chrome_extract", "pokedex_chrome_extract",
|
|
"seagallop_extract", "door_anim_extract", "text_chrome_extract",
|
|
"help_extract", "quest_log_extract", "object_interactions_extract",
|
|
"weather_extract")]
|
|
values = set()
|
|
for path in files:
|
|
for line in path.read_text().splitlines():
|
|
line = re.sub(r'"[^"\n]*"|\'[^\'\n]*\'', "", line.split("--")[0])
|
|
for literal in re.findall(r"0x[0-9A-Fa-f]+", line):
|
|
v = int(literal, 16)
|
|
if 0x10000 <= v < 0x1000000 or B < v < B + 0x1000000:
|
|
values.add(v)
|
|
lines = ["-- Generated by tools/gen_leafgreen_profile.py from matching pret ELF symbols.", "-- Addresses only; no ROM content. Local symbols are qualified by object file.", "return {"]
|
|
for value in sorted(values):
|
|
addr = value + B if value < B else value
|
|
start, key, size = a[bisect.bisect_right(starts, addr) - 1]
|
|
target = (key[0], aliases.get(key[1], key[1]))
|
|
if target not in bd:
|
|
raise SystemExit(f"Unmapped {value:#x}: {key}")
|
|
offset = addr - start
|
|
mapped = bd[target][0] + offset - (B if value < B else 0)
|
|
lines.append(f" [0x{value:X}] = 0x{mapped:X}, -- {key[0]}:{target[1]} + {offset}")
|
|
lines.append("}")
|
|
out = ROOT / "src/import/gba/editions/leafgreen_1_0.lua"
|
|
out.parent.mkdir(parents=True, exist_ok=True)
|
|
out.write_text("\n".join(lines) + "\n")
|
|
print(f"Wrote {len(values)} address mappings to {out}")
|