mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
D88.4: d88_emit.py --regen flag + PC layout probe for propDef records
--regen drops all Usetup*Z rows (manifest + bytes) and rebuilds the sidecar from the surviving d69 rows before re-converting, for clean converter iteration. d88_layoutprobe.c prints sizeof/offsetof for every propDef record struct against the real port include chain.
This commit is contained in:
1 parent
c09bf37c66
commit
f333a713fd
2 files changed
+144
-15
No files matched your search
+36
-15
@@ -80,8 +80,10 @@ existing sidecar+manifest are present -- it loads and extends them).
|
||||
import csv, struct, zlib, os, re, sys
|
||||
|
||||
REGION = "ntsc-final"
|
||||
if len(sys.argv) > 1 and sys.argv[1] in ("ntsc-final", "pal-final", "jpn-final"):
|
||||
REGION = sys.argv[1]
|
||||
REGEN = "--regen" in sys.argv[1:]
|
||||
for _a in sys.argv[1:]:
|
||||
if _a in ("ntsc-final", "pal-final", "jpn-final"):
|
||||
REGION = _a
|
||||
|
||||
ROM_PATH = f"data/ge007.{REGION}.z64"
|
||||
OUT_DIR = f"data/pccg-{REGION}"
|
||||
@@ -461,19 +463,8 @@ existing_names = set()
|
||||
os.makedirs(OUT_DIR, exist_ok=True)
|
||||
bin_path = os.path.join(OUT_DIR, "pccg.bin")
|
||||
man_path = os.path.join(OUT_DIR, "manifest.csv")
|
||||
if os.path.exists(bin_path) and os.path.exists(man_path):
|
||||
with open(man_path, newline="") as f:
|
||||
r = csv.reader(f)
|
||||
next(r, None)
|
||||
for row in r:
|
||||
if len(row) == 3:
|
||||
manifest.append((row[0], int(row[1]), int(row[2])))
|
||||
existing_names.add(row[0])
|
||||
with open(bin_path, "rb") as f:
|
||||
base = f.read()
|
||||
chunks.append(base)
|
||||
cur_off = len(base)
|
||||
print(f"extending existing sidecar: {len(base)} bytes, {len(manifest)} rows")
|
||||
def is_usetup_row(nm):
|
||||
return nm.startswith("Usetup") and nm.endswith("Z")
|
||||
|
||||
def emit(name, data):
|
||||
global cur_off
|
||||
@@ -485,6 +476,36 @@ def emit(name, data):
|
||||
chunks.append(data)
|
||||
cur_off += len(data)
|
||||
|
||||
if os.path.exists(bin_path) and os.path.exists(man_path):
|
||||
old_rows = []
|
||||
with open(man_path, newline="") as f:
|
||||
r = csv.reader(f)
|
||||
next(r, None)
|
||||
for row in r:
|
||||
if len(row) == 3:
|
||||
old_rows.append((row[0], int(row[1]), int(row[2])))
|
||||
with open(bin_path, "rb") as f:
|
||||
base = f.read()
|
||||
if REGEN:
|
||||
# Drop every Usetup*Z row (manifest entry + its bytes) and rebuild the
|
||||
# sidecar from the surviving d69 rows only, so converter iteration
|
||||
# starts from a clean slate every run. Don't hand-edit manifest.csv.
|
||||
dropped = [nm for (nm, _o, _s) in old_rows if is_usetup_row(nm)]
|
||||
for (nm, o, s) in old_rows:
|
||||
if is_usetup_row(nm):
|
||||
continue
|
||||
emit(nm, base[o:o + s])
|
||||
existing_names.add(nm)
|
||||
print(f"--regen: kept {len(manifest)} d69 rows, dropped "
|
||||
f"{len(dropped)} Usetup*Z rows; sidecar rebuilt to {cur_off} bytes")
|
||||
else:
|
||||
manifest.extend(old_rows)
|
||||
for (nm, _o, _s) in old_rows:
|
||||
existing_names.add(nm)
|
||||
chunks.append(base)
|
||||
cur_off = len(base)
|
||||
print(f"extending existing sidecar: {len(base)} bytes, {len(manifest)} rows")
|
||||
|
||||
n_ok = 0
|
||||
for name in usetup_names:
|
||||
if name in existing_names:
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/* D88.4: compiler-verified PC layout probe for propDef record types.
|
||||
*
|
||||
* Prints sizeof (and key offsets) for every PROPDEF_* record struct the
|
||||
* offline converter (d88_emit.py) must reproduce byte-for-byte, compiled with
|
||||
* the SAME toolchain + include chain + flags as the PC game build. Run:
|
||||
*
|
||||
* export PATH="/c/msys64/mingw64/bin:$PATH"
|
||||
* x86_64-w64-mingw32-gcc -std=gnu11 -DPORT=1 -DPLATFORM_64BIT=1 \
|
||||
* -D_LANGUAGE_C=1 -DVERSION_US -DLANG_US -DREFRESH_NTSC \
|
||||
* -Iport/shim -I. -Iinclude -Iinclude/PR -Isrc -Isrc/game -Isrc/libultra \
|
||||
* -Isrc/libultra/audio -Iport/include -Ibuild-pc/port/include \
|
||||
* -include versioninfo.h \
|
||||
* tools_pc/d88_layoutprobe.c -o build-pc/d88_layoutprobe.exe
|
||||
* ./build-pc/d88_layoutprobe.exe
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <ultra64.h>
|
||||
#include <bondtypes.h>
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||
#endif
|
||||
|
||||
#define P_SZ(t) printf("SZ %-34s %3lu bytes %2lu words\n", #t, \
|
||||
(unsigned long)sizeof(t), (unsigned long)sizeof(t) / 4)
|
||||
#define P_OFF(t, f) printf("OFF %-28s %-16s %3lu\n", #t, #f, \
|
||||
(unsigned long)offsetof(t, f))
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* --- the base header every record embeds --- */
|
||||
P_SZ(PropDefHeaderRecord);
|
||||
P_OFF(PropDefHeaderRecord, extrascale);
|
||||
P_OFF(PropDefHeaderRecord, state);
|
||||
P_OFF(PropDefHeaderRecord, type);
|
||||
|
||||
/* --- ObjectRecord family (PROP/GLASS/ALARM/RACK/HAT/SAFE/GAS/KEY) --- */
|
||||
P_SZ(ObjectRecord);
|
||||
P_OFF(ObjectRecord, obj);
|
||||
P_OFF(ObjectRecord, pad);
|
||||
P_OFF(ObjectRecord, flags);
|
||||
P_OFF(ObjectRecord, flags2);
|
||||
P_OFF(ObjectRecord, prop);
|
||||
P_OFF(ObjectRecord, model);
|
||||
P_OFF(ObjectRecord, mtx);
|
||||
P_OFF(ObjectRecord, runtime_pos);
|
||||
P_OFF(ObjectRecord, runtime_bitflags);
|
||||
P_OFF(ObjectRecord, ptr_allocated_collisiondata_block);
|
||||
P_OFF(ObjectRecord, projectile);
|
||||
P_OFF(ObjectRecord, maxdamage);
|
||||
P_OFF(ObjectRecord, damage);
|
||||
P_OFF(ObjectRecord, shadecol);
|
||||
P_OFF(ObjectRecord, nextcol);
|
||||
|
||||
P_SZ(DoorRecord);
|
||||
P_OFF(DoorRecord, linkedDoorOffset);
|
||||
P_OFF(DoorRecord, maxFrac);
|
||||
P_OFF(DoorRecord, doorFlags);
|
||||
P_OFF(DoorRecord, doorType);
|
||||
P_OFF(DoorRecord, keyflags);
|
||||
P_OFF(DoorRecord, autoCloseFrames);
|
||||
P_OFF(DoorRecord, doorOpenSound);
|
||||
P_OFF(DoorRecord, frac);
|
||||
P_OFF(DoorRecord, openstate);
|
||||
P_OFF(DoorRecord, calculatedopacity);
|
||||
P_OFF(DoorRecord, TintDist);
|
||||
P_OFF(DoorRecord, CullDist);
|
||||
P_OFF(DoorRecord, soundType);
|
||||
P_OFF(DoorRecord, linkedDoor);
|
||||
P_OFF(DoorRecord, unkcc);
|
||||
P_OFF(DoorRecord, bbox);
|
||||
P_OFF(DoorRecord, openedTime);
|
||||
P_OFF(DoorRecord, portalNumber);
|
||||
P_OFF(DoorRecord, openSoundState);
|
||||
P_OFF(DoorRecord, closeSoundState);
|
||||
|
||||
P_SZ(GuardRecord);
|
||||
P_OFF(GuardRecord, chrnum);
|
||||
P_OFF(GuardRecord, PadID);
|
||||
P_OFF(GuardRecord, bitflags);
|
||||
P_OFF(GuardRecord, HeadID);
|
||||
P_OFF(GuardRecord, Data);
|
||||
|
||||
P_SZ(GlobalDoorScaleRecord);
|
||||
P_SZ(KeyRecord);
|
||||
P_OFF(KeyRecord, keyflags);
|
||||
P_SZ(TintedGlassRecord);
|
||||
P_SZ(TagObjectRecord);
|
||||
P_OFF(TagObjectRecord, NextTag);
|
||||
P_OFF(TagObjectRecord, TaggedObject);
|
||||
|
||||
/* --- records whose sizepropdef() arm is a hardcoded literal --- */
|
||||
/* Wrapped so the probe still builds if a type is missing; each line that
|
||||
* fails to compile tells us that type has no PC struct yet. */
|
||||
#define TRY_SZ(t) P_SZ(t)
|
||||
TRY_SZ(CutsceneRecord);
|
||||
TRY_SZ(RenameObjectRecord);
|
||||
TRY_SZ(LockDoorRecord);
|
||||
TRY_SZ(SafeObjectRecord);
|
||||
TRY_SZ(PhotographObjectRecord);
|
||||
TRY_SZ(DestroyObjectRecord);
|
||||
TRY_SZ(CollectObjectRecord);
|
||||
TRY_SZ(DepositObjectRecord);
|
||||
TRY_SZ(NULLObjectRecord);
|
||||
TRY_SZ(CoopyObjectRecord);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user