mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
v0.2.1 hotfix batch: D259 audio silence, D260 wheel direction, D261 watch-nav repeat, D263 script order, D264 watch preview model
User playtest reports against v0.2.0: - D259: geEepromPatchAllCheats left an all-zero fresh save at volume 0 (silence) instead of seeding max volume like fileResetSave would. - D260: swap wheel-up/wheel-down to match the PC wheel-menu's on-screen order (was inverted vs. user expectation). - D261: watch-menu stick-held navigation had no repeat past the smooth-scroll band, so holding W/S or a pegged stick crawled one item per tap; added a bounded auto-repeat. - D263: GE_INPUTSCRIPT stick tokens were applied after the stick was already written out and silently discarded (test-harness fix, kept from the D263 Facility/Ourumov investigation, which itself found no port bug). - D264: watch item-preview ModelRenderData template read across two globals that no longer sit adjacent on PC, zeroing renderdata.flags and gating all geometry emission in the preview's subdraw pass. Claude-Session: https://claude.ai/code/session_01KwZViAFaXua3PKgHHjNgvi
This commit is contained in:
1 parent
b0dc9d1257
commit
ffb786bad8
5 files changed
+121
-11
No files matched your search
@@ -12,6 +12,25 @@
|
|||||||
> missions load and run crash-free, but the known issues below are real;
|
> missions load and run crash-free, but the known issues below are real;
|
||||||
> feedback is very welcome.
|
> feedback is very welcome.
|
||||||
|
|
||||||
|
### What's new since v0.2.0
|
||||||
|
|
||||||
|
Small hotfix batch from user playtest feedback on v0.2.0:
|
||||||
|
|
||||||
|
- **Fixed: `All unlocked` + a fresh save produced silent music/SFX** (D259).
|
||||||
|
A brand-new save now seeds max volume the same way the N64 does, whether
|
||||||
|
or not `All unlocked` is on.
|
||||||
|
- **Mouse wheel weapon cycling now matches the on-screen wheel-menu order**:
|
||||||
|
scroll up = previous weapon, scroll down = next (D260).
|
||||||
|
- **Watch menu: holding a direction now auto-repeats** instead of crawling
|
||||||
|
one item per key press/notch (D261).
|
||||||
|
- **Fixed: the watch menu's item-preview 3D model wasn't rendering** —
|
||||||
|
weapons now show their model when selected on the watch inventory page
|
||||||
|
(D264).
|
||||||
|
- Investigated the Facility report of Ourumov never executing Trevelyan:
|
||||||
|
confirmed it's proximity/line-of-sight-triggered exactly as on the N64
|
||||||
|
(walk toward the room), not a port bug — the full scripted beat, including
|
||||||
|
the execution shot, fires correctly (D263).
|
||||||
|
|
||||||
### What's new since v0.1.0
|
### What's new since v0.1.0
|
||||||
|
|
||||||
- **Drop-in ROM, no tooling**: unpack the bundle, drop your NTSC-U (US) ROM
|
- **Drop-in ROM, no tooling**: unpack the bundle, drop your NTSC-U (US) ROM
|
||||||
@@ -77,6 +96,9 @@
|
|||||||
selected** (e.g. the MSAA value appears both on its own row and again at
|
selected** (e.g. the MSAA value appears both on its own row and again at
|
||||||
the panel bottom); earlier builds showed it as an intermittent 4K-
|
the panel bottom); earlier builds showed it as an intermittent 4K-
|
||||||
fullscreen ghost of the top row.
|
fullscreen ghost of the top row.
|
||||||
|
- **Surface 1: the 2D billboard trees near the start render as a solid wall
|
||||||
|
of tree texture** instead of discrete sprites (D236). Under active
|
||||||
|
investigation; no fix in this release.
|
||||||
- **Steam Deck: one intermittent crash remains**: the v0.1.0-era Facility
|
- **Steam Deck: one intermittent crash remains**: the v0.1.0-era Facility
|
||||||
crash is confirmed fixed on Deck hardware, but a SIGSEGV can occasionally
|
crash is confirmed fixed on Deck hardware, but a SIGSEGV can occasionally
|
||||||
occur during heavy firefights (D255; seen on Bunker and Frigate). The
|
occur during heavy firefights (D255; seen on Bunker and Frigate). The
|
||||||
|
|||||||
+15
-11
@@ -1177,6 +1177,14 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (idx == 0 && scriptIsActive()) {
|
||||||
|
/* D263: apply BEFORE the stick is written out -- scripted stick
|
||||||
|
* tokens (SUP/SDOWN/SLEFT/SRIGHT) used to be discarded. */
|
||||||
|
button = scriptApply(button);
|
||||||
|
sx = scriptCurSX;
|
||||||
|
sy = scriptCurSY;
|
||||||
|
}
|
||||||
|
|
||||||
if (sx > STICK_MAX) sx = STICK_MAX;
|
if (sx > STICK_MAX) sx = STICK_MAX;
|
||||||
if (sx < -STICK_MAX) sx = -STICK_MAX;
|
if (sx < -STICK_MAX) sx = -STICK_MAX;
|
||||||
if (sy > STICK_MAX) sy = STICK_MAX;
|
if (sy > STICK_MAX) sy = STICK_MAX;
|
||||||
@@ -1185,12 +1193,6 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
|||||||
if (stick_x) *stick_x = (signed char)sx;
|
if (stick_x) *stick_x = (signed char)sx;
|
||||||
if (stick_y) *stick_y = (signed char)sy;
|
if (stick_y) *stick_y = (signed char)sy;
|
||||||
|
|
||||||
if (idx == 0 && scriptIsActive()) {
|
|
||||||
button = scriptApply(button);
|
|
||||||
sx = scriptCurSX;
|
|
||||||
sy = scriptCurSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configGetInputLog() && (button || sx || sy)) {
|
if (configGetInputLog() && (button || sx || sy)) {
|
||||||
sysLogPrintf(LOG_NOTE, "GE_INPUTLOG cont%d: btn=%04x stick=(%d,%d)",
|
sysLogPrintf(LOG_NOTE, "GE_INPUTLOG cont%d: btn=%04x stick=(%d,%d)",
|
||||||
idx, button, sx, sy);
|
idx, button, sx, sy);
|
||||||
@@ -1297,11 +1299,13 @@ void inputSuspendForOverlay(void)
|
|||||||
|
|
||||||
void inputPostWheel(int notches)
|
void inputPostWheel(int notches)
|
||||||
{
|
{
|
||||||
/* D223: keep the direction -- up cycles to the next weapon, down to the
|
/* D223: keep the direction. v0.2.1: swapped per user request -- up now
|
||||||
* previous one. A burst of same-direction notches just re-arms the same
|
* cycles to the PREVIOUS weapon, down to the NEXT one (PC convention
|
||||||
* pulse; a direction change mid-sequence restarts it (last wins). */
|
* "scroll down = advance list"). A burst of same-direction notches just
|
||||||
if (notches > 0) { wheelFwd = WHEEL_FWD_POLLS; wheelBack = 0; }
|
* re-arms the same pulse; a direction change mid-sequence restarts it
|
||||||
else if (notches < 0) { wheelBack = 2; wheelFwd = 0; }
|
* (last wins). */
|
||||||
|
if (notches > 0) { wheelBack = 2; wheelFwd = 0; }
|
||||||
|
else if (notches < 0) { wheelFwd = WHEEL_FWD_POLLS; wheelBack = 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from the host event pump on SDL_CONTROLLERDEVICEADDED/REMOVED.
|
/* Called from the host event pump on SDL_CONTROLLERDEVICEADDED/REMOVED.
|
||||||
|
|||||||
@@ -1278,6 +1278,25 @@ static void geEepromPatchAllCheats(u8 *buf)
|
|||||||
|
|
||||||
int changed = 0;
|
int changed = 0;
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
|
/* D259: a fresh ge007.eep is zero-filled, so every slot reads as
|
||||||
|
* all-zero. Normally such a slot fails fileValidateSaves' CRC and is
|
||||||
|
* reset to BLANKSAVEDATA (music_vol/sfx_vol = 0xFF); but this patch
|
||||||
|
* gives the slot a valid CRC below, so it survives with volume 0
|
||||||
|
* -> silence. Emulate fileResetSave: seed max volume on all-zero
|
||||||
|
* slots only -- real saves (incl. a deliberately muted one) keep
|
||||||
|
* their bytes. */
|
||||||
|
{
|
||||||
|
const u8 *raw = (const u8 *)&slots[i];
|
||||||
|
int allzero = 1;
|
||||||
|
for (int b = 0; b < (int)sizeof(ge_save_slot); b++)
|
||||||
|
if (raw[b]) { allzero = 0; break; }
|
||||||
|
if (allzero && (slots[i].music_vol != 0xFF ||
|
||||||
|
slots[i].sfx_vol != 0xFF)) {
|
||||||
|
slots[i].music_vol = 0xFF;
|
||||||
|
slots[i].sfx_vol = 0xFF;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Cheat ids are level ids 0..19 (CHEAT_INPUT_BUFFER_SIZE == 20):
|
/* Cheat ids are level ids 0..19 (CHEAT_INPUT_BUFFER_SIZE == 20):
|
||||||
* bits 0-7 in _1, 8-15 in _2, 16-19 in the low nibble of _3. */
|
* bits 0-7 in _1, 8-15 in _2, 16-19 in the low nibble of _3. */
|
||||||
if (slots[i].unlocked_cheats_1 != 0xFF ||
|
if (slots[i].unlocked_cheats_1 != 0xFF ||
|
||||||
|
|||||||
@@ -1721,7 +1721,21 @@ void gunRenderFirstPersonGunModels(Gfx **gdlptr)
|
|||||||
|
|
||||||
Gfx *set_enviro_fog_for_items_in_solo_watch_menu(Gfx *gdl, ITEM_IDS itemid, Mtxf *mtx, s32 arg3, s32 arg4)
|
Gfx *set_enviro_fog_for_items_in_solo_watch_menu(Gfx *gdl, ITEM_IDS itemid, Mtxf *mtx, s32 arg3, s32 arg4)
|
||||||
{
|
{
|
||||||
|
#ifdef PORT
|
||||||
|
/* D264 (ABI/layout class, cf. D140): on N64 this 64-byte copy spans two
|
||||||
|
* adjacent globals — D_80035D00 (zero) and D_80035D04 {1, 3, 0..} — i.e.
|
||||||
|
* the ModelRenderData template documented above D_80035D00 in gun.c
|
||||||
|
* (zbufferenabled=TRUE, flags=3, rest zero; CULLMODE_BOTH is 0). The PC
|
||||||
|
* link puts them in separate .bss/.data sections, so the read was all
|
||||||
|
* zeros: flags==0 gates every geometry node in subdraw() and the watch
|
||||||
|
* item preview emitted nothing. Use the explicit template (identical
|
||||||
|
* values to the N64 ROM bytes). */
|
||||||
|
ModelRenderData renderdata = {0};
|
||||||
|
renderdata.zbufferenabled = TRUE;
|
||||||
|
renderdata.flags = 3;
|
||||||
|
#else
|
||||||
ModelRenderData renderdata = *((ModelRenderData *) (&D_80035D00));
|
ModelRenderData renderdata = *((ModelRenderData *) (&D_80035D00));
|
||||||
|
#endif
|
||||||
ModelHeader model;
|
ModelHeader model;
|
||||||
u8 spb8[0x80];
|
u8 spb8[0x80];
|
||||||
s32 padb4;
|
s32 padb4;
|
||||||
|
|||||||
@@ -67,6 +67,44 @@
|
|||||||
#define GE_WATCH_STICK_FASTDOWN(pad) (joyGetStickY(pad) < -0x46)
|
#define GE_WATCH_STICK_FASTDOWN(pad) (joyGetStickY(pad) < -0x46)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef PORT
|
||||||
|
/* v0.2.1 (user report: "watch menu sensitivity for wasd/controller"): D118d
|
||||||
|
* removed the N64 slam-the-stick fast scroll because digital sources peg
|
||||||
|
* past its threshold -- but that left |stickY| >= 0x46 with NO repeat at all
|
||||||
|
* (the latched path steps once per press), so holding W/S or a full stick
|
||||||
|
* press crawled one item per tap through the list. Restore fast navigation
|
||||||
|
* as a bounded auto-repeat: while the stick is held past the smooth-scroll
|
||||||
|
* band (0x1f..0x45, untouched), step one extra item every GE_WATCH_NAV_RATE
|
||||||
|
* frames after an initial GE_WATCH_NAV_DELAY hold. The first press still goes
|
||||||
|
* through the latched single-step path, so a tap behaves exactly as before.
|
||||||
|
* Returns -1 (up) / +1 (down) on repeat frames, 0 otherwise. */
|
||||||
|
#define GE_WATCH_NAV_DELAY 15
|
||||||
|
#define GE_WATCH_NAV_RATE 6
|
||||||
|
static int s_watchNavHoldDir = 0; /* -1 up, +1 down, 0 none */
|
||||||
|
static int s_watchNavHoldFrames = 0;
|
||||||
|
|
||||||
|
static s32 geWatchStickFastStep(void)
|
||||||
|
{
|
||||||
|
int dir = 0;
|
||||||
|
if (joyGetStickY(PLAYER_1) >= 0x46) dir = -1;
|
||||||
|
else if (joyGetStickY(PLAYER_1) <= -0x45) dir = 1;
|
||||||
|
|
||||||
|
if (dir != s_watchNavHoldDir) {
|
||||||
|
s_watchNavHoldDir = dir;
|
||||||
|
s_watchNavHoldFrames = 0;
|
||||||
|
return 0; /* new direction: the latched press path already stepped */
|
||||||
|
}
|
||||||
|
if (dir == 0)
|
||||||
|
return 0;
|
||||||
|
if (++s_watchNavHoldFrames > GE_WATCH_NAV_DELAY &&
|
||||||
|
s_watchNavHoldFrames % GE_WATCH_NAV_RATE == 0)
|
||||||
|
return dir;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static s32 geWatchStickFastStep(void) { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
// bss
|
// bss
|
||||||
Mtx gfx_background_8007B0A0;
|
Mtx gfx_background_8007B0A0;
|
||||||
Mtx gfx_background_8007B0E0;
|
Mtx gfx_background_8007B0E0;
|
||||||
@@ -1107,6 +1145,19 @@ after_updown:
|
|||||||
watch_inventory_cursor_pos += 1.0f;
|
watch_inventory_cursor_pos += 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PORT
|
||||||
|
/* v0.2.1: bounded auto-repeat for a stick held past the smooth band
|
||||||
|
* (see geWatchStickFastStep). */
|
||||||
|
{
|
||||||
|
s32 fast = geWatchStickFastStep();
|
||||||
|
if (fast < 0 && g_curWatchItemIndex > 0 && !watch_item_is_actively_selected)
|
||||||
|
watch_inventory_cursor_pos += (f32) fast;
|
||||||
|
else if (fast > 0 && (s32) watch_inventory_cursor_pos < count - 1
|
||||||
|
&& !watch_item_is_actively_selected)
|
||||||
|
watch_inventory_cursor_pos += (f32) fast;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (is_holding_less_than_10_up_on_stick() || is_holding_less_than_10_down_on_stick())
|
if (is_holding_less_than_10_up_on_stick() || is_holding_less_than_10_down_on_stick())
|
||||||
{
|
{
|
||||||
watch_stick_y_prev_active = 1;
|
watch_stick_y_prev_active = 1;
|
||||||
|
|||||||
Reference in new issue
Block a user