mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-29 23:24:32 -04:00
feat(main): split src/800.c at the jtbl-span TU boundaries — spans B and C now carve
BYTE-IDENTICAL with NO function banked (gate_main --assert-baseline, clean rebuild), which is the whole point: the structure lands first and proves neutral, then drafts bank against it. One code object contributes exactly ONE contiguous .rodata run, and 800.o's is span A, so spans B and C each needed their own object: 800 vram 0x800123F0-0x8002B0B4 -> .rodata span A (0x80072A38-0x80072C70) 800_b vram 0x8002B0B4-0x80035270 -> .rodata span B (0x80072E44-0x80073140) 800_c vram 0x80035270-0x8003A444 -> .rodata span C (0x800732A0-0x8007344C) The span owners' address ranges are disjoint and ordered — tables pack tight WITHIN a TU and are separated by other data ACROSS TUs — so these are (at least some of) the original translation-unit boundaries. Splitting here is both the fix and the minimum; any extra split would be speculation. main's island is now a 7-piece data->rodata sandwich, so ld_interleave moves from --front/--tail to --order. THE SPLIT WAS CHEAP, AND MY FIRST ESTIMATE WAS WRONG. I costed it at '2,318 scattered extern lines' — that is the TOTAL; what matters is how many CROSS a boundary, and that is 57 of 1,247 declared names (4.6%), of which 19 are typedefs with exactly one definition each and zero shape conflicts. Zero file-local statics. src/800_shared.h carries exactly those, derived from the COMPILER's own errors rather than a regex model of C (R33), and each typedef was MOVED, never copied. Unlocks 17 functions / 4,471 instructions = 39% of what is left in main, incl. SaveLoadRoutine (1139) and func_8003388C (663).
This commit is contained in:
@@ -659,7 +659,11 @@ ifeq ($(BINARY),main)
|
||||
# 6324C.data. Idempotent; keyed off splat's exact output (re-run = no-op).
|
||||
# EXE-only (overlays have no rodata island) — gated to BINARY=main; --front/--tail
|
||||
# name the sandwich .data objects (cookbook §8).
|
||||
$(PYTHON) tools/ld_interleave.py --front 53198.data.o --tail 63470.data.o $(LD_SCRIPT)
|
||||
# P31 S72: main's island is now a 7-PIECE sandwich (three .rodata carves, one per
|
||||
# jtbl-span-owning code object), so --front/--tail can no longer express it. --order
|
||||
# takes the address-ordered leaf list: a *.data.o leaf contributes its (.data), a code
|
||||
# object leaf contributes its (.rodata) carve.
|
||||
$(PYTHON) tools/ld_interleave.py --order 53198.data.o,800.o,63470.data.o,800_b.o,63940.data.o,800_c.o,63C4C.data.o $(LD_SCRIPT)
|
||||
endif
|
||||
# Phase-26 §8: overlays that carve a jr-function's jtbl into a dotted .rodata subseg run
|
||||
# ld_interleave to place the migrated .rodata between the pre/post data-tail chunks (the
|
||||
|
||||
@@ -76,7 +76,16 @@ segments:
|
||||
# INCLUDE_ASM (Phase-7 regression gate) — opt level only affects matched C, not stubs.
|
||||
# Boundary = func_800123F0 (vram 0x800123F0 -> file vram-0x8000F800 = 0x2BF0).
|
||||
- [0x800, c, boot] # -O0 boot module -> src/boot.c (vram 0x80010000-0x800123F0)
|
||||
- [0x2BF0, c, 800] # -O2 game code -> src/800.c (vram 0x800123F0-0x8003A444); name "800" kept (legacy) so the matched fns + their asm/nonmatchings/800 paths don't migrate
|
||||
# P31 S72 — SPLIT AT THE JTBL-SPAN TU BOUNDARIES. One code object contributes exactly ONE
|
||||
# contiguous `.rodata` run, so each jump-table span needs its own object. The span owners'
|
||||
# address ranges are DISJOINT AND ORDERED, which is the evidence that these are (at least
|
||||
# some of) the original translation-unit boundaries — tables pack tight WITHIN a TU and are
|
||||
# separated by other data ACROSS TUs (§8e/§426). Splitting here is therefore both the fix
|
||||
# and the minimum: any extra split would be speculation. `800` keeps its legacy name so the
|
||||
# matched fns + their asm/nonmatchings/800 paths don't migrate.
|
||||
- [0x2BF0, c, 800] # -O2 game code -> src/800.c (vram 0x800123F0-0x8002B0B4); owns .rodata span A
|
||||
- [0x1B8B4, c, 800_b] # -O2 game code -> src/800_b.c (vram 0x8002B0B4-0x80035270); owns .rodata span B
|
||||
- [0x25A70, c, 800_c] # -O2 game code -> src/800_c.c (vram 0x80035270-0x8003A444); owns .rodata span C
|
||||
# PsyQ libspu+libsnd COMBINED sound region (Phase 8): the two SDK sound libs are interleaved here,
|
||||
# so they link as one 60-object region (curated by tools/make_snd_used.py; 4 addresses excluded as
|
||||
# scattered-.bss/false-positive stubs: S_R/S_W 0x3C438, S_GRMDT* 0x3D424, S_IH/UT_RON 0x3D94C,
|
||||
@@ -217,6 +226,14 @@ segments:
|
||||
# into .rodata while the raw copy stayed here, so the image GREW (measured +28/+52/+76/+84
|
||||
# on four drafts) and all 238 symbols above 0x80072A4C shifted. 25 of main's 59 frontier
|
||||
# functions (6,215 of 12,912 instructions) are in that class.
|
||||
- [0x63238, .rodata, 800] # LZSS jtbl + the 11 contiguous game jtbls (vram 0x80072A38-0x80072C70)
|
||||
- [0x63470, data, 63470] # tail data: loadDestPtrTable onward (vram 0x80072C70-0x80074800)
|
||||
# The island is data -> rodata -> data -> rodata -> data -> rodata -> data. Each `.rodata`
|
||||
# piece is dotted onto the code subseg that OWNS those tables, so spimdisasm migrates each
|
||||
# table into its referencing function and ld_interleave --order lays the pieces back down in
|
||||
# address order. Span D (0x80073494-0x80073514) belongs to snd2, not to game code.
|
||||
- [0x63238, .rodata, 800] # span A: LZSS jtbl + 11 game jtbls (vram 0x80072A38-0x80072C70)
|
||||
- [0x63470, data, 63470] # loadDestPtrTable + globals (vram 0x80072C70-0x80072E44)
|
||||
- [0x63644, .rodata, 800_b] # span B: 14 game jtbls (vram 0x80072E44-0x80073140)
|
||||
- [0x63940, data, 63940] # globals (vram 0x80073140-0x800732A0)
|
||||
- [0x63AA0, .rodata, 800_c] # span C: 8 game jtbls (vram 0x800732A0-0x8007344C)
|
||||
- [0x63C4C, data, 63C4C] # tail: snd2 jtbls + globals (vram 0x8007344C-0x80074800)
|
||||
- [0x65000]
|
||||
|
||||
+5478
File diff suppressed because it is too large
Load Diff
+2450
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,190 @@
|
||||
#ifndef BFM_800_SHARED_H
|
||||
#define BFM_800_SHARED_H
|
||||
|
||||
/* The include environment the original single TU had. Every TU of the split needs the same
|
||||
* one: `psyq/libcd.h` supplies CdlLOC/CdlFILE to functions now in 800_c.c, and
|
||||
* `shared/clearTbl40.h` supplies the CLEAR_TBL40 dedup macro whose two instantiation sites
|
||||
* ended up in DIFFERENT TUs after the split. Both are guarded, so src/800.c keeping its own
|
||||
* copies is harmless. */
|
||||
#include "psyq/libcd.h"
|
||||
#include "shared/clearTbl40.h"
|
||||
|
||||
/* P31 S72 — the declarations that CROSS the src/800.c -> 800_b.c -> 800_c.c split.
|
||||
*
|
||||
* Measured, not guessed: of 1,247 names declared across the three regions, only 57 are used
|
||||
* outside the region that declares them, and 19 of those are typedefs. Every one had exactly
|
||||
* ONE definition and zero shape conflicts, so this is a partition of the old file, not a
|
||||
* rewrite — each typedef was MOVED here, never copied (a duplicate typedef is a C89 error).
|
||||
* The set was derived from the compiler's own errors, not from a regex model of C (R33).
|
||||
* See cookbook §426 and config/splat.us.exe.yaml for why the split exists at all. */
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct Ent30D80 {
|
||||
/* 0x00 */ s32 unk00;
|
||||
/* 0x04 */ u8 pad04[6];
|
||||
/* 0x0A */ u16 unk0A;
|
||||
/* 0x0C */ u8 pad0C[0x34];
|
||||
/* 0x40 */ void (*unk40)(s32, s32);
|
||||
/* 0x44 */ s32 unk44;
|
||||
/* 0x48 */ u8 pad48[6];
|
||||
/* 0x4E */ u8 unk4E;
|
||||
/* 0x4F */ u8 pad4F;
|
||||
/* 0x50 */ u8 unk50;
|
||||
/* 0x51 */ u8 unk51;
|
||||
} Ent30D80;
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct { u8 v; } W8;
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct Rec14 {
|
||||
/* 0x00 */ u16 unk00;
|
||||
/* 0x02 */ u16 unk02;
|
||||
/* 0x04 */ u32 unk04;
|
||||
/* 0x08 */ u32 unk08;
|
||||
/* 0x0C */ u16 unk0C;
|
||||
/* 0x0E */ u16 unk0E;
|
||||
/* 0x10 */ u32 unk10;
|
||||
} Rec14; /* 0x14 */
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct Owner4EE8 {
|
||||
/* 0x00 */ u8 pad00[0x14];
|
||||
/* 0x14 */ Rec14 **unk14;
|
||||
} Owner4EE8;
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct Slot {
|
||||
/* 0x00 */ s32 unk00;
|
||||
/* 0x04 */ s32 unk04;
|
||||
/* 0x08 */ u8 unk08[0xC];
|
||||
/* 0x14 */ s16 unk14;
|
||||
/* 0x16 */ u8 unk16[2];
|
||||
/* 0x18 */ s16 unk18;
|
||||
/* 0x1A */ u8 unk1A[0x26];
|
||||
/* 0x40 */ s32 unk40;
|
||||
/* 0x44 */ u8 unk44;
|
||||
/* 0x45 */ u8 unk45[3];
|
||||
} Slot;
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct {
|
||||
s16 unk00;
|
||||
s16 unk02;
|
||||
s16 unk04;
|
||||
s16 unk06;
|
||||
s16 unk08;
|
||||
s16 unk0A;
|
||||
s16 unk0C;
|
||||
s16 unk0E;
|
||||
u8 unk10;
|
||||
u8 unk11;
|
||||
u8 unk12;
|
||||
u8 unk13;
|
||||
s32 unk14;
|
||||
} Rsc24; /* 0x18 */
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct {
|
||||
/* 0x00 */ u8 *unk00;
|
||||
/* 0x04 */ u8 pad04[2];
|
||||
/* 0x06 */ u8 unk06;
|
||||
/* 0x07 */ u8 unk07;
|
||||
/* 0x08 */ u8 unk08;
|
||||
/* 0x09 */ u8 pad09[3];
|
||||
} A12; /* 0x0C */
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct {
|
||||
/* 0x00 */ s32 unk00;
|
||||
/* 0x04 */ s16 unk04;
|
||||
/* 0x06 */ s16 unk06;
|
||||
/* 0x08 */ s16 unk08;
|
||||
/* 0x0A */ u8 unk0A;
|
||||
/* 0x0B */ u8 unk0B;
|
||||
} B12; /* 0x0C */
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct {
|
||||
/* 0x00 */ u8 pad00[4];
|
||||
/* 0x04 */ u8 unk04;
|
||||
/* 0x05 */ u8 pad05[11];
|
||||
/* 0x10 */ u16 unk10;
|
||||
/* 0x12 */ u16 unk12;
|
||||
/* 0x14 */ u8 pad14[2];
|
||||
/* 0x16 */ s16 unk16;
|
||||
/* 0x18 */ u8 pad18[8];
|
||||
} C24; /* 0x20 */
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct { /* 0x18 stride; D_800A463C + k*0x18 */
|
||||
s32 unk00;
|
||||
u8 unk04[0x14];
|
||||
} Ent24;
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct { /* base 0x80064D49, stride 0x0C */
|
||||
u8 unk00;
|
||||
u8 pad[11];
|
||||
} Elm12;
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct { /* base 0x80076240, stride 0x10 */
|
||||
u16 unk00;
|
||||
u16 unk02;
|
||||
s32 unk04;
|
||||
s32 unk08;
|
||||
s32 unk0C;
|
||||
} Slot16A;
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct {
|
||||
s32 unk00;
|
||||
s32 unk04;
|
||||
s32 unk08;
|
||||
u8 unk0C;
|
||||
u8 unk0D;
|
||||
u8 unk0E;
|
||||
u8 unk0F;
|
||||
} Slot16; /* 0x10 */
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct { s32 v; } W32;
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct Slot54 {
|
||||
/* 0x00 */ s16 unk00;
|
||||
/* 0x02 */ s16 unk02;
|
||||
/* 0x04 */ s16 unk04;
|
||||
/* 0x06 */ s16 unk06;
|
||||
/* 0x08 */ u16 unk08;
|
||||
/* 0x0A */ s8 unk0A;
|
||||
} Slot54;
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct { u16 f0; } H2; /* 0x2 */
|
||||
|
||||
/* was: src/800.c */
|
||||
typedef struct {
|
||||
s32 unk00;
|
||||
u8 unk04;
|
||||
u8 unk05;
|
||||
u8 unk06;
|
||||
u8 unk07;
|
||||
u8 unk08;
|
||||
u8 unk09;
|
||||
u8 unk0A;
|
||||
u8 unk0B;
|
||||
s32 unk0C;
|
||||
} Rsc16; /* 0x10 */
|
||||
|
||||
/* was: src/800_c.c */
|
||||
typedef struct { s16 v; } W16;
|
||||
|
||||
/* was: src/800_c.c */
|
||||
typedef struct {
|
||||
u8 unk00;
|
||||
u8 unk01[11];
|
||||
} Rsc12; /* 0x0C */
|
||||
|
||||
#endif /* BFM_800_SHARED_H */
|
||||
Reference in New Issue
Block a user