From 971151ab836590126e7c6ba5e957fe03c5d01252 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 13:06:05 -0400 Subject: [PATCH] Fixes: MetaPage, AdvanceToNextPage, center/scale icons, button handling --- src/dehacked.c | 25 +++++++----- src/doomstat.h | 2 + src/f_finale.c | 107 +++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 116 insertions(+), 18 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b439f43de..2b466fab7 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1690,19 +1690,24 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].textsfx = get_number(word2); else if (fastcmp(word, "METAPAGE")) { - if (usi <= textprompts[num]->numpages) + if (usi && usi <= textprompts[num]->numpages) { - strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[usi].name, 32); - strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[usi].iconname, 8); - textprompts[num]->page[pagenum].rightside = textprompts[num]->page[usi].rightside; - textprompts[num]->page[pagenum].lines = textprompts[num]->page[usi].lines; - textprompts[num]->page[pagenum].backcolor = textprompts[num]->page[usi].backcolor; - textprompts[num]->page[pagenum].align = textprompts[num]->page[usi].align; - textprompts[num]->page[pagenum].verticalalign = textprompts[num]->page[usi].verticalalign; - textprompts[num]->page[pagenum].textspeed = textprompts[num]->page[usi].textspeed; - textprompts[num]->page[pagenum].textsfx = textprompts[num]->page[usi].textsfx; + UINT8 metapagenum = usi - 1; + strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[metapagenum].name, 32); + strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[metapagenum].iconname, 8); + textprompts[num]->page[pagenum].rightside = textprompts[num]->page[metapagenum].rightside; + textprompts[num]->page[pagenum].lines = textprompts[num]->page[metapagenum].lines; + textprompts[num]->page[pagenum].backcolor = textprompts[num]->page[metapagenum].backcolor; + textprompts[num]->page[pagenum].align = textprompts[num]->page[metapagenum].align; + textprompts[num]->page[pagenum].verticalalign = textprompts[num]->page[metapagenum].verticalalign; + textprompts[num]->page[pagenum].textspeed = textprompts[num]->page[metapagenum].textspeed; + textprompts[num]->page[pagenum].textsfx = textprompts[num]->page[metapagenum].textsfx; } } + else if (fastcmp(word, "NEXTPROMPT")) + textprompts[num]->page[pagenum].nextprompt = usi; + else if (fastcmp(word, "NEXTPAGE")) + textprompts[num]->page[pagenum].nextpage = usi; else deh_warning("PromptPage %d: unknown word '%s'", num, word); } diff --git a/src/doomstat.h b/src/doomstat.h index d737ef451..eaa19e3d6 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -177,6 +177,8 @@ typedef struct UINT8 verticalalign; // vertical text alignment, 0 = top, 1 = bottom, 2 = middle UINT8 textspeed; // text speed 0-15, makes it slower. See f_finale.c F_WriteText sfxenum_t textsfx; // sfx_ id for printing text + UINT8 nextprompt; // next prompt to jump to, one-based. 0 = current prompt + UINT8 nextpage; // next page to jump to, one-based. 0 = next page within prompt->numpages char *text; } textpage_t; diff --git a/src/f_finale.c b/src/f_finale.c index c25dd9eca..baaad10b0 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2019,6 +2019,47 @@ boolean F_CutsceneResponder(event_t *event) return false; } +// ================== +// TEXT PROMPTS +// ================== + +static void F_AdvanceToNextPage(void) +{ + UINT8 nextprompt = textprompts[cutnum]->page[scenenum].nextprompt, + nextpage = textprompts[cutnum]->page[scenenum].nextpage, + oldcutnum = cutnum; + + // determine next prompt + if (nextprompt) + { + if (textprompts[nextprompt-1]) + cutnum = nextprompt-1; + else + cutnum = INT32_MAX; + } + + // determine next page + if (nextpage) + { + scenenum = nextpage-1; + if (scenenum > textprompts[cutnum]->numpages-1) + scenenum = INT32_MAX; + } + else + { + if (cutnum != oldcutnum) + scenenum = 0; + else if (scenenum < textprompts[cutnum]->numpages-1) + scenenum++; + else + scenenum = INT32_MAX; + } + + // close the prompt if either num is invalid + if (cutnum == INT32_MAX || scenenum == INT32_MAX) + F_EndTextPrompt(); +} + void F_EndTextPrompt(void) { promptactive = false; @@ -2034,9 +2075,9 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum) stoptimer = 0; skullAnimCounter = 0; - cutnum = promptnum; - scenenum = pagenum; - promptactive = true; + cutnum = (textprompts[promptnum]) ? promptnum : INT32_MAX; + scenenum = (pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX; + promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX); } void F_TextPromptDrawer(void) @@ -2050,6 +2091,7 @@ void F_TextPromptDrawer(void) lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); UINT8 pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; + boolean rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); // Vertical calculations INT32 boxh = pagelines*2; @@ -2061,8 +2103,8 @@ void F_TextPromptDrawer(void) // Horizontal calculations // Shift text to the right if we have a character icon on the left side // Add 4 margin against icon - INT32 textx = iconlump != LUMPERROR && !textprompts[cutnum]->page[scenenum].rightside ? ((boxh * 4) + (boxh/2)*4) + 4 : 4; - INT32 textr = textprompts[cutnum]->page[scenenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4) + 4) : BASEVIDWIDTH-4; + INT32 textx = (iconlump != LUMPERROR && !rightside) ? ((boxh * 4) + (boxh/2)*4) + 4 : 4; + INT32 textr = rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4) + 4) : BASEVIDWIDTH-4; // Data patch_t *patch; @@ -2074,9 +2116,33 @@ void F_TextPromptDrawer(void) // Draw narrator icon if (iconlump != LUMPERROR) { - INT32 iconx = textprompts[cutnum]->page[scenenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4; + INT32 iconx, icony, scale, scaledsize; patch = W_CachePatchName(textprompts[cutnum]->page[scenenum].iconname, PU_CACHE); - V_DrawFixedPatch(iconx<width), V_SNAPTOBOTTOM, patch, NULL); + + // scale and center + if (patch->width > patch->height) + { + scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->width); + scaledsize = FixedMul(patch->height, scale); + iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS; + icony = ((namey-4) << FRACBITS) + FixedDiv(BASEVIDHEIGHT - namey + 4 - scaledsize, 2); // account for 4 margin + } + else if (patch->height > patch->width) + { + scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->height); + scaledsize = FixedMul(patch->width, scale); + iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS; + icony = namey << FRACBITS; + iconx += FixedDiv(FixedMul(patch->height, scale) - scaledsize, 2); + } + else + { + scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->width); + iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS; + icony = namey << FRACBITS; + } + + V_DrawFixedPatch(iconx, icony, scale, V_SNAPTOBOTTOM, patch, NULL); W_UnlockCachedPatch(patch); } @@ -2091,11 +2157,13 @@ void F_TextPromptDrawer(void) V_DrawString(textx, namey, V_SNAPTOBOTTOM, textprompts[cutnum]->page[scenenum].name); // Draw chevron - V_DrawString(textr-8, chevrony + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); // down arrow + V_DrawString(textr-8, chevrony + (skullAnimCounter/5), (V_SNAPTOBOTTOM|V_YELLOWMAP), "\x1B"); // down arrow } void F_TextPromptTicker(void) { + INT32 i; + if (!promptactive) return; @@ -2106,4 +2174,27 @@ void F_TextPromptTicker(void) // for the chevron if (--skullAnimCounter <= 0) skullAnimCounter = 8; + + // button handling + for (i = 0; i < MAXPLAYERS; i++) + { + if (netgame && i != serverplayer && i != adminplayer) + continue; + + if ((players[i].cmd.buttons & BT_USE) || (players[i].cmd.buttons & BT_JUMP)) + { + if (keypressed) + return; + + cutscene_boostspeed = 1; + if (timetonext) + timetonext = 2; + F_AdvanceToNextPage(); + keypressed = true; // prevent repeat events + } + else if (!(players[i].cmd.buttons & BT_USE) && !(players[i].cmd.buttons & BT_JUMP)) + keypressed = false; + + break; + } }