diff --git a/src/game/bg.c b/src/game/bg.c index ec0f7174..0702bbd1 100644 --- a/src/game/bg.c +++ b/src/game/bg.c @@ -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;