diff --git a/src/f_finale.c b/src/f_finale.c index cb64618535659f329bb357f65c2cec0bbe006b2d..a86ce53c7354975e29afde7a5b268d25ad246549 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1308,25 +1308,39 @@ void F_CreditDrawer(void) { switch(credits[i][0]) { - case 0: - y += 80<<FRACBITS; - break; - case 1: - if (y>>FRACBITS > -20) - V_DrawCreditString((160 - (V_CreditStringWidth(&credits[i][1])>>1))<<FRACBITS, y, 0, &credits[i][1]); - y += 30<<FRACBITS; - break; - case 2: - if (y>>FRACBITS > -10) - V_DrawStringAtFixed((BASEVIDWIDTH-V_StringWidth(&credits[i][1], V_ALLOWLOWERCASE|V_YELLOWMAP))<<FRACBITS>>1, y, V_ALLOWLOWERCASE|V_YELLOWMAP, &credits[i][1]); - y += 12<<FRACBITS; - break; - default: - if (y>>FRACBITS > -10) - V_DrawStringAtFixed(32<<FRACBITS, y, V_ALLOWLOWERCASE, credits[i]); - y += 12<<FRACBITS; - break; + case 0: + y += 80<<FRACBITS; + break; + case 1: + { + INT32 height = V_CreditStringHeight(&credits[i][1], 0) * vid.dup; + height <<= FRACBITS; + if (y > -height) + V_DrawCreditString((160 - (V_CreditStringWidth(&credits[i][1]) >> 1)) << FRACBITS, y, 0, &credits[i][1]); + y += 30 << FRACBITS; + break; + } + case 2: + { + // Because of how the text is drawn, assuming a line height of 12, measuring the string height here won't work. + INT32 height = /*V_StringHeight(&credits[i][1], V_ALLOWLOWERCASE | V_YELLOWMAP)*/ 12 * vid.dup; + height <<= FRACBITS; + if (y > -height) + V_DrawStringAtFixed((BASEVIDWIDTH - V_StringWidth(&credits[i][1], V_ALLOWLOWERCASE | V_YELLOWMAP)) << FRACBITS >> 1, y, V_ALLOWLOWERCASE | V_YELLOWMAP, &credits[i][1]); + y += 12 << FRACBITS; + break; + } + default: + { + INT32 height = /*V_StringHeight(credits[i], V_ALLOWLOWERCASE)*/ 12 * vid.dup; + height <<= FRACBITS; + if (y > -height) + V_DrawStringAtFixed(32 << FRACBITS, y, V_ALLOWLOWERCASE, credits[i]); + y += 12 << FRACBITS; + break; + } } + if (FixedMul(y,vid.dup) > vid.height) break; } diff --git a/src/v_video.c b/src/v_video.c index cb7db487e921b88e50fd0b6d97a6d3f631841c90..304771a9dd92caf846fcd3ac7ff6ea813bfcdf2c 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -3213,6 +3213,65 @@ INT32 V_CreditStringWidth(const char *string) return w; } +// +// V_CreditStringHeight +// +// Returns the UNSCALED height of the credit string, including line breaks. +// +INT32 V_CreditStringHeight(const char *string) +{ + fixed_t x = 0; + fixed_t y = 0; + INT32 w, c; + fixed_t cx = x, cy = y; + const char *ch = string; + + INT32 textHeight = 0; + INT32 lineHeight = 0; + INT32 verticalPad = 0; + + // It's possible for string to be a null pointer + if (!string) + return; + + for (;;) + { + c = *ch++; + if (!c) + { + textHeight += lineHeight; + break; + } + + if (c == '\n') + { + cx = x; + cy += 12; + textHeight += lineHeight; + lineHeight = 0; + verticalPad += 4; + continue; + } + + c = toupper(c) - CRED_FONTSTART; + if (c < 0 || c >= CRED_FONTSIZE) + { + cx += 16; + continue; + } + + w = cred_font[c]->width; + + INT16 charHeight = cred_font[c]->height; + if (charHeight > lineHeight) + lineHeight = charHeight; + + cx += w; + } + + return textHeight + verticalPad; +} + // Write a string using the level title font // NOTE: the text is centered for screens larger than the base width // @@ -3380,6 +3439,100 @@ INT32 V_StringWidth(const char *string, INT32 option) return w; } +// +// V_StringHeight +// +// Returns the UNSCALED height of the string, including line breaks. +// +INT32 V_StringHeight(const char *string, INT32 option) +{ + INT32 x = 0; + INT32 y = 0; + INT32 w, c, cx = x, cy = y, center = 0; + const char *ch = string; + INT32 charflags = (option & V_CHARCOLORMASK); + INT32 spacewidth = 4, charwidth = 0; + + INT32 lowercase = (option & V_ALLOWLOWERCASE); + option &= ~V_FLIP; // which is also shared with V_ALLOWLOWERCASE... + + switch (option & V_SPACINGMASK) + { + case V_MONOSPACE: + spacewidth = 8; + /* FALLTHRU */ + case V_OLDSPACING: + charwidth = 8; + break; + case V_6WIDTHSPACE: + spacewidth = 6; + default: + break; + } + + INT32 textHeight = 0; + INT32 lineHeight = 0; + INT32 verticalPad = 0; + + for (;; ch++) + { + if (!*ch) + { + textHeight += lineHeight; + break; + } + if (*ch & 0x80) //color parsing -x 2.16.09 + { + // manually set flags override color codes + if (!(option & V_CHARCOLORMASK)) + charflags = ((*ch & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK; + continue; + } + if (*ch == '\n') + { + cx = x; + + if (option & V_RETURN8) + cy += 8; + else + { + cy += 12; + verticalPad += 4; + } + + textHeight += lineHeight; + lineHeight = 0; + + continue; + } + + c = *ch; + if (!lowercase) + c = toupper(c); + c -= HU_FONTSTART; + + // character does not exist or is a space + if (c < 0 || c >= HU_FONTSIZE || !hu_font[c]) + { + cx += spacewidth; + continue; + } + + if (charwidth) + w = charwidth; + else + w = hu_font[c]->width; + + INT16 charHeight = hu_font[c]->height; + if (charHeight > lineHeight) + lineHeight = charHeight; + + cx += w; + } + + return textHeight + verticalPad; +} + // // Find string width from hu_font chars, 0.5x scale // diff --git a/src/v_video.h b/src/v_video.h index 5a3df5a4499588df56e4a6d152f1445f82a60926..c440e6978b36717a784a4b33ddd562e4ffafc96b 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -257,6 +257,7 @@ INT16 V_LevelActNumWidth(UINT8 num); // act number width void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string); INT32 V_CreditStringWidth(const char *string); +INT32 V_CreditStringHeight(const char *string, INT32 option); // Draw a string using the nt_font void V_DrawNameTag(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string); @@ -265,6 +266,7 @@ INT32 V_NameTagWidth(const char *string); // Find string width from hu_font chars INT32 V_StringWidth(const char *string, INT32 option); +INT32 V_StringHeight(const char *string, INT32 option); // Find string width from hu_font chars, 0.5x scale INT32 V_SmallStringWidth(const char *string, INT32 option); // Find string width from tny_font chars