mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
02f060f607
800c3 (0x8005CE18-0x8005FC68, one contiguous run of 33 interleaved Sony objects) is now four
stub rows — libapi1 (21 BIOS trampolines + COUNTER), libpad1 (PADENTRY + PADMAIN 760), libapi2
(L02/L03), libpad2 (PADCMD PADIF PADPORTD PADSEQD WAITRC2) — fed by two WINDOWED psyq_integrate
calls from the raw .run/obj42/{libapi42,libpad421} dirs (integrate tiles each stub with one
library; every boundary checked against .text SECTION sizes). The apicard region's three
"game code" rows were libapi 4.2's C objects to the byte: 800c2 = FIRST.o (firstfile + the
"no jump table wall" stub func_80062144), 800c2_2 = PAD.o, 800c2_3 = PATCH.o + CHCLRPAD.o ->
apicard5/6/7; make_apicard_used.py sources libapi from 4.2 (the EXE's real libapi; libcard
stays 4.0) into .run/obj42/apicard_used, 26 objects / 7 blocks, no game code left in
0x80061F38-0x80062888. src/800c3.c (129 hand-matched "C", 62 verbatim bodies, 19 stubs incl.
the four §332 %lo-in-a-delay-slot "walls"), src/800c2.c, src/800c2_2.c, src/800c2_3.c removed;
REORDER_TUS is empty (mechanism kept). Cookbook §490.
Two stale instruments fixed: exclude_audit let a pinned WALL outrank LINKED (PopMatrix/
PushMatrix had sat as walls since S68 while living in libgte3, linked since Phase 8) — LINKED
dominates now, config/wave_exclude.txt 13 -> 3; frontier_classify carried a hard-coded 49-name
LINKED set (R51) and reported 337 "stubs" — derived from the Makefile now.
Verified: main 143dbb89f34491258bbc27810d0a12ec8b43a8dd WITH all SDK dirs and WITHOUT them from
a fresh extract; make tools-health OK; R22 fleet extract-all 212/212 + check-all 213/213.
Metrics: main REAL 839->773, LINKED 1,150->1,256, VERBATIM 29->3, stubs 29->16, byte-identical
2,075/2,091 = 99.2%; game-code weighted 93.3% (38,748/41,534), remainder 2,786 = the open-stub
sum; fleet stubs 51->38 (frontier_classify: 39 rows incl. the data word). Verbatim manifest
33 -> 6. Docs: worklist rows + "S79 task #5", SETUP (fresh-clone obj42 commands, Makefile
blocks, exclude_audit), decision-log "S79 addendum 2", accelerators "S79 (2)", CURRENT_PHASE
S79 FINAL refreshed (census, metrics, the task #6 brief).
68 lines
3.1 KiB
Python
68 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Build .run/obj42/apicard_used = the combined libapi+libcard objects in the 800c2 region (Phase 8; S79 #5).
|
|
|
|
libapi (BIOS syscall trampolines + the C objects FIRST/PAD/PATCH/CHCLRPAD) and libcard interleave in
|
|
0x80061F38..0x80062888 with one shared object (C112.o, identical in both libs). Linked as one 26-object
|
|
combined region tiling the whole range (apicard1..7). No exclusions — every object byte-matches.
|
|
P31 S79 #5: libapi comes from `.run/obj42/libapi42` — PsyQ LIBAPI.LIB **4.2**, the EXE's real libapi (its 4.2
|
|
`Ps` stamp is C114 at 0x8005CE48; tools/psyq/lib421, cookbook §490) — which also supplies FIRST.o (168 ins,
|
|
`firstfile`, formerly REAL C in 800c2), PAD.o (192, formerly 800c2_2) and PATCH.o + CHCLRPAD.o (formerly
|
|
800c2_3). libcard stays 4.0 (`.run/obj40/libcard`): byte-identical in this region. libapi 4.2's band objects
|
|
(0x8005CE18..0x8005E188) are wired separately by the Makefile's LIBAPI42 call from the raw dir.
|
|
Regenerate: tools/psyq_build_libs.sh LIBCARD + the lib421 ELF step (docs/SETUP.md) first.
|
|
"""
|
|
import os, re, shutil, subprocess, sys
|
|
from collections import defaultdict
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
from psyq_link import link_object # noqa: E402
|
|
|
|
# EXE-curation tool: --exe/--vram-base default to the retail EXE's (threaded into psyq_identify +
|
|
# link_object, which require them post-T8). RLO/RHI are the EXE's 800c2 region (EXE-specific).
|
|
EXE = "extracted/retail/SLUS_007.26"
|
|
VRAM_BASE = 0x8000F800
|
|
RLO, RHI = 0x80061F38, 0x80062888
|
|
|
|
|
|
# object sources: libapi 4.2 (S79 #5) + libcard 4.0 — see the module docstring
|
|
SOURCES = (".run/obj42/libapi42", ".run/obj40/libcard")
|
|
|
|
|
|
def place(lib, exe, vram_base):
|
|
out = subprocess.check_output(["python3", "tools/psyq_identify.py", lib,
|
|
"--vram-base", hex(vram_base), "--exe", exe], text=True)
|
|
return {m.group(2): int(m.group(1), 16)
|
|
for ln in out.splitlines()
|
|
if (m := re.match(r"\s+0x([0-9A-Fa-f]+)\s+(\S+\.o)\s+\((\d+) ins\)", ln))}
|
|
|
|
|
|
def main():
|
|
import argparse
|
|
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
ap.add_argument("--exe", default=EXE)
|
|
ap.add_argument("--vram-base", default=hex(VRAM_BASE))
|
|
args = ap.parse_args()
|
|
exe_path, vram_base = args.exe, int(args.vram_base, 0)
|
|
exe = open(exe_path, "rb").read()
|
|
byaddr = defaultdict(list)
|
|
for lib in SOURCES:
|
|
for nm, a in place(lib, exe_path, vram_base).items():
|
|
byaddr[a].append((lib, nm))
|
|
dst = ".run/obj42/apicard_used"
|
|
shutil.rmtree(dst, ignore_errors=True)
|
|
os.makedirs(dst)
|
|
n = 0
|
|
for a in sorted(byaddr):
|
|
if not (RLO <= a < RHI):
|
|
continue
|
|
lib, nm = next(((l, m) for l, m in byaddr[a]
|
|
if link_object(f"{l}/{m}", a, name=m, exe_bytes=exe,
|
|
vram_base=vram_base)["ok"]),
|
|
byaddr[a][0])
|
|
shutil.copy(f"{lib}/{nm}", f"{dst}/{nm}")
|
|
n += 1
|
|
print(f"apicard_used: {n} objects (libapi 4.2 + libcard 4.0 combined, 800c2 region) -> {dst}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|