mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-09 08:22:28 +00:00
V_ScaledWordWrap
Moves WordWrap to the font/V_GetFontSpecification system. Much healthier long-term for our purposes, including the possibility of changing fonts for various contexts freely.
This commit is contained in:
parent
fb0fa9ac53
commit
277f7c51a3
7 changed files with 187 additions and 207 deletions
|
|
@ -2281,7 +2281,24 @@ static void F_PreparePageText(char *pagetext)
|
|||
|
||||
if (promptpagetext)
|
||||
Z_Free(promptpagetext);
|
||||
promptpagetext = (pagetext && pagetext[0]) ? V_WordWrap(textx, textr, 0, pagetext) : Z_StrDup("");
|
||||
if (pagetext && pagetext[0])
|
||||
{
|
||||
promptpagetext = Z_StrDup(pagetext);
|
||||
V_ScaledWordWrap(
|
||||
(textx - textr)<<FRACBITS,
|
||||
FRACUNIT, FRACUNIT, FRACUNIT,
|
||||
0, HU_FONT,
|
||||
promptpagetext
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The original code I was replacing did this,
|
||||
// And I'm not really interested enough to figure out
|
||||
// if this is strictly necessary in the long term or
|
||||
// if it was just an anti-crash doohickey. ~toast 110723
|
||||
promptpagetext = Z_StrDup("");
|
||||
}
|
||||
|
||||
F_NewCutscene(promptpagetext);
|
||||
cutscene_textspeed = textprompts[cutnum]->page[scenenum].textspeed ? textprompts[cutnum]->page[scenenum].textspeed : TICRATE/5;
|
||||
|
|
|
|||
|
|
@ -1270,56 +1270,21 @@ boolean HU_Responder(event_t *ev)
|
|||
//======================================================================
|
||||
|
||||
// Precompile a wordwrapped string to any given width.
|
||||
// This is a muuuch better method than V_WORDWRAP.
|
||||
// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day.
|
||||
// this one is simplified for the chat drawer.
|
||||
// Now a wrapper for the chat drawer.
|
||||
static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
{
|
||||
INT32 c;
|
||||
size_t chw, i, lastusablespace = 0;
|
||||
size_t slen;
|
||||
char *newstring = Z_StrDup(string);
|
||||
INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4;
|
||||
|
||||
slen = strlen(string);
|
||||
x = 0;
|
||||
fixed_t scale = (vid.width < 640) ? FRACUNIT : FRACUNIT/2;
|
||||
|
||||
for (i = 0; i < slen; ++i)
|
||||
{
|
||||
c = newstring[i];
|
||||
if ((UINT8)c >= 0x80 && (UINT8)c <= 0x8F) //color parsing! -Inuyasha 2.16.09
|
||||
continue;
|
||||
V_ScaledWordWrap(
|
||||
(w - x) << FRACBITS,
|
||||
scale, scale, scale,
|
||||
option,
|
||||
HU_FONT,
|
||||
newstring
|
||||
);
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
x = 0;
|
||||
lastusablespace = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!!(option & V_FORCEUPPERCASE))
|
||||
c = toupper(c);
|
||||
c -= HU_FONTSTART;
|
||||
|
||||
if (c < 0 || c >= HU_FONTSIZE || !fontv[HU_FONT].font[c])
|
||||
{
|
||||
chw = spacewidth;
|
||||
lastusablespace = i;
|
||||
}
|
||||
else
|
||||
chw = charwidth;
|
||||
|
||||
x += chw;
|
||||
|
||||
if (lastusablespace != 0 && x > w)
|
||||
{
|
||||
//CONS_Printf("Wrap at index %d\n", i);
|
||||
newstring[lastusablespace] = '\n';
|
||||
i = lastusablespace+1;
|
||||
lastusablespace = 0;
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
return newstring;
|
||||
}
|
||||
|
||||
|
|
|
|||
42
src/m_cond.c
42
src/m_cond.c
|
|
@ -1515,7 +1515,7 @@ char *M_BuildConditionSetString(UINT16 unlockid)
|
|||
size_t len = 1024, worklen;
|
||||
static char message[1024] = "";
|
||||
const char *work = NULL;
|
||||
size_t max = 0, maxatstart = 0, start = 0, i;
|
||||
size_t i;
|
||||
boolean stopasap = false;
|
||||
|
||||
message[0] = '\0';
|
||||
|
|
@ -1577,37 +1577,6 @@ char *M_BuildConditionSetString(UINT16 unlockid)
|
|||
}
|
||||
}
|
||||
|
||||
// Rudementary word wrapping.
|
||||
// Simple and effective. Does not handle nonuniform letter sizes, etc. but who cares.
|
||||
for (i = 0; message[i]; i++)
|
||||
{
|
||||
if (message[i] == ' ')
|
||||
{
|
||||
start = i;
|
||||
max += 4;
|
||||
maxatstart = max;
|
||||
}
|
||||
else if (message[i] == '\n')
|
||||
{
|
||||
start = 0;
|
||||
max = 0;
|
||||
maxatstart = 0;
|
||||
continue;
|
||||
}
|
||||
else if (message[i] & 0x80)
|
||||
continue;
|
||||
else
|
||||
max += 8;
|
||||
|
||||
// Start trying to wrap if presumed length exceeds the space we have on-screen.
|
||||
if (max >= DESCRIPTIONWIDTH && start > 0)
|
||||
{
|
||||
message[start] = '\n';
|
||||
max -= maxatstart;
|
||||
start = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Valid sentence capitalisation handling.
|
||||
{
|
||||
// Finds the first : character, indicating the end of the prefix.
|
||||
|
|
@ -1634,6 +1603,15 @@ char *M_BuildConditionSetString(UINT16 unlockid)
|
|||
}
|
||||
}
|
||||
|
||||
// Finally, do a clean wordwrap!
|
||||
V_ScaledWordWrap(
|
||||
DESCRIPTIONWIDTH << FRACBITS,
|
||||
FRACUNIT, FRACUNIT, FRACUNIT,
|
||||
0,
|
||||
HU_FONT,
|
||||
message
|
||||
);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// \brief MESSAGE BOX (aka: a hacked, cobbled together menu)
|
||||
|
||||
#include "../../k_menu.h"
|
||||
#include "../../v_video.h" // V_ScaledWordWrap, HU_FONT
|
||||
#include "../../z_zone.h"
|
||||
|
||||
// message prompt struct
|
||||
|
|
@ -30,42 +31,18 @@ static inline size_t M_StringHeight(const char *string)
|
|||
void M_StartMessage(const char *header, const char *string, void (*routine)(INT32), menumessagetype_t itemtype, const char *confirmstr, const char *defaultstr)
|
||||
{
|
||||
const UINT8 pid = 0;
|
||||
size_t max = 0, maxatstart = 0, start = 0, strlines, i;
|
||||
static char *message = NULL;
|
||||
Z_Free(message);
|
||||
message = Z_StrDup(string);
|
||||
DEBFILE(message);
|
||||
|
||||
// Rudementary word wrapping.
|
||||
// Simple and effective. Does not handle nonuniform letter sizes, etc. but who cares.
|
||||
for (i = 0; message[i]; i++)
|
||||
{
|
||||
if (message[i] == ' ')
|
||||
{
|
||||
start = i;
|
||||
max += 4;
|
||||
maxatstart = max;
|
||||
}
|
||||
else if (message[i] == '\n')
|
||||
{
|
||||
start = 0;
|
||||
max = 0;
|
||||
maxatstart = 0;
|
||||
continue;
|
||||
}
|
||||
else if (message[i] & 0x80)
|
||||
continue;
|
||||
else
|
||||
max += 8;
|
||||
|
||||
// Start trying to wrap if presumed length exceeds the screen width.
|
||||
if (max >= BASEVIDWIDTH && start > 0)
|
||||
{
|
||||
message[start] = '\n';
|
||||
max -= maxatstart;
|
||||
start = 0;
|
||||
}
|
||||
}
|
||||
V_ScaledWordWrap(
|
||||
BASEVIDWIDTH << FRACBITS,
|
||||
FRACUNIT, FRACUNIT, FRACUNIT,
|
||||
0,
|
||||
HU_FONT,
|
||||
message
|
||||
);
|
||||
|
||||
strncpy(menumessage.message, string, MAXMENUMESSAGE);
|
||||
menumessage.header = header;
|
||||
|
|
@ -77,9 +54,6 @@ void M_StartMessage(const char *header, const char *string, void (*routine)(INT3
|
|||
menumessage.closing = 0;
|
||||
menumessage.active = true;
|
||||
|
||||
start = 0;
|
||||
max = 0;
|
||||
|
||||
if (!routine)
|
||||
{
|
||||
menumessage.flags = MM_NOTHING;
|
||||
|
|
@ -108,29 +82,7 @@ void M_StartMessage(const char *header, const char *string, void (*routine)(INT3
|
|||
}*/
|
||||
|
||||
//added : 06-02-98: now draw a textbox around the message
|
||||
// compute lenght max and the numbers of lines
|
||||
for (strlines = 0; *(message+start); strlines++)
|
||||
{
|
||||
for (i = 0; i < strlen(message+start);i++)
|
||||
{
|
||||
if (*(message+start+i) == '\n')
|
||||
{
|
||||
if (i > max)
|
||||
max = i;
|
||||
start += i;
|
||||
i = (size_t)-1; //added : 07-02-98 : damned!
|
||||
start++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == strlen(message+start))
|
||||
{
|
||||
start += i;
|
||||
if (i > max)
|
||||
max = i;
|
||||
}
|
||||
}
|
||||
// oogh my god this was replaced in 2023
|
||||
|
||||
menumessage.x = (8 * MAXSTRINGLENGTH) - 1;
|
||||
menumessage.y = M_StringHeight(message);
|
||||
|
|
|
|||
|
|
@ -305,6 +305,8 @@ static void I_ShowErrorMessageBox(const char *messagefordevelopers, boolean dump
|
|||
|
||||
// Rudementary word wrapping.
|
||||
// Simple and effective. Does not handle nonuniform letter sizes, etc. but who cares.
|
||||
// We can't use V_ScaledWordWrap, which this shares DNA with, because no guarantee
|
||||
// string character graphics exist as reference in the error handler...
|
||||
{
|
||||
size_t max = 0, maxatstart = 0, start = 0, width = 0, i;
|
||||
|
||||
|
|
|
|||
200
src/v_video.cpp
200
src/v_video.cpp
|
|
@ -2043,76 +2043,6 @@ void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boole
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Precompile a wordwrapped string to any given width.
|
||||
// This is a muuuch better method than V_WORDWRAP.
|
||||
char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
{
|
||||
int c;
|
||||
size_t chw, i, lastusablespace = 0;
|
||||
size_t slen;
|
||||
char *newstring = Z_StrDup(string);
|
||||
INT32 spacewidth = 4, charwidth = 0;
|
||||
|
||||
slen = strlen(string);
|
||||
|
||||
if (w == 0)
|
||||
w = BASEVIDWIDTH;
|
||||
w -= x;
|
||||
x = 0;
|
||||
|
||||
switch (option & V_SPACINGMASK)
|
||||
{
|
||||
case V_MONOSPACE:
|
||||
spacewidth = 8;
|
||||
/* FALLTHRU */
|
||||
case V_OLDSPACING:
|
||||
charwidth = 8;
|
||||
break;
|
||||
case V_6WIDTHSPACE:
|
||||
spacewidth = 6;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < slen; ++i)
|
||||
{
|
||||
c = newstring[i];
|
||||
if ((UINT8)c & 0x80) //color parsing! -Inuyasha 2.16.09
|
||||
continue;
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
x = 0;
|
||||
lastusablespace = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!!(option & V_FORCEUPPERCASE))
|
||||
c = toupper(c);
|
||||
c -= HU_FONTSTART;
|
||||
|
||||
if (c < 0 || c >= HU_FONTSIZE || !fontv[HU_FONT].font[c])
|
||||
{
|
||||
chw = spacewidth;
|
||||
lastusablespace = i;
|
||||
}
|
||||
else
|
||||
chw = (charwidth ? charwidth : fontv[HU_FONT].font[c]->width);
|
||||
|
||||
x += chw;
|
||||
|
||||
if (lastusablespace != 0 && x > w)
|
||||
{
|
||||
newstring[lastusablespace] = '\n';
|
||||
i = lastusablespace;
|
||||
lastusablespace = 0;
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
return newstring;
|
||||
}
|
||||
|
||||
static inline fixed_t FixedCharacterDim(
|
||||
fixed_t scale,
|
||||
fixed_t chw,
|
||||
|
|
@ -2684,6 +2614,136 @@ fixed_t V_StringScaledWidth(
|
|||
return fullwidth;
|
||||
}
|
||||
|
||||
// Modify a string to wordwrap at any given width.
|
||||
void V_ScaledWordWrap(
|
||||
fixed_t w,
|
||||
fixed_t scale,
|
||||
fixed_t spacescale,
|
||||
fixed_t lfscale,
|
||||
INT32 flags,
|
||||
int fontno,
|
||||
char *newstring)
|
||||
{
|
||||
INT32 hchw;/* half-width for centering */
|
||||
|
||||
INT32 dupx;
|
||||
|
||||
font_t *font;
|
||||
|
||||
boolean uppercase;
|
||||
|
||||
fixed_t cx;
|
||||
fixed_t right;
|
||||
|
||||
fixed_t cw;
|
||||
|
||||
int c;
|
||||
|
||||
uppercase = ((flags & V_FORCEUPPERCASE) == V_FORCEUPPERCASE);
|
||||
flags &= ~(V_FLIP);/* These two (V_FORCEUPPERCASE) share a bit. */
|
||||
|
||||
font = &fontv[fontno];
|
||||
|
||||
fontspec_t fontspec;
|
||||
|
||||
V_GetFontSpecification(fontno, flags, &fontspec);
|
||||
|
||||
hchw = fontspec.chw >> 1;
|
||||
|
||||
fontspec.chw <<= FRACBITS;
|
||||
fontspec.spacew <<= FRACBITS;
|
||||
|
||||
#define Mul( id, scale ) ( id = FixedMul (scale, id) )
|
||||
Mul (fontspec.chw, scale);
|
||||
Mul (fontspec.spacew, scale);
|
||||
Mul (fontspec.lfh, scale);
|
||||
|
||||
Mul (fontspec.spacew, spacescale);
|
||||
Mul (fontspec.lfh, lfscale);
|
||||
#undef Mul
|
||||
|
||||
if (( flags & V_NOSCALESTART ))
|
||||
{
|
||||
dupx = vid.dupx;
|
||||
|
||||
hchw *= dupx;
|
||||
|
||||
fontspec.chw *= dupx;
|
||||
fontspec.spacew *= dupx;
|
||||
fontspec.lfh *= vid.dupy;
|
||||
}
|
||||
else
|
||||
{
|
||||
dupx = 1;
|
||||
}
|
||||
|
||||
cx = 0;
|
||||
right = 0;
|
||||
|
||||
size_t i = 0, start = 0;
|
||||
fixed_t cxatstart = 0;
|
||||
|
||||
for (; ( c = newstring[i] ); ++i)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
cx = 0;
|
||||
cxatstart = 0;
|
||||
start = 0;
|
||||
break;
|
||||
default:
|
||||
if (( c & 0x80 ))
|
||||
continue;
|
||||
|
||||
if (uppercase)
|
||||
{
|
||||
c = toupper(c);
|
||||
}
|
||||
else if (V_CharacterValid(font, c - font->start) == false)
|
||||
{
|
||||
// Try the other case if it doesn't exist
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
{
|
||||
c = tolower(c);
|
||||
}
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
{
|
||||
c = toupper(c);
|
||||
}
|
||||
}
|
||||
|
||||
c -= font->start;
|
||||
if (V_CharacterValid(font, c) == true)
|
||||
{
|
||||
cw = SHORT (font->font[c]->width) * dupx;
|
||||
|
||||
// How bunched dims work is by incrementing cx slightly less than a full character width.
|
||||
// This causes the next character to be drawn overlapping the previous.
|
||||
// We need to count the full width to get the rightmost edge of the string though.
|
||||
right = cx + (cw * scale);
|
||||
|
||||
(*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw);
|
||||
cx += cw;
|
||||
}
|
||||
else
|
||||
{
|
||||
right = (cx += fontspec.spacew);
|
||||
cxatstart = cx;
|
||||
start = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Start trying to wrap if presumed length exceeds the space we have on-screen.
|
||||
if (start != 0 && right > w)
|
||||
{
|
||||
newstring[start] = '\n';
|
||||
cx -= cxatstart;
|
||||
start = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void V_DrawCenteredString(INT32 x, INT32 y, INT32 option, const char *string)
|
||||
{
|
||||
x -= V_StringWidth(string, option)/2;
|
||||
|
|
|
|||
|
|
@ -273,9 +273,6 @@ UINT8 *V_GetStringColormap(INT32 colorflags);
|
|||
|
||||
INT32 V_LevelNameHeight(const char *string);
|
||||
|
||||
// wordwrap a string using the hu_font
|
||||
char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string);
|
||||
|
||||
// draw a string using a font
|
||||
void V_DrawStringScaled(
|
||||
fixed_t x,
|
||||
|
|
@ -296,6 +293,15 @@ fixed_t V_StringScaledWidth(
|
|||
int fontno,
|
||||
const char *s);
|
||||
|
||||
void V_ScaledWordWrap(
|
||||
fixed_t w,
|
||||
fixed_t scale,
|
||||
fixed_t spacescale,
|
||||
fixed_t lfscale,
|
||||
INT32 flags,
|
||||
int fontno,
|
||||
char *newstring);
|
||||
|
||||
// draw a string using the hu_font
|
||||
#define V_DrawString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,NULL,HU_FONT,string)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue