diff --git a/src/deh_soc.c b/src/deh_soc.c index 7b4b0ad172d05b8feeca41ddf99c33c3455ffe57..b22e01014e38ad756449866037ed6294be5b1ae2 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2278,7 +2278,12 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) else if (fastcmp(word, "ICONFLIP")) page->iconflip = (i || word2[0] == 'T' || word2[0] == 'Y'); else if (fastcmp(word, "LINES")) - page->lines = usi; + { + if (i <= 0) + deh_warning("PromptPage %d: line count must be 1 or higher", num); + else + page->lines = usi; + } else if (fastcmp(word, "BACKCOLOR")) { INT32 backcolor = -1; @@ -2395,8 +2400,9 @@ void readtextprompt(MYFILE *f, INT32 num) { if (1 <= value && value <= MAX_PAGES) { - textprompts[num]->page[value - 1].backcolor = 1; // default to gray - textprompts[num]->page[value - 1].hidehud = 1; // hide appropriate HUD elements + textpage_t *page = &textprompts[num]->page[value - 1]; + if (page->lines == 0) + P_InitTextPromptPage(page); readtextpromptpage(f, num, value - 1); } else diff --git a/src/doomstat.h b/src/doomstat.h index e8a475b6f8208f10a4b73757af637c91dc168def..b9a6f07dc2d536ed01984bbefc102c0e5a81c77e 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -257,7 +257,7 @@ typedef struct INT32 backcolor; // see CON_SetupBackColormap: 0-11, INT32_MAX for user-defined (CONS_BACKCOLOR) UINT8 align; // text alignment, 0 = left, 1 = right, 2 = center UINT8 verticalalign; // vertical text alignment, 0 = top, 1 = bottom, 2 = middle - UINT8 textspeed; // text speed, delay in tics between characters. + SINT8 textspeed; // text speed, delay in tics between characters. sfxenum_t textsfx; // sfx_ id for printing text UINT16 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 diff --git a/src/p_dialog.c b/src/p_dialog.c index 2ae00da218e7fa4f98e0c84d2bdd08fb248da3c8..ae6b3ecdf942d877e9c8ef21fb7a7a2dd8550972 100644 --- a/src/p_dialog.c +++ b/src/p_dialog.c @@ -62,12 +62,15 @@ static void WriterTextBufferAlloc(textwriter_t *writer) UINT8 P_CutsceneWriteText(textwriter_t *writer) { INT32 numtowrite = 1; + const char *c; + const int max_speed = 8; + if (writer->boostspeed) { // for custom cutscene speedup mode - numtowrite = 8; + numtowrite = max_speed; } else { @@ -75,8 +78,8 @@ UINT8 P_CutsceneWriteText(textwriter_t *writer) if (--writer->textcount >= 0) return 1; - if (writer->textspeed < 7) - numtowrite = 8 - writer->textspeed; + if (writer->textspeed < max_speed-1) + numtowrite = max_speed - writer->textspeed; } for (;numtowrite > 0;++writer->baseptr) @@ -181,6 +184,14 @@ static INT32 P_FindTextPromptSlot(const char *name) return -1; } +void P_InitTextPromptPage(textpage_t *page) +{ + page->lines = 4; // default line count to four + page->textspeed = TICRATE/5; // default text speed to 1/5th of a second + page->backcolor = 1; // default to gray + page->hidehud = 1; // hide appropriate HUD elements +} + void P_FreeTextPrompt(textprompt_t *prompt) { if (!prompt) @@ -235,7 +246,7 @@ static void F_GetPageTextGeometry(dialog_t *dialog, dialog_geometry_t *geo) if (dialog->icon[0]) iconlump = W_CheckNumForLongName(dialog->icon); - INT32 pagelines = dialog->page->lines ? dialog->page->lines : 4; + INT32 pagelines = dialog->page->lines; boolean rightside = iconlump != LUMPERROR && dialog->page->rightside; // Vertical calculations @@ -597,8 +608,13 @@ static UINT8 P_DialogWriteText(dialog_t *dialog, textwriter_t *writer) writer->numtowrite = 1; + const int max_speed = 8; + if (writer->boostspeed && !writer->paused) - writer->numtowrite = 8; + { + // When the player is holding jump or spin + writer->numtowrite = max_speed; + } else { // Don't draw any characters if the count was 1 or more when we started @@ -607,8 +623,8 @@ static UINT8 P_DialogWriteText(dialog_t *dialog, textwriter_t *writer) writer->paused = false; - if (writer->textspeed < 7) - writer->numtowrite = 8 - writer->textspeed; + if (writer->textspeed >= 0 && writer->textspeed < max_speed-1) + writer->numtowrite = max_speed - writer->textspeed; } while (writer->numtowrite > 0) @@ -636,7 +652,7 @@ static UINT8 P_DialogWriteText(dialog_t *dialog, textwriter_t *writer) // Ignore non-printable characters // (that is, decrement numtowrite if this character is printable.) - if (lastchar < 0x80) + if (lastchar < 0x80 && writer->textspeed >= 0) --writer->numtowrite; } @@ -645,8 +661,8 @@ static UINT8 P_DialogWriteText(dialog_t *dialog, textwriter_t *writer) if (writer->textcount < 0) { writer->textcount = 0; - if (writer->textspeed > 7) - writer->textcount = writer->textspeed - 7; + if (writer->textspeed > max_speed-1) + writer->textcount = writer->textspeed - max_speed-1; } if (lastchar == '\0' || isspace(lastchar)) @@ -710,13 +726,22 @@ void P_DialogSetText(dialog_t *dialog, char *pagetext, size_t textlength) P_ResetTextWriter(writer, dialog->pagetext, dialog->pagetextlength); - writer->textspeed = dialog->page->textspeed ? dialog->page->textspeed : TICRATE/5; + INT32 textspeed = dialog->page->textspeed; + if (textspeed >= -1) + writer->textspeed = textspeed; + else + writer->textspeed = TICRATE/5; + writer->textcount = 0; // no delay in beginning writer->boostspeed = false; // don't print 8 characters to start P_DialogSetDisplayText(dialog); + + // Immediately type the first character + P_DialogWriteText(dialog, writer); } +// TODO: Just remove this? This used to be a wrapper. static void P_PreparePageText(dialog_t *dialog, char *pagetext, size_t textlength) { P_DialogSetText(dialog, pagetext, textlength); @@ -727,8 +752,6 @@ static void P_PreparePageText(dialog_t *dialog, char *pagetext, size_t textlengt static void P_DialogStartPage(player_t *player, dialog_t *dialog) { - P_PreparePageText(dialog, dialog->page->text, dialog->page->textlength); - // on page mode, number of tics before allowing boost // on timer mode, number of tics until page advances dialog->timetonext = dialog->page->timetonext ? dialog->page->timetonext : TICRATE/10; @@ -783,6 +806,9 @@ static void P_DialogStartPage(player_t *player, dialog_t *dialog) dialog->iconflip = dialog->page->iconflip; + // Prepare page text + P_PreparePageText(dialog, dialog->page->text, dialog->page->textlength); + // music change if (P_IsLocalPlayer(player) || globaltextprompt) { @@ -2290,12 +2316,14 @@ static void InterpretControlCode(char **input, UINT8 **buf, size_t *buffer_pos, char *param = GetControlCodeParam(input); if (param) { - int speed = 0; + int speed = 1; if (StringToNumber(param, &speed)) { if (speed < 0) speed = 0; + + speed--; } else EXPECTED_NUMBER("SPEED"); @@ -2459,8 +2487,7 @@ static void ParsePage(textprompt_t *prompt, tokenizer_t *sc) textpage_t *page = &prompt->page[prompt->numpages]; - page->backcolor = 1; // default to gray - page->hidehud = 1; // hide appropriate HUD elements + P_InitTextPromptPage(page); prompt->numpages++; @@ -2595,6 +2622,9 @@ static void ParsePage(textprompt_t *prompt, tokenizer_t *sc) EXPECT_NUMBER("page 'duration'"); + if (num < 0) + num = 0; + page->timetonext = num; EXPECT_TOKEN(";"); @@ -2607,7 +2637,10 @@ static void ParsePage(textprompt_t *prompt, tokenizer_t *sc) EXPECT_NUMBER("page 'textspeed'"); - page->textspeed = num; + if (num < 1) + num = 1; + + page->textspeed = num - 1; EXPECT_TOKEN(";"); } @@ -2619,6 +2652,9 @@ static void ParsePage(textprompt_t *prompt, tokenizer_t *sc) EXPECT_NUMBER("page 'textlines'"); + if (num < 1) + num = 1; + page->lines = num; EXPECT_TOKEN(";"); diff --git a/src/p_dialog.h b/src/p_dialog.h index 6201a2754f0d1e679925d5711baecaf9fab11d4d..6c94a992c51c24574719c56141366077aee70312 100644 --- a/src/p_dialog.h +++ b/src/p_dialog.h @@ -103,6 +103,7 @@ INT32 P_GetPromptPageByName(textprompt_t *prompt, const char *name); void P_GetPromptPageByNamedTag(const char *tag, INT32 *promptnum, INT32 *pagenum); void P_SetMetaPage(textpage_t *page, textpage_t *metapage); void P_SetPicsMetaPage(textpage_t *page, textpage_t *metapage); +void P_InitTextPromptPage(textpage_t *page); void P_FreeTextPrompt(textprompt_t *prompt); char *P_ConvertSOCPageDialog(char *text, size_t *text_length);