From 4e1b891fc6ec25bafaed53d5e79799fad1e6bb29 Mon Sep 17 00:00:00 2001 From: James Dansereau <106631954+jkdansereau@users.noreply.github.com> Date: Fri, 28 Aug 2026 08:30:56 -0400 Subject: [PATCH] D88.1/D88.3: SetupIntroCamera narrow-pointer ABI + pccg wiring - bondtypes.h: SetupIntroCamera lang1c/lang20/prev kept u32 under #ifdef PORT so sizeof stays 40 and the fixed-stride intro-record walk in bondview_r.c/bondview2.c still matches 40-byte file records. Fields are write-before-read (bondview_r.c:276-300 writes all three before any read via langGet()/list-link), verified. Same class as D79/D53.1. - bondview2.c/bondview_r.c: cast (char *)(uintptr_t) at each use site. - pccg.c: PCCG_MAX_FILES 128 -> 256 to also hold the Usetup*Z rows. --- port/src/pccg.c | 2 +- src/bondtypes.h | 25 +++++++++++++++++++++++++ src/game/bondview2.c | 16 ++++++++++++++++ src/game/bondview_r.c | 17 +++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/port/src/pccg.c b/port/src/pccg.c index 824f1e52..a126938f 100644 --- a/port/src/pccg.c +++ b/port/src/pccg.c @@ -38,7 +38,7 @@ extern struct fileentry file_resource_table[]; extern resource_lookup_data_entry resource_lookup_data_array[]; extern s32 file_entry_max; -#define PCCG_MAX_FILES 128 +#define PCCG_MAX_FILES 256 /* D88: grown to also hold Usetup*Z rows */ #define PCCG_NAME_LEN 64 struct pccgRow { diff --git a/src/bondtypes.h b/src/bondtypes.h index 7b86b231..d8803cb7 100644 --- a/src/bondtypes.h +++ b/src/bondtypes.h @@ -3929,6 +3929,30 @@ typedef struct SetupIntroCamera fs15_16 unk10; // yaw in radians fs15_16 unk14; // pitch in radians s32 unk18; // pad +#ifdef PORT + /* D88: lang_ptr/prev are ROM-serialized as N64 4-byte pointer-sized + * union members / struct members, but are NEVER read from file data -- + * every use site (bondview_r.c) writes them (via langGet()/list-link) + * before the sole subsequent reads (bondview_r.c/bondview2.c). Widening + * them to real 8-byte PC pointers would grow sizeof(SetupIntroCamera) + * from 40 (0x28) to 56, breaking the intro-record walk's + * `(s32)intro_record + sizeof(SetupIntroCamera)` stride (bondview_r.c/ + * bondview2.c) against the still-40-byte-per-record file data. Kept as + * u32 (same class as D79/D53.1); cast to the real pointer type at each + * use site under #ifdef PORT. No behavior change -- see D88 in + * PCPortResearch.md. */ + union + { + u16 lang_index[2]; + u32 lang_ptr; + } lang1c; + union + { + s32 lang_index; + u32 lang_ptr; + } lang20; + u32 prev; +#else union { u16 lang_index[2]; @@ -3940,6 +3964,7 @@ typedef struct SetupIntroCamera char *lang_ptr; } lang20; struct SetupIntroCamera *prev; +#endif } SetupIntroCamera; /** diff --git a/src/game/bondview2.c b/src/game/bondview2.c index c289bb89..ae031fcc 100644 --- a/src/game/bondview2.c +++ b/src/game/bondview2.c @@ -1208,9 +1208,17 @@ void bondviewFrozenCameraTick(u16 buttons, u16 oldbuttons, struct coord3d *pos, { #if defined(VERSION_US) setFontTables(ptrFontZurichBoldChars, ptrFontZurichBold); +#ifdef PORT + hudmsgBottomShow((char *)(uintptr_t)ptr_random06cam_entry->lang1c.lang_ptr); +#else hudmsgBottomShow(ptr_random06cam_entry->lang1c.lang_ptr); +#endif +#else +#ifdef PORT + hudmsgBottomShow((char *)(uintptr_t)ptr_random06cam_entry->lang1c.lang_ptr, ptrFontZurichBoldChars, ptrFontZurichBold); #else hudmsgBottomShow(ptr_random06cam_entry->lang1c.lang_ptr, ptrFontZurichBoldChars, ptrFontZurichBold); +#endif #endif } @@ -1219,9 +1227,17 @@ void bondviewFrozenCameraTick(u16 buttons, u16 oldbuttons, struct coord3d *pos, if ((camera_transition_timer < 300.0f) && ((camera_transition_timer + g_GlobalTimerDelta) >= 300.0f)) { #if defined(VERSION_US) +#ifdef PORT + hudmsgBottomShow((char *)(uintptr_t)ptr_random06cam_entry->lang20.lang_ptr); +#else hudmsgBottomShow(ptr_random06cam_entry->lang20.lang_ptr); +#endif +#else +#ifdef PORT + hudmsgBottomShow((char *)(uintptr_t)ptr_random06cam_entry->lang20.lang_ptr, ptrFontZurichBoldChars, ptrFontZurichBold); #else hudmsgBottomShow(ptr_random06cam_entry->lang20.lang_ptr, ptrFontZurichBoldChars, ptrFontZurichBold); +#endif #endif } diff --git a/src/game/bondview_r.c b/src/game/bondview_r.c index 48cd0243..8e2ad3f0 100644 --- a/src/game/bondview_r.c +++ b/src/game/bondview_r.c @@ -276,7 +276,12 @@ void bondviewLoadSetupIntroSection(void) { if (get_cur_playernum() == 0) { +#ifdef PORT + /* D88: prev/lang_ptr are u32 on PORT (see SetupIntroCamera). */ + ((struct SetupIntroCamera*)intro_record)->prev = (u32)(uintptr_t)g_CurrentSetupIntroCamera; +#else ((struct SetupIntroCamera*)intro_record)->prev = g_CurrentSetupIntroCamera; +#endif g_CurrentSetupIntroCamera = (struct SetupIntroCamera*)intro_record; g_SetupIntroCameraCount = g_SetupIntroCameraCount + 1; @@ -286,11 +291,19 @@ void bondviewLoadSetupIntroSection(void) ((struct SetupIntroCamera*)intro_record)->unk10.fval = ((struct SetupIntroCamera*)intro_record)->unk10.ival / M_U16_MAX_VALUE_F; ((struct SetupIntroCamera*)intro_record)->unk14.fval = ((struct SetupIntroCamera*)intro_record)->unk14.ival / M_U16_MAX_VALUE_F; +#ifdef PORT + ((struct SetupIntroCamera*)intro_record)->lang1c.lang_ptr = (u32)(uintptr_t)langGet(((struct SetupIntroCamera*)intro_record)->lang1c.lang_index[1]); +#else ((struct SetupIntroCamera*)intro_record)->lang1c.lang_ptr = langGet(((struct SetupIntroCamera*)intro_record)->lang1c.lang_index[1]); +#endif if (((struct SetupIntroCamera*)intro_record)->lang20.lang_index != 0) { +#ifdef PORT + ((struct SetupIntroCamera*)intro_record)->lang20.lang_ptr = (u32)(uintptr_t)langGet((u16)((struct SetupIntroCamera*)intro_record)->lang20.lang_index); +#else ((struct SetupIntroCamera*)intro_record)->lang20.lang_ptr = langGet((u16)((struct SetupIntroCamera*)intro_record)->lang20.lang_index); +#endif } } @@ -358,7 +371,11 @@ void bondviewLoadSetupIntroSection(void) while (rand_camera_index > 0) { rand_camera_index--; +#ifdef PORT + ptr_random06cam_entry = (struct SetupIntroCamera *)(uintptr_t)ptr_random06cam_entry->prev; +#else ptr_random06cam_entry = ptr_random06cam_entry->prev; +#endif } }