mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-24 00:02:45 +02:00
D106: portal near-plane projection garbage no longer culls the next room
BUNKER1's portal-visibility BFS (sub_GAME_7F0B7F84 -> sub_GAME_7F0B5864) projects each candidate portal polygon to a screen-space bbox. When the player straddles a portal's plane, sub_GAME_7F0B5528 emits z==0 near-plane clip points; transform3Dto2DWithZScaling then uses inv_z = -1e20, sending those points to +/-1e20-scale screen coords. On N64 the two clip points bracket the view symmetrically, so the degenerate-box check (bg.c:1713) or the downstream screensize clamp yields a full-screen box and the room is kept. On x86 the exact garbage can come back min>max on a single axis (or non-finite), slipping past that check -> the portal is dropped and the room the player is walking toward vanishes, showing skyRender's background fill through the doorway. Fix: #ifdef PORT, treat any wildly out-of-range / non-finite projected bound as degenerate -> full screensize (matches the N64 outcome). Verified -level_09: per-frame visible-room count 1-3 -> 2-4; rooms beyond near doorways (r11 from r27, etc.) now render. Reworks the GE_D104 probe to dump the per-frame visible-room list (gated, capped). Residual (separate): a bounded central sky gap + a blurry grey wall/ ceiling texture remain in the storage rooms — a dropped-poly / texture- dimension issue in the D85 room GDL path, not visibility.
This commit is contained in:
1 parent
5a5c73de56
commit
ad220f4e3d
1 file changed
+37
-25
+37
-25
@@ -636,31 +636,23 @@ Gfx *sub_GAME_7F0B3C8C(Gfx *gdl)
|
||||
gSPMatrix(gdl++, osVirtualToPhysical((void*)get_BONDdata_field_10E0()), (G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION));
|
||||
#ifdef PORT
|
||||
/* TEMP D104: room render-pass geometry-visibility probe. */
|
||||
if (getenv("GE_D104")) {
|
||||
static s32 d104n = 0;
|
||||
if (d104n < 40) {
|
||||
s32 *mp = (s32 *)(uintptr_t)(u32)get_BONDdata_field_10E0();
|
||||
s32 *pp = (s32 *)(uintptr_t)(u32)(uintptr_t)currentPlayerGetProjectionMatrix();
|
||||
osSyncPrintf("D104 room=%d bbox=(%d,%d)-(%d,%d) view l=%d t=%d x=%d y=%d screensize=(%d,%d)-(%d,%d)\n",
|
||||
dword_CODE_bss_8007FFA0[j].roomid,
|
||||
(s32)dword_CODE_bss_8007FFA0[j].bbox.min.x, (s32)dword_CODE_bss_8007FFA0[j].bbox.min.y,
|
||||
(s32)dword_CODE_bss_8007FFA0[j].bbox.max.x, (s32)dword_CODE_bss_8007FFA0[j].bbox.max.y,
|
||||
(s32)g_CurrentPlayer->viewleft, (s32)g_CurrentPlayer->viewtop,
|
||||
(s32)g_CurrentPlayer->viewx, (s32)g_CurrentPlayer->viewy,
|
||||
(s32)g_CurrentPlayer->screensize.min.x, (s32)g_CurrentPlayer->screensize.min.y,
|
||||
(s32)g_CurrentPlayer->screensize.max.x, (s32)g_CurrentPlayer->screensize.max.y);
|
||||
if (mp) {
|
||||
s32 r;
|
||||
for (r = 0; r < 4; r++) {
|
||||
f32 e0 = (f32)(s32)((mp[r*2+0] & 0xffff0000) | ((u32)mp[8+r*2+0] >> 16)) / 65536.0f;
|
||||
f32 e1 = (f32)(s32)((mp[r*2+0] << 16) | (mp[8+r*2+0] & 0xffff)) / 65536.0f;
|
||||
f32 e2 = (f32)(s32)((mp[r*2+1] & 0xffff0000) | ((u32)mp[8+r*2+1] >> 16)) / 65536.0f;
|
||||
f32 e3 = (f32)(s32)((mp[r*2+1] << 16) | (mp[8+r*2+1] & 0xffff)) / 65536.0f;
|
||||
osSyncPrintf("D104 row%d = % .4f % .4f % .4f % .4f\n", r, e0, e1, e2, e3);
|
||||
}
|
||||
{
|
||||
static s32 d104c = 0;
|
||||
if (getenv("GE_D104") && (d104c++ % 600) == 0 && d104c < 12000) {
|
||||
s32 rr;
|
||||
osSyncPrintf("D104 tick=%d curRoom=%d roomsDrawn=%d budget=%d :",
|
||||
d104c, (s32)g_CurrentPlayer->curRoomIndex,
|
||||
(s32)g_BgNumberOfRoomsDrawn, (s32)g_RoomLoadBudget);
|
||||
for (rr = 0; rr < g_BgNumberOfRoomsDrawn && rr < 24; rr++) {
|
||||
s32 rid = dword_CODE_bss_8007FFA0[rr].roomid;
|
||||
osSyncPrintf(" r%d(ld=%d %d,%d-%d,%d)", rid,
|
||||
(s32)g_BgRoomInfo[rid].model_bin_loaded,
|
||||
(s32)dword_CODE_bss_8007FFA0[rr].bbox.min.x,
|
||||
(s32)dword_CODE_bss_8007FFA0[rr].bbox.min.y,
|
||||
(s32)dword_CODE_bss_8007FFA0[rr].bbox.max.x,
|
||||
(s32)dword_CODE_bss_8007FFA0[rr].bbox.max.y);
|
||||
}
|
||||
osSyncPrintf("D104 f10E0=%p projm=%p\n", (void *)mp, (void *)pp);
|
||||
d104n++;
|
||||
osSyncPrintf("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1715,7 +1707,27 @@ s32 sub_GAME_7F0B5864(s32 portalnum, bbox2d *bbox)
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((bounds.max.x <= bounds.min.x) || (bounds.max.y <= bounds.min.y))
|
||||
s32 degenerate = (bounds.max.x <= bounds.min.x) || (bounds.max.y <= bounds.min.y);
|
||||
#ifdef PORT
|
||||
/* D106: a portal straddling the camera near-plane feeds z==0 clip
|
||||
* points into transform3Dto2DWithZScaling, whose inv_z = -1e20 sends
|
||||
* them to +/-1e20-scale screen coords. On N64 those bracket the view
|
||||
* symmetrically so the box just clamps to full screen downstream;
|
||||
* on PC the exact garbage can come back min>max on only one axis, or
|
||||
* non-finite, slipping past the check above and culling the room the
|
||||
* player is walking toward. Any wildly out-of-range / non-finite
|
||||
* bound means "portal fills the view" -> full screensize. */
|
||||
{
|
||||
const f32 lim = 100000.0f;
|
||||
if (!(bounds.min.x > -lim && bounds.min.x < lim) ||
|
||||
!(bounds.min.y > -lim && bounds.min.y < lim) ||
|
||||
!(bounds.max.x > -lim && bounds.max.x < lim) ||
|
||||
!(bounds.max.y > -lim && bounds.max.y < lim)) {
|
||||
degenerate = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (degenerate)
|
||||
{
|
||||
bounds.min.x = g_CurrentPlayer->screensize.min.x;
|
||||
bounds.min.y = g_CurrentPlayer->screensize.min.y;
|
||||
|
||||
Reference in new issue
Block a user