forked from Ports/goldeneye-pc-port
M-27: D143 null-string text guard + D144 bad-matrix-ptr fast3d guard
D143 (src/game/textrelated.c): langGet() returns NULL for a string slot the current flow has not loaded (non-DEBUG builds; DEBUG substitutes a placeholder). The N64 retail menu flow guarantees every front-end string is resident before it is drawn; the PC flow does not yet, so a missing briefing/objective/mode-select string reached textRender/textMeasure/ textWrap as NULL and faulted in the `*text` scan. Added #ifdef PORT NULL guards at all four entry points -> degrade to "draw nothing" (blank text) instead of crashing. User verified: front-end now navigable folder -> mode -> difficulty -> level -> in-game. D144 (port/fast3d/gfx_pc.cpp gfx_sp_matrix): a front-end 3D model (MISSION COMPLETE dossier / mode-select wallets - D75 family) emits a gSPMatrix whose pointer field was never resolved; w1 arrives as 0xFFFFFFFFFFFFFFFF, seg_addr() passes it through, and gfx_sp_matrix faults reading addr[]. Guard: an unmapped/non-canonical addr -> substitute identity (model draws with wrong transform, already a parked D75 cosmetic) so the screen and its "Next" -> menu transition survive. Verified: -level_09 unregressed (framediff 2/2 ok w/ HUD mask, no crash).
This commit is contained in:
1 parent
94f677584a
commit
70793eba4f
2 files changed
+50
-2
No files matched your search
@@ -1039,6 +1039,21 @@ static void gfx_matrix_mul(float res[4][4], const float a[4][4], const float b[4
|
||||
static void gfx_sp_matrix(uint8_t parameters, const int32_t* addr) {
|
||||
float matrix[4][4];
|
||||
|
||||
/* D144: a front-end 3D model (MISSION COMPLETE dossier, mode-select
|
||||
* wallets - the D75 family) can emit a gSPMatrix whose pointer field was
|
||||
* never resolved: w1 comes through as 0xFFFF... or another non-canonical
|
||||
* value, and seg_addr() then hands us a wild pointer -> AV reading addr[].
|
||||
* A real N64 matrix pointer always lands in mapped memory. Rather than
|
||||
* crash the menu transition, substitute identity for an unmapped source
|
||||
* (the model draws with the wrong transform - already a parked D75
|
||||
* cosmetic - but the screen and its "Next" -> menu path work). */
|
||||
const bool addr_bad = ((uintptr_t)addr < 0x10000 ||
|
||||
(uintptr_t)addr >= 0x0000800000000000ULL);
|
||||
|
||||
if (addr_bad) {
|
||||
memset(matrix, 0, sizeof(matrix));
|
||||
matrix[0][0] = matrix[1][1] = matrix[2][2] = matrix[3][3] = 1.0f;
|
||||
} else
|
||||
#ifndef GBI_FLOATS
|
||||
// Original GBI where fixed point matrices are used
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
||||
+35
-2
@@ -420,7 +420,19 @@ Gfx *textRender(Gfx *gdl, s32 *x, s32 *y, char *text,
|
||||
s32 stack3;
|
||||
s32 stack4;
|
||||
//s32 stack5;
|
||||
|
||||
|
||||
#ifdef PORT
|
||||
/* D143: langGet() returns NULL for a string slot the current flow has not
|
||||
* loaded (non-DEBUG builds; DEBUG substitutes a placeholder). The N64
|
||||
* retail flow guarantees every front-end string is resident before it is
|
||||
* drawn; the PC menu flow does not yet, so a missing briefing/objective
|
||||
* string reaches textRender as NULL and faults in the `*text` scan.
|
||||
* Degrade to "draw nothing" like an empty string would. */
|
||||
if (text == NULL) {
|
||||
return gdl;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_JpnTextTlutNeedsLoad = 1;
|
||||
|
||||
savedx = *x;
|
||||
@@ -683,7 +695,13 @@ Gfx *textRenderOutlined(Gfx *gdl, s32 *x, s32 *y,
|
||||
s32 savedx;
|
||||
struct fontchar sp74;
|
||||
s32 prevchar;
|
||||
|
||||
|
||||
#ifdef PORT
|
||||
if (text == NULL) { /* D143 - see textRender */
|
||||
return gdl;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_JpnTextTlutNeedsLoad = 1;
|
||||
|
||||
savedx = *x;
|
||||
@@ -757,6 +775,12 @@ void textMeasure(s32 *textheight, s32 *textwidth, char *text, struct fontchar *f
|
||||
*textheight = 0;
|
||||
*textwidth = 0;
|
||||
|
||||
#ifdef PORT
|
||||
if (text == NULL) { /* D143 - see textRender */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lineheight == 0)
|
||||
{
|
||||
lineheight = font1['['].baseline + font1['['].height;
|
||||
@@ -834,6 +858,15 @@ void textWrap(s32 wrapwidth, char *src, char *dst, struct fontchar *chars, struc
|
||||
u32 stack;
|
||||
char curword[32];
|
||||
|
||||
#ifdef PORT
|
||||
if (src == NULL) { /* D143 - see textRender */
|
||||
if (dst != NULL) {
|
||||
dst[0] = '\0';
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (more == 1) {
|
||||
// Load the next word
|
||||
wordwidth = 0;
|
||||
|
||||
Reference in new issue
Block a user