Fix crash when page text is empty; add checks for MAX_PROMPTS and MAX_PAGES
This commit is contained in:
parent
311cb27818
commit
b8897db308
|
@ -1773,17 +1773,17 @@ static void readtextprompt(MYFILE *f, INT32 num)
|
||||||
|
|
||||||
if (fastcmp(word, "NUMPAGES"))
|
if (fastcmp(word, "NUMPAGES"))
|
||||||
{
|
{
|
||||||
textprompts[num]->numpages = value;
|
textprompts[num]->numpages = min(max(value, 0), MAX_PAGES);
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "PAGE"))
|
else if (fastcmp(word, "PAGE"))
|
||||||
{
|
{
|
||||||
if (1 <= value && value <= 128)
|
if (1 <= value && value <= MAX_PAGES)
|
||||||
{
|
{
|
||||||
textprompts[num]->page[value - 1].backcolor = UINT8_MAX; // non-zero default
|
textprompts[num]->page[value - 1].backcolor = UINT8_MAX; // non-zero default
|
||||||
readtextpromptpage(f, num, value - 1);
|
readtextpromptpage(f, num, value - 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
deh_warning("Page number %d out of range (1 - 128)", value);
|
deh_warning("Page number %d out of range (1 - %d)", value, MAX_PAGES);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -166,6 +166,9 @@ typedef struct
|
||||||
|
|
||||||
extern cutscene_t *cutscenes[128];
|
extern cutscene_t *cutscenes[128];
|
||||||
|
|
||||||
|
#define MAX_PROMPTS 256
|
||||||
|
#define MAX_PAGES 128
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char name[32]; // narrator name
|
char name[32]; // narrator name
|
||||||
|
@ -186,11 +189,11 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
textpage_t page[128]; // 128 pages per prompt.
|
textpage_t page[MAX_PAGES];
|
||||||
INT32 numpages; // Number of pages in this prompt
|
INT32 numpages; // Number of pages in this prompt
|
||||||
} textprompt_t;
|
} textprompt_t;
|
||||||
|
|
||||||
extern textprompt_t *textprompts[256];
|
extern textprompt_t *textprompts[MAX_PROMPTS];
|
||||||
|
|
||||||
// For the Custom Exit linedef.
|
// For the Custom Exit linedef.
|
||||||
extern INT16 nextmapoverride;
|
extern INT16 nextmapoverride;
|
||||||
|
|
|
@ -2065,7 +2065,7 @@ static void F_PreparePageText(char *pagetext)
|
||||||
|
|
||||||
if (promptpagetext)
|
if (promptpagetext)
|
||||||
Z_Free(promptpagetext);
|
Z_Free(promptpagetext);
|
||||||
promptpagetext = V_WordWrap(textx, textr, 0, pagetext);
|
promptpagetext = (pagetext && pagetext[0]) ? V_WordWrap(textx, textr, 0, pagetext) : "";
|
||||||
|
|
||||||
F_NewCutscene(promptpagetext);
|
F_NewCutscene(promptpagetext);
|
||||||
cutscene_textspeed = textprompts[cutnum]->page[scenenum].textspeed ? textprompts[cutnum]->page[scenenum].textspeed : TICRATE/5;
|
cutscene_textspeed = textprompts[cutnum]->page[scenenum].textspeed ? textprompts[cutnum]->page[scenenum].textspeed : TICRATE/5;
|
||||||
|
@ -2085,7 +2085,7 @@ static void F_AdvanceToNextPage(void)
|
||||||
// determine next prompt
|
// determine next prompt
|
||||||
if (nextprompt)
|
if (nextprompt)
|
||||||
{
|
{
|
||||||
if (textprompts[nextprompt-1])
|
if (nextprompt <= MAX_PROMPTS && textprompts[nextprompt-1])
|
||||||
cutnum = nextprompt-1;
|
cutnum = nextprompt-1;
|
||||||
else
|
else
|
||||||
cutnum = INT32_MAX;
|
cutnum = INT32_MAX;
|
||||||
|
@ -2095,14 +2095,14 @@ static void F_AdvanceToNextPage(void)
|
||||||
if (nextpage)
|
if (nextpage)
|
||||||
{
|
{
|
||||||
scenenum = nextpage-1;
|
scenenum = nextpage-1;
|
||||||
if (scenenum > textprompts[cutnum]->numpages-1)
|
if (scenenum >= MAX_PAGES || scenenum > textprompts[cutnum]->numpages-1)
|
||||||
scenenum = INT32_MAX;
|
scenenum = INT32_MAX;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (cutnum != oldcutnum)
|
if (cutnum != oldcutnum)
|
||||||
scenenum = 0;
|
scenenum = 0;
|
||||||
else if (scenenum < textprompts[cutnum]->numpages-1)
|
else if (scenenum + 1 < MAX_PAGES && scenenum < textprompts[cutnum]->numpages-1)
|
||||||
scenenum++;
|
scenenum++;
|
||||||
else
|
else
|
||||||
scenenum = INT32_MAX;
|
scenenum = INT32_MAX;
|
||||||
|
@ -2157,8 +2157,8 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex
|
||||||
(void)freezerealtime; // \todo freeze player->realtime, maybe this needs to cycle through player thinkers
|
(void)freezerealtime; // \todo freeze player->realtime, maybe this needs to cycle through player thinkers
|
||||||
|
|
||||||
// Initialize current prompt and scene
|
// Initialize current prompt and scene
|
||||||
cutnum = (textprompts[promptnum]) ? promptnum : INT32_MAX;
|
cutnum = (promptnum < MAX_PROMPTS && textprompts[promptnum]) ? promptnum : INT32_MAX;
|
||||||
scenenum = (cutnum != INT32_MAX && pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX;
|
scenenum = (cutnum != INT32_MAX && pagenum < MAX_PAGES && pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX;
|
||||||
promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX);
|
promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX);
|
||||||
|
|
||||||
if (promptactive)
|
if (promptactive)
|
||||||
|
@ -2320,7 +2320,10 @@ void F_TextPromptTicker(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate letter-by-letter text
|
// generate letter-by-letter text
|
||||||
if (!F_WriteText())
|
if (scenenum >= MAX_PAGES ||
|
||||||
|
!textprompts[cutnum]->page[scenenum].text ||
|
||||||
|
!textprompts[cutnum]->page[scenenum].text[0] ||
|
||||||
|
!F_WriteText())
|
||||||
timetonext = !promptblockcontrols; // never show the chevron if we can't toggle pages
|
timetonext = !promptblockcontrols; // never show the chevron if we can't toggle pages
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue