Merge branch 'font_drawer' into 'next'

Refactor string drawing functions

See merge request STJr/SRB2!1726
This commit is contained in:
sphere 2024-03-10 12:48:59 +00:00
commit df18cc0960
9 changed files with 394 additions and 1755 deletions

View file

@ -1707,11 +1707,11 @@ static void CON_DrawHudlines(void)
} }
if (c >= con_width) if (c >= con_width)
break; break;
if (*p < HU_FONTSTART) if (*p < FONTSTART)
;//charwidth = 4 * con_scalefactor; ;//charwidth = 4 * con_scalefactor;
else else
{ {
//charwidth = (hu_font['A'-HU_FONTSTART]->width) * con_scalefactor; //charwidth = (hu_font.chars['A'-FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true);
} }
} }

View file

@ -108,6 +108,7 @@ char *nongnu_strcasestr(const char *in, const char *what);
int startswith (const char *base, const char *tag); int startswith (const char *base, const char *tag);
int endswith (const char *base, const char *tag); int endswith (const char *base, const char *tag);
char *xstrtok(char *line, const char *delims);
#if defined (_WIN32) || defined (__HAIKU__) #if defined (_WIN32) || defined (__HAIKU__)
#define HAVE_DOSSTR_FUNCS #define HAVE_DOSSTR_FUNCS

View file

@ -61,21 +61,22 @@
#define HU_CSAY 2 // Server CECHOes to everyone. #define HU_CSAY 2 // Server CECHOes to everyone.
//------------------------------------------- //-------------------------------------------
// heads up font // Fonts & stuff
//------------------------------------------- //-------------------------------------------
patch_t *hu_font[HU_FONTSIZE]; // Font definitions
patch_t *tny_font[HU_FONTSIZE]; fontdef_t hu_font;
fontdef_t tny_font;
fontdef_t cred_font;
fontdef_t lt_font;
fontdef_t ntb_font;
fontdef_t nto_font;
// Numbers
patch_t *tallnum[10]; // 0-9 patch_t *tallnum[10]; // 0-9
patch_t *nightsnum[10]; // 0-9 patch_t *nightsnum[10]; // 0-9
// Level title and credits fonts
patch_t *lt_font[LT_FONTSIZE];
patch_t *cred_font[CRED_FONTSIZE];
patch_t *ttlnum[10]; // act numbers (0-9) patch_t *ttlnum[10]; // act numbers (0-9)
patch_t *tallminus;
// Name tag fonts patch_t *tallinfin;
patch_t *ntb_font[NT_FONTSIZE];
patch_t *nto_font[NT_FONTSIZE];
static player_t *plr; static player_t *plr;
boolean chat_on; // entering a chat message? boolean chat_on; // entering a chat message?
@ -91,8 +92,6 @@ patch_t *bflagico;
patch_t *rmatcico; patch_t *rmatcico;
patch_t *bmatcico; patch_t *bmatcico;
patch_t *tagico; patch_t *tagico;
patch_t *tallminus;
patch_t *tallinfin;
//------------------------------------------- //-------------------------------------------
// coop hud // coop hud
@ -188,53 +187,26 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum);
void HU_LoadGraphics(void) void HU_LoadGraphics(void)
{ {
char buffer[9]; char buffer[9];
INT32 i, j; INT32 i;
if (dedicated) if (dedicated)
return; return;
j = HU_FONTSTART; // Cache fonts
for (i = 0; i < HU_FONTSIZE; i++, j++) HU_LoadFontCharacters(&hu_font, "STCFN");
{ HU_LoadFontCharacters(&tny_font, "TNYFN");
// cache the heads-up font for entire game execution HU_LoadFontCharacters(&cred_font, "CRFNT");
sprintf(buffer, "STCFN%.3d", j); HU_LoadFontCharacters(&lt_font, "LTFNT");
if (W_CheckNumForName(buffer) == LUMPERROR) HU_LoadFontCharacters(&ntb_font, "NTFNT");
hu_font[i] = NULL; HU_LoadFontCharacters(&nto_font, "NTFNO");
else
hu_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
// tiny version of the heads-up font // For each font, set kerning, space width, character width and line spacing
sprintf(buffer, "TNYFN%.3d", j); HU_SetFontProperties(&hu_font, 0, 4, 8, 12);
if (W_CheckNumForName(buffer) == LUMPERROR) HU_SetFontProperties(&tny_font, 0, 2, 4, 12);
tny_font[i] = NULL; HU_SetFontProperties(&cred_font, 0, 16, 16, 16);
else HU_SetFontProperties(&lt_font, 0, 16, 20, 20);
tny_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); HU_SetFontProperties(&ntb_font, 2, 4, 20, 21);
} HU_SetFontProperties(&nto_font, 0, 4, 20, 21);
j = LT_FONTSTART;
for (i = 0; i < LT_FONTSIZE; i++)
{
sprintf(buffer, "LTFNT%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
lt_font[i] = NULL;
else
lt_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// cache the credits font for entire game execution (why not?)
j = CRED_FONTSTART;
for (i = 0; i < CRED_FONTSIZE; i++)
{
sprintf(buffer, "CRFNT%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
cred_font[i] = NULL;
else
cred_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
//cache numbers too! //cache numbers too!
for (i = 0; i < 10; i++) for (i = 0; i < 10; i++)
@ -243,45 +215,14 @@ void HU_LoadGraphics(void)
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "NGTNUM%d", i); sprintf(buffer, "NGTNUM%d", i);
nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "TTL%.2d", i);
ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
} }
// minus for negative tallnums // minus for negative tallnums
tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX); tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX);
tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX); tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX);
// cache act numbers for level titles
for (i = 0; i < 10; i++)
{
sprintf(buffer, "TTL%.2d", i);
ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// cache the base name tag font for entire game execution
j = NT_FONTSTART;
for (i = 0; i < NT_FONTSIZE; i++)
{
sprintf(buffer, "NTFNT%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
ntb_font[i] = NULL;
else
ntb_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// cache the outline name tag font for entire game execution
j = NT_FONTSTART;
for (i = 0; i < NT_FONTSIZE; i++)
{
sprintf(buffer, "NTFNO%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
nto_font[i] = NULL;
else
nto_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// cache the crosshairs, don't bother to know which one is being used, // cache the crosshairs, don't bother to know which one is being used,
// just cache all 3, they're so small anyway. // just cache all 3, they're so small anyway.
for (i = 0; i < HU_CROSSHAIRS; i++) for (i = 0; i < HU_CROSSHAIRS; i++)
@ -323,6 +264,29 @@ void HU_LoadGraphics(void)
//emeraldpics[2][7] = W_CachePatchName("EMBOX8", PU_HUDGFX); -- unused //emeraldpics[2][7] = W_CachePatchName("EMBOX8", PU_HUDGFX); -- unused
} }
void HU_LoadFontCharacters(fontdef_t *font, const char *prefix)
{
char buffer[9];
INT32 i, j = FONTSTART;
for (i = 0; i < FONTSIZE; i++, j++)
{
sprintf(buffer, "%.5s%.3d", prefix, j);
if (W_CheckNumForName(buffer) == LUMPERROR)
font->chars[i] = NULL;
else
font->chars[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
}
void HU_SetFontProperties(fontdef_t *font, INT32 kerning, UINT32 spacewidth, UINT32 charwidth, UINT32 linespacing)
{
font->kerning = kerning;
font->spacewidth = spacewidth;
font->charwidth = charwidth;
font->linespacing = linespacing;
}
// Initialise Heads up // Initialise Heads up
// once at game startup. // once at game startup.
// //
@ -1117,7 +1081,7 @@ boolean HU_Responder(event_t *ev)
if (ev->type == ev_text) if (ev->type == ev_text)
{ {
if ((c < HU_FONTSTART || c > HU_FONTEND || !hu_font[c-HU_FONTSTART]) if ((c < FONTSTART || c > FONTEND || !hu_font.chars[c-FONTSTART])
&& c != ' ') // Allow spaces, of course && c != ' ') // Allow spaces, of course
{ {
return false; return false;
@ -1236,201 +1200,83 @@ boolean HU_Responder(event_t *ev)
// HEADS UP DRAWING // HEADS UP DRAWING
//====================================================================== //======================================================================
// 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.
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;
for (i = 0; i < slen; ++i)
{
c = newstring[i];
if ((UINT8)c >= 0x80 && (UINT8)c <= 0x89) //color parsing! -Inuyasha 2.16.09
continue;
if (c == '\n')
{
x = 0;
lastusablespace = 0;
continue;
}
if (!(option & V_ALLOWLOWERCASE))
c = toupper(c);
c -= HU_FONTSTART;
if (c < 0 || c >= HU_FONTSIZE || !hu_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;
}
// 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense. // 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense.
INT16 chatx = 13, chaty = 169; // let's use this as our coordinates INT16 chatx = 13, chaty = 169; // let's use this as our coordinates
// chat stuff by VincyTM LOL XD!
// HU_DrawMiniChat // HU_DrawMiniChat
static void HU_drawMiniChat(void) static void HU_drawMiniChat(void)
{ {
INT32 x = chatx+2; INT32 x = chatx+2, y;
INT32 chatheight = 0;
INT32 charwidth = 4, charheight = 6; INT32 charwidth = 4, charheight = 6;
INT32 boxw = cv_chatwidth.value; INT32 boxw = cv_chatwidth.value;
INT32 dx = 0, dy = 0; INT32 dx = 0, dy = 0;
size_t i = chat_nummsg_min;
boolean prev_linereturn = false; // a hack to prevent double \n while I have no idea why they happen in the first place.
INT32 msglines = 0;
// process all messages once without rendering anything or doing anything fancy so that we know how many lines each message has...
INT32 y;
if (!chat_nummsg_min) if (!chat_nummsg_min)
return; // needless to say it's useless to do anything if we don't have anything to draw. return; // needless to say it's useless to do anything if we don't have anything to draw.
/*if (splitscreen > 1) for (size_t i = chat_nummsg_min; i > 0; i--)
boxw = max(64, boxw/2);*/
for (; i>0; i--)
{ {
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
size_t j = 0; for(size_t j = 0; msg[j]; j++) // iterate through msg
INT32 linescount = 0;
while(msg[j]) // iterate through msg
{
if (msg[j] < HU_FONTSTART) // don't draw
{ {
if (msg[j] == '\n') // get back down. if (msg[j] == '\n') // get back down.
{ {
++j; chatheight += charheight;
if (!prev_linereturn)
{
linescount += 1;
dx = 0; dx = 0;
} }
prev_linereturn = true; else if (msg[j] >= FONTSTART)
continue;
}
else if (msg[j] & 0x80) // stolen from video.c, nice.
{ {
++j;
continue;
}
++j;
}
else
{
j++;
}
prev_linereturn = false;
dx += charwidth; dx += charwidth;
if (dx >= boxw) if (dx >= boxw)
{ {
dx = 0; dx = 0;
linescount += 1; chatheight += charheight;
}
} }
} }
dy = 0;
dx = 0; dx = 0;
msglines += linescount+1; chatheight += charheight;
if (msg) if (msg)
Z_Free(msg); Z_Free(msg);
} }
y = chaty - charheight*(msglines+1); y = chaty - (chatheight + charheight);
/*if (splitscreen) for (size_t i = 0; i < chat_nummsg_min; i++) // iterate through our hot messages
{ {
y -= BASEVIDHEIGHT/2;
if (splitscreen > 1)
y += 16;
}*/
dx = 0;
dy = 0;
i = 0;
prev_linereturn = false;
for (; i<=(chat_nummsg_min-1); i++) // iterate through our hot messages
{
INT32 clrflag = 0;
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
size_t j = 0; char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
while(msg[j]) // iterate through msg for(size_t j = 0; msg[j]; j++) // iterate through msg
{
if (msg[j] < HU_FONTSTART) // don't draw
{ {
if (msg[j] == '\n') // get back down. if (msg[j] == '\n') // get back down.
{
++j;
if (!prev_linereturn)
{ {
dy += charheight; dy += charheight;
dx = 0; dx = 0;
} }
prev_linereturn = true; else if (msg[j] & 0x80) // get colormap
continue; colormap = V_GetStringColormap(((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK);
} else if (msg[j] >= FONTSTART)
else if (msg[j] & 0x80) // stolen from video.c, nice.
{
clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK;
colormap = V_GetStringColormap(clrflag);
++j;
continue;
}
++j;
}
else
{ {
if (cv_chatbacktint.value) // on request of wolfy if (cv_chatbacktint.value) // on request of wolfy
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, true, colormap); V_DrawChatCharacter(x + dx + 2, y+dy, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, true, colormap);
}
dx += charwidth; dx += charwidth;
prev_linereturn = false;
if (dx >= boxw) if (dx >= boxw)
{ {
dx = 0; dx = 0;
dy += charheight; dy += charheight;
} }
} }
}
dy += charheight; dy += charheight;
dx = 0; dx = 0;
@ -1440,7 +1286,6 @@ static void HU_drawMiniChat(void)
// decrement addy and make that shit smooth: // decrement addy and make that shit smooth:
addy /= 2; addy /= 2;
} }
// HU_DrawChatLog // HU_DrawChatLog
@ -1485,46 +1330,30 @@ static void HU_drawChatLog(INT32 offset)
for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog
{ {
INT32 clrflag = 0; char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
INT32 j = 0;
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
while(msg[j]) // iterate through msg for(size_t j = 0; msg[j]; j++) // iterate through msg
{
if (msg[j] < HU_FONTSTART) // don't draw
{ {
if (msg[j] == '\n') // get back down. if (msg[j] == '\n') // get back down.
{ {
++j;
dy += charheight; dy += charheight;
dx = 0; dx = 0;
continue;
} }
else if (msg[j] & 0x80) // stolen from video.c, nice. else if (msg[j] & 0x80) // get colormap
{ colormap = V_GetStringColormap(((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK);
clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK; else if (msg[j] >= FONTSTART)
colormap = V_GetStringColormap(clrflag);
++j;
continue;
}
++j;
}
else
{ {
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy))) if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, true, colormap); V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, true, colormap);
else
j++; // don't forget to increment this or we'll get stuck in the limbo.
}
dx += charwidth; dx += charwidth;
if (dx >= boxw-charwidth-2 && i<chat_nummsg_log && msg[j] >= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!! if (dx >= boxw-charwidth-2 && i<chat_nummsg_log) // end of message shouldn't count, nor should invisible characters!!!!
{ {
dx = 0; dx = 0;
dy += charheight; dy += charheight;
} }
} }
}
dy += charheight; dy += charheight;
dx = 0; dx = 0;
@ -1532,30 +1361,25 @@ static void HU_drawChatLog(INT32 offset)
Z_Free(msg); Z_Free(msg);
} }
if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling. if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling.
{
atbottom = true; // we should scroll atbottom = true; // we should scroll
}
chat_scrollmedown = false; chat_scrollmedown = false;
// getmaxscroll through a lazy hack. We do all these loops, // getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P
// so let's not do more loops that are gonna lag the game more. :P
chat_maxscroll = max(dy / charheight - cv_chatheight.value, 0); chat_maxscroll = max(dy / charheight - cv_chatheight.value, 0);
// if we're not bound by the time, autoscroll for next frame: // if we're not bound by the time, autoscroll for next frame:
if (atbottom) if (atbottom)
chat_scroll = chat_maxscroll; chat_scroll = chat_maxscroll;
// draw arrows to indicate that we can (or not) scroll. // draw arrows to indicate that we can (or not) scroll, accounting for Y = -1 offset in tinyfont
// account for Y = -1 offset in tinyfont
if (chat_scroll > 0) if (chat_scroll > 0)
V_DrawThinString(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)) - 1, V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1A"); // up arrow V_DrawThinString(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)) - 1, V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1A"); // up arrow
if (chat_scroll < chat_maxscroll) if (chat_scroll < chat_maxscroll)
V_DrawThinString(chatx-8, chat_bottomy-((justscrolleddown) ? 5 : 6) - 1, V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1B"); // down arrow V_DrawThinString(chatx-8, chat_bottomy-((justscrolleddown) ? 5 : 6) - 1, V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1B"); // down arrow
justscrolleddown = false; justscrolleddown = justscrolledup = false;
justscrolledup = false;
} }
// //
@ -1587,15 +1411,7 @@ static void HU_DrawChat(void)
#endif #endif
if (teamtalk) if (teamtalk)
{
talk = ttalk; talk = ttalk;
#if 0
if (players[consoleplayer].ctfteam == 1)
t = 0x500; // Red
else if (players[consoleplayer].ctfteam == 2)
t = 0x400; // Blue
#endif
}
if (CHAT_MUTE) if (CHAT_MUTE)
{ {
@ -1609,16 +1425,10 @@ static void HU_DrawChat(void)
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
while (talk[i]) for (i = 0; talk[i]; i++)
{
if (talk[i] < HU_FONTSTART)
++i;
else
{ {
if (talk[i] >= FONTSTART)
V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, true, V_GetStringColormap(talk[i]|cflag)); V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, true, V_GetStringColormap(talk[i]|cflag));
i++;
}
c += charwidth; c += charwidth;
} }
@ -1629,13 +1439,12 @@ static void HU_DrawChat(void)
return; return;
} }
i = 0;
typelines = 1; typelines = 1;
if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4)
V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, true, NULL); V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, true, NULL);
while (w_chat[i]) for (i = 0; w_chat[i]; i++)
{ {
boolean skippedline = false; boolean skippedline = false;
if (c_input == (i+1)) if (c_input == (i+1))
@ -1652,14 +1461,11 @@ static void HU_DrawChat(void)
} }
} }
//Hurdler: isn't it better like that? if (w_chat[i] >= FONTSTART)
if (w_chat[i] < HU_FONTSTART) V_DrawChatCharacter(chatx + c + 2, y, w_chat[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, true, NULL);
++i;
else
V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, true, NULL);
c += charwidth; c += charwidth;
if (c > boxw-(charwidth*2) && !skippedline) if (c > boxw-charwidth && !skippedline)
{ {
c = 0; c = 0;
y += charheight; y += charheight;
@ -1681,8 +1487,7 @@ static void HU_DrawChat(void)
} }
#endif #endif
i = 0; for(i=0; i<MAXPLAYERS; i++)
for(i=0; (i<MAXPLAYERS); i++)
{ {
// filter: (code needs optimization pls help I'm bad with C) // filter: (code needs optimization pls help I'm bad with C)
if (w_chat[3]) if (w_chat[3])
@ -1697,32 +1502,16 @@ static void HU_DrawChat(void)
playernum[3] = 0; playernum[3] = 0;
n = atoi(playernum); // turn that into a number n = atoi(playernum); // turn that into a number
// special cases: // special cases:
if ((n == 0) && !(w_chat[4] == '0') && (!(i<10)))
if ((n == 0) && !(w_chat[4] == '0'))
{
if (!(i<10))
continue; continue;
} else if ((n == 1) && !(w_chat[3] == '0') && (!((i == 1) || ((i >= 10) && (i <= 19)))))
else if ((n == 1) && !(w_chat[3] == '0'))
{
if (!((i == 1) || ((i >= 10) && (i <= 19))))
continue; continue;
} else if ((n == 2) && !(w_chat[3] == '0') && (!((i == 2) || ((i >= 20) && (i <= 29)))))
else if ((n == 2) && !(w_chat[3] == '0'))
{
if (!((i == 2) || ((i >= 20) && (i <= 29))))
continue; continue;
} else if ((n == 3) && !(w_chat[3] == '0') && (!((i == 3) || ((i >= 30) && (i <= 31)))))
else if ((n == 3) && !(w_chat[3] == '0'))
{
if (!((i == 3) || ((i >= 30) && (i <= 31))))
continue; continue;
}
else // general case. else // general case.
{ if (i != n) continue;
if (i != n)
continue;
}
} }
if (playeringame[i]) if (playeringame[i])
@ -1753,41 +1542,22 @@ static void HU_DrawChat_Old(void)
size_t i = 0; size_t i = 0;
const char *ntalk = "Say: ", *ttalk = "Say-Team: "; const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
const char *talk = ntalk; const char *talk = ntalk;
INT32 charwidth = 8 * con_scalefactor; //(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor; INT32 charwidth = 8 * con_scalefactor, charheight = 8 * con_scalefactor;
INT32 charheight = 8 * con_scalefactor; //(hu_font['A'-HU_FONTSTART]->height) * con_scalefactor;
if (teamtalk) if (teamtalk)
{
talk = ttalk; talk = ttalk;
#if 0
if (players[consoleplayer].ctfteam == 1)
t = 0x500; // Red
else if (players[consoleplayer].ctfteam == 2)
t = 0x400; // Blue
#endif
}
while (talk[i]) for (i = 0; talk[i]; i++)
{ {
if (talk[i] < HU_FONTSTART) if (talk[i] >= FONTSTART)
{ V_DrawCharacter(HU_INPUTX + c, y, talk[i] | cv_constextsize.value | V_NOSCALESTART, true);
++i;
//charwidth = 4 * con_scalefactor;
}
else
{
//charwidth = (hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, true);
}
c += charwidth; c += charwidth;
} }
if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4)
V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, true); V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, true);
i = 0; for (i = 0; w_chat[i]; i++)
while (w_chat[i])
{ {
if (c_input == (i+1) && hu_tick < 4) if (c_input == (i+1) && hu_tick < 4)
{ {
INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down. INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down.
@ -1795,17 +1565,8 @@ static void HU_DrawChat_Old(void)
V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, true); V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, true);
} }
//Hurdler: isn't it better like that? if (w_chat[i] >= FONTSTART)
if (w_chat[i] < HU_FONTSTART) V_DrawCharacter(HU_INPUTX + c, y, w_chat[i] | cv_constextsize.value | V_NOSCALESTART | t, true);
{
++i;
//charwidth = 4 * con_scalefactor;
}
else
{
//charwidth = (hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, true);
}
c += charwidth; c += charwidth;
if (c >= vid.width) if (c >= vid.width)
@ -1814,9 +1575,6 @@ static void HU_DrawChat_Old(void)
y += charheight; y += charheight;
} }
} }
if (hu_tick < 4)
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true);
} }
// Draw crosshairs at the exact center of the view. // Draw crosshairs at the exact center of the view.
@ -1902,21 +1660,6 @@ static void HU_DrawCEcho(void)
} }
} }
static void HU_drawGametype(void)
{
const char *strvalue = NULL;
if (gametype < 0 || gametype >= gametypecount)
return; // not a valid gametype???
strvalue = Gametype_Names[gametype];
if (splitscreen)
V_DrawString(4, 184, 0, strvalue);
else
V_DrawString(4, 192, 0, strvalue);
}
// //
// demo info stuff // demo info stuff
// //
@ -2778,7 +2521,8 @@ static void HU_DrawRankings(void)
UINT32 whiteplayer; UINT32 whiteplayer;
// draw the current gametype in the lower right // draw the current gametype in the lower right
HU_drawGametype(); if (gametype >= 0 && gametype < gametypecount)
V_DrawString(4, splitscreen ? 184 : 192, 0, Gametype_Names[gametype]);
if (gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)) if (gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT))
{ {

View file

@ -19,33 +19,34 @@
#include "r_defs.h" #include "r_defs.h"
//------------------------------------ //------------------------------------
// heads up font // Fonts & stuff
//------------------------------------ //------------------------------------
#define HU_FONTSTART '\x16' // the first font character #define FONTSTART '\x16' // the first font character
#define HU_FONTEND '~' #define FONTEND '~'
#define FONTSIZE (FONTEND - FONTSTART + 1)
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
// Level title font
#define LT_FONTSTART '!' // the first font characters
#define LT_FONTEND 'z' // the last font characters
#define LT_FONTSIZE (LT_FONTEND - LT_FONTSTART + 1)
#define CRED_FONTSTART '!' // the first font character
#define CRED_FONTEND 'Z' // the last font character
#define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1)
// Name tag font
// Used by base and outline font set
#define NT_FONTSTART '!' // the first font character
#define NT_FONTEND 'Z' // the last font character
#define NT_FONTSIZE (NT_FONTEND - NT_FONTSTART + 1)
#define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init(); #define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init();
extern char *shiftxform; // english translation shift table extern char *shiftxform; // english translation shift table
extern char english_shiftxform[]; extern char english_shiftxform[];
typedef struct
{
patch_t *chars[FONTSIZE];
INT32 kerning;
UINT32 spacewidth;
UINT32 charwidth;
UINT32 linespacing;
} fontdef_t;
extern fontdef_t hu_font, tny_font, cred_font, lt_font;
extern fontdef_t ntb_font, nto_font;
extern patch_t *tallnum[10];
extern patch_t *nightsnum[10];
extern patch_t *ttlnum[10];
extern patch_t *tallminus;
extern patch_t *tallinfin;
//------------------------------------ //------------------------------------
// sorted player lines // sorted player lines
//------------------------------------ //------------------------------------
@ -78,22 +79,12 @@ void HU_AddChatText(const char *text, boolean playsound);
// set true when entering a chat message // set true when entering a chat message
extern boolean chat_on; extern boolean chat_on;
extern patch_t *hu_font[HU_FONTSIZE], *tny_font[HU_FONTSIZE];
extern patch_t *tallnum[10];
extern patch_t *nightsnum[10];
extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *ntb_font[NT_FONTSIZE];
extern patch_t *nto_font[NT_FONTSIZE];
extern patch_t *ttlnum[10];
extern patch_t *emeraldpics[3][8]; extern patch_t *emeraldpics[3][8];
extern patch_t *rflagico; extern patch_t *rflagico;
extern patch_t *bflagico; extern patch_t *bflagico;
extern patch_t *rmatcico; extern patch_t *rmatcico;
extern patch_t *bmatcico; extern patch_t *bmatcico;
extern patch_t *tagico; extern patch_t *tagico;
extern patch_t *tallminus;
extern patch_t *tallinfin;
extern patch_t *tokenicon; extern patch_t *tokenicon;
// set true whenever the tab rankings are being shown for any reason // set true whenever the tab rankings are being shown for any reason
@ -103,6 +94,8 @@ extern boolean hu_showscores;
void HU_Init(void); void HU_Init(void);
void HU_LoadGraphics(void); void HU_LoadGraphics(void);
void HU_LoadFontCharacters(fontdef_t *font, const char *prefix);
void HU_SetFontProperties(fontdef_t *font, INT32 kerning, UINT32 spacewidth, UINT32 charwidth, UINT32 linespacing);
// reset heads up when consoleplayer respawns. // reset heads up when consoleplayer respawns.
void HU_Start(void); void HU_Start(void);

View file

@ -4956,22 +4956,6 @@ static void M_DrawCenteredMenu(void)
} }
} }
//
// M_StringHeight
//
// Find string height from hu_font chars
//
static inline size_t M_StringHeight(const char *string)
{
size_t h = 8, i;
for (i = 0; i < strlen(string); i++)
if (string[i] == '\n')
h += 8;
return h;
}
// ========================================================================== // ==========================================================================
// Extraneous menu patching functions // Extraneous menu patching functions
// ========================================================================== // ==========================================================================
@ -6089,56 +6073,16 @@ menu_t MessageDef =
NULL NULL
}; };
void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype)
void M_StartMessage(const char *string, void *routine,
menumessagetype_t itemtype)
{ {
size_t max = 0, start = 0, i, strlines; static char *message;
static char *message = NULL;
Z_Free(message); Z_Free(message);
message = Z_StrDup(string); message = V_WordWrap(0,0,V_ALLOWLOWERCASE,string);
DEBFILE(message); DEBFILE(message);
// Rudementary word wrapping.
// Simple and effective. Does not handle nonuniform letter sizes, colors, etc. but who cares.
strlines = 0;
for (i = 0; message[i]; i++)
{
if (message[i] == ' ')
{
start = i;
max += 4;
}
else if (message[i] == '\n')
{
strlines = i;
start = 0;
max = 0;
continue;
}
else
max += 8;
// Start trying to wrap if presumed length exceeds the screen width.
if (max >= BASEVIDWIDTH && start > 0)
{
message[start] = '\n';
max -= (start-strlines)*8;
strlines = start;
start = 0;
}
}
start = 0;
max = 0;
M_StartControlPanel(); // can't put menuactive to true M_StartControlPanel(); // can't put menuactive to true
if (currentMenu == &MessageDef) // Prevent recursion MessageDef.prevMenu = (currentMenu == &MessageDef) ? &MainDef : currentMenu; // Prevent recursion
MessageDef.prevMenu = &MainDef;
else
MessageDef.prevMenu = currentMenu;
MessageDef.menuitems[0].text = message; MessageDef.menuitems[0].text = message;
MessageDef.menuitems[0].alphaKey = (UINT8)itemtype; MessageDef.menuitems[0].alphaKey = (UINT8)itemtype;
if (!routine && itemtype != MM_NOTHING) itemtype = MM_NOTHING; if (!routine && itemtype != MM_NOTHING) itemtype = MM_NOTHING;
@ -6157,51 +6101,17 @@ void M_StartMessage(const char *string, void *routine,
MessageDef.menuitems[0].itemaction = routine; MessageDef.menuitems[0].itemaction = routine;
break; break;
} }
//added : 06-02-98: now draw a textbox around the message MessageDef.x = (INT16)((BASEVIDWIDTH - V_StringWidth(message, 0)-32)/2);
// compute lenght max and the numbers of lines MessageDef.y = (INT16)((BASEVIDHEIGHT - V_StringHeight(message, V_RETURN8))/2);
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;
}
MessageDef.x = (INT16)((BASEVIDWIDTH - 8*max-16)/2);
MessageDef.y = (INT16)((BASEVIDHEIGHT - M_StringHeight(message))/2);
MessageDef.lastOn = (INT16)((strlines<<8)+max);
//M_SetupNextMenu();
currentMenu = &MessageDef; currentMenu = &MessageDef;
itemOn = 0; itemOn = 0;
} }
#define MAXMSGLINELEN 256
static void M_DrawMessageMenu(void) static void M_DrawMessageMenu(void)
{ {
INT32 y = currentMenu->y;
size_t i, start = 0;
INT16 max;
char string[MAXMSGLINELEN];
INT32 mlines;
const char *msg = currentMenu->menuitems[0].text; const char *msg = currentMenu->menuitems[0].text;
mlines = currentMenu->lastOn>>8;
max = (INT16)((UINT8)(currentMenu->lastOn & 0xFF)*8);
// hack: draw RA background in RA menus // hack: draw RA background in RA menus
if (gamestate == GS_TIMEATTACK) if (gamestate == GS_TIMEATTACK)
{ {
@ -6225,51 +6135,8 @@ static void M_DrawMessageMenu(void)
V_DrawFadeScreen(0xFF00, curfadevalue); V_DrawFadeScreen(0xFF00, curfadevalue);
} }
M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines); M_DrawTextBox(currentMenu->x, currentMenu->y - 8, 2+V_StringWidth(msg, 0)/8, V_StringHeight(msg, V_RETURN8)/8);
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y, V_ALLOWLOWERCASE|V_RETURN8, msg);
while (*(msg+start))
{
size_t len = strlen(msg+start);
for (i = 0; i < len; i++)
{
if (*(msg+start+i) == '\n')
{
memset(string, 0, MAXMSGLINELEN);
if (i >= MAXMSGLINELEN)
{
CONS_Printf("M_DrawMessageMenu: too long segment in %s\n", msg);
return;
}
else
{
strncpy(string,msg+start, i);
string[i] = '\0';
start += i;
i = (size_t)-1; //added : 07-02-98 : damned!
start++;
}
break;
}
}
if (i == strlen(msg+start))
{
if (i >= MAXMSGLINELEN)
{
CONS_Printf("M_DrawMessageMenu: too long segment in %s\n", msg);
return;
}
else
{
strcpy(string, msg + start);
start += i;
}
}
V_DrawString((BASEVIDWIDTH - V_StringWidth(string, 0))/2,y,V_ALLOWLOWERCASE,string);
y += 8; //hu_font[0]->height;
}
} }
// default message handler // default message handler
@ -7956,7 +7823,7 @@ static void M_DrawSoundTest(void)
{ {
V_DrawFill(165+140-9, y-4, 8, 16, 150); V_DrawFill(165+140-9, y-4, 8, 16, 150);
//V_DrawCharacter(165+140-8, y, '\x19' | V_YELLOWMAP, false); //V_DrawCharacter(165+140-8, y, '\x19' | V_YELLOWMAP, false);
V_DrawFixedPatch((165+140-9)<<FRACBITS, (y<<FRACBITS)-(bounce*4), FRACUNIT, 0, hu_font['\x19'-HU_FONTSTART], V_GetStringColormap(V_YELLOWMAP)); V_DrawFixedPatch((165+140-9)<<FRACBITS, (y<<FRACBITS)-(bounce*4), FRACUNIT, 0, hu_font.chars['\x19'-FONTSTART], V_GetStringColormap(V_YELLOWMAP));
} }
} }
t++; t++;

View file

@ -509,7 +509,7 @@ static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fix
static void ST_drawDebugInfo(void) static void ST_drawDebugInfo(void)
{ {
INT32 height = 0, h = 8, w = 18, lowh; INT32 height = 0, h = 8, w = 18, lowh;
void (*textfunc)(INT32, INT32, INT32, const char *); fixed_t textscale = FRACUNIT/2;
if (!(stplyr->mo && cv_debug)) if (!(stplyr->mo && cv_debug))
return; return;
@ -518,12 +518,12 @@ static void ST_drawDebugInfo(void)
if ((moviemode == MM_GIF && cv_gif_downscale.value) || vid.dup == 1) if ((moviemode == MM_GIF && cv_gif_downscale.value) || vid.dup == 1)
{ {
textfunc = V_DrawRightAlignedString; textscale = FRACUNIT;
lowh = ((vid.height/vid.dup) - 16); lowh = ((vid.height/vid.dup) - 16);
} }
else else
{ {
textfunc = V_DrawRightAlignedSmallString; textscale = FRACUNIT/2;
h /= 2; h /= 2;
w /= 2; w /= 2;
lowh = 0; lowh = 0;
@ -534,10 +534,10 @@ static void ST_drawDebugInfo(void)
V_DrawRightAlignedThinString(320, 8+lowh, VFLAGS|V_REDMAP, "SOME INFO NOT VISIBLE");\ V_DrawRightAlignedThinString(320, 8+lowh, VFLAGS|V_REDMAP, "SOME INFO NOT VISIBLE");\
return;\ return;\
}\ }\
textfunc(320, height, VFLAGS, str);\ V_DrawAlignedFontString(320, height, VFLAGS, textscale, textscale, str, hu_font, alignright);\
height += h; height += h;
#define V_DrawDebugFlag(f, str) textfunc(width, height, VFLAGS|f, str);\ #define V_DrawDebugFlag(f, str) V_DrawAlignedFontString(width, height, VFLAGS|f, textscale, textscale, str, hu_font, alignright);\
width -= w width -= w
if (cv_debug & DBG_MEMORY) if (cv_debug & DBG_MEMORY)

View file

@ -68,3 +68,27 @@ int endswith(const char *base, const char *tag)
return !memcmp(&base[base_length - tag_length], tag, tag_length); return !memcmp(&base[base_length - tag_length], tag, tag_length);
} }
// strtok version that only skips over one delimiter at a time
char *xstrtok(char *line, const char *delims)
{
static char *saveline = NULL;
char *p;
if(line != NULL)
saveline = line;
// see if we have reached the end of the line
if(saveline == NULL || *saveline == '\0')
return NULL;
p = saveline; // save start of this token
saveline += strcspn(saveline, delims); // get the number of non-delims characters, go past delimiter
if(*saveline != '\0') // trash the delim if necessary
*saveline++ = '\0';
return p;
}

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@
#include "doomdef.h" #include "doomdef.h"
#include "doomtype.h" #include "doomtype.h"
#include "r_defs.h" #include "r_defs.h"
#include "hu_stuff.h" //font arrays
// //
// VIDEO // VIDEO
@ -191,86 +192,93 @@ void V_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c, UINT16 color, U
void V_DrawFadeConsBack(INT32 plines); void V_DrawFadeConsBack(INT32 plines);
void V_DrawPromptBack(INT32 boxheight, INT32 color); void V_DrawPromptBack(INT32 boxheight, INT32 color);
// draw a single character
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed);
// draw a single character, but for the chat
void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap);
UINT8 *V_GetStringColormap(INT32 colorflags); UINT8 *V_GetStringColormap(INT32 colorflags);
void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string); // Generalized character drawing function, combining console & chat functionality with a specified font.
void V_DrawFontCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, fixed_t scale, UINT8 *colormap, fontdef_t font);
#define V_DrawCharacter(x,y,c,l) V_DrawFontCharacter(x,y,c,l,FRACUNIT,NULL,hu_font)
#define V_DrawChatCharacter(x,y,c,l,cm) V_DrawFontCharacter(x,y,c,l,FRACUNIT/2,cm,hu_font)
// wordwrap a string using the hu_font // Precompile a wordwrapped string to any given width, using a specified font.
char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string); char *V_FontWordWrap(INT32 x, INT32 w, INT32 option, fixed_t scale, const char *string, fontdef_t font);
UINT8 *V_GetStringColormap(INT32 colorflags); #define V_WordWrap(x,w,o,str) V_FontWordWrap(x, w, o, FRACUNIT, str, hu_font)
#define V_ChatWordWrap(x,w,o,str) V_FontWordWrap(x, w, o, FRACUNIT/2, str, hu_font)
enum string_align {
alignleft = 0,
aligncenter,
alignright
};
// Draw a string, using a supplied font and scale.
void V_DrawFontString(INT32 x, INT32 y, INT32 option, fixed_t pscale, fixed_t vscale, const char *string, fontdef_t font);
void V_DrawAlignedFontString(INT32 x, INT32 y, INT32 option, fixed_t pscale, fixed_t vscale, const char *string, fontdef_t font, enum string_align align);
// Draw a string, using a supplied font and scale, at fixed_t coordinates.
void V_DrawFontStringAtFixed(fixed_t x, fixed_t y, INT32 option, fixed_t pscale, fixed_t vscale, const char *string, fontdef_t font);
void V_DrawAlignedFontStringAtFixed(fixed_t x, fixed_t y, INT32 option, fixed_t pscale, fixed_t vscale, const char *string, fontdef_t font, enum string_align align);
// Defines for old string drawers.
// draw a string using the hu_font // draw a string using the hu_font
void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawString(x,y,o,str) V_DrawFontString(x,y,o,FRACUNIT,FRACUNIT,str,hu_font)
void V_DrawCenteredString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawCenteredString(x,y,o,str) V_DrawAlignedFontString(x,y,o,FRACUNIT,FRACUNIT,str,hu_font,aligncenter)
void V_DrawRightAlignedString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawRightAlignedString(x,y,o,str) V_DrawAlignedFontString(x,y,o,FRACUNIT,FRACUNIT,str,hu_font,alignright)
// draw a string using the hu_font, 0.5x scale // draw a string using the hu_font, 0.5x scale
void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawSmallString(x,y,o,str) V_DrawFontString(x,y,o,FRACUNIT/2,FRACUNIT/2,str,hu_font)
void V_DrawCenteredSmallString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawCenteredSmallString(x,y,o,str) V_DrawAlignedFontString(x,y,o,FRACUNIT/2,FRACUNIT/2,str,hu_font,aligncenter)
void V_DrawRightAlignedSmallString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawRightAlignedSmallString(x,y,o,str) V_DrawAlignedFontString(x,y,o,FRACUNIT/2,FRACUNIT/2,str,hu_font,alignright)
// Write a string using the tny_font
// draw a string using the tny_font #define V_DrawThinString(x,y,o,str) V_DrawFontString(x,y,o,FRACUNIT,FRACUNIT,str,tny_font)
void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawCenteredThinString(x,y,o,str) V_DrawAlignedFontString(x,y,o,FRACUNIT,FRACUNIT,str,tny_font,aligncenter)
void V_DrawCenteredThinString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawRightAlignedThinString(x,y,o,str) V_DrawAlignedFontString(x,y,o,FRACUNIT,FRACUNIT,str,tny_font,alignright)
void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *string);
// draw a string using the tny_font, 0.5x scale // draw a string using the tny_font, 0.5x scale
void V_DrawSmallThinString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawSmallThinString(x,y,o,str) V_DrawFontString(x,y,o,FRACUNIT/2,FRACUNIT/2,str,tny_font)
void V_DrawCenteredSmallThinString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawCenteredSmallThinString(x,y,o,str) V_DrawAlignedFontString(x,y,o,FRACUNIT/2,FRACUNIT/2,str,tny_font,aligncenter)
void V_DrawRightAlignedSmallThinString(INT32 x, INT32 y, INT32 option, const char *string); #define V_DrawRightAlignedSmallThinString(x,y,o,str) V_DrawAlignedFontString(x,y,o,FRACUNIT/2,FRACUNIT/2,str,tny_font,alignright)
// draw a string using the hu_font at fixed_t coordinates // draw a string using the hu_font at fixed_t coordinates
void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawStringAtFixed(x,y,o,str) V_DrawFontStringAtFixed(x,y,o,FRACUNIT,FRACUNIT,str,hu_font)
void V_DrawCenteredStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawCenteredStringAtFixed(x,y,o,str) V_DrawAlignedFontStringAtFixed(x,y,o,FRACUNIT,FRACUNIT,str,hu_font,aligncenter)
void V_DrawRightAlignedStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawRightAlignedStringAtFixed(x,y,o,str) V_DrawAlignedFontStringAtFixed(x,y,o,FRACUNIT,FRACUNIT,str,hu_font,alignright)
// draw a string using the hu_font at fixed_t coordinates, 0.5x scale // draw a string using the hu_font at fixed_t coordinates, 0.5x scale
void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawSmallStringAtFixed(x,y,o,str) V_DrawFontStringAtFixed(x,y,o,FRACUNIT/2,FRACUNIT/2,str,hu_font)
void V_DrawCenteredSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawCenteredSmallStringAtFixed(x,y,o,str) V_DrawAlignedFontStringAtFixed(x,y,o,FRACUNIT/2,FRACUNIT/2,str,hu_font,aligncenter)
void V_DrawRightAlignedSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawRightAlignedSmallStringAtFixed(x,y,o,str) V_DrawAlignedFontStringAtFixed(x,y,o,FRACUNIT/2,FRACUNIT/2,str,hu_font,alignright)
// draw a string using the tny_font at fixed_t coordinates // draw a string using the tny_font at fixed_t coordinates
void V_DrawThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawThinStringAtFixed(x,y,o,str) V_DrawFontStringAtFixed(x,y,o,FRACUNIT,FRACUNIT,str,tny_font)
void V_DrawCenteredThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawCenteredThinStringAtFixed(x,y,o,str) V_DrawAlignedFontStringAtFixed(x,y,o,FRACUNIT,FRACUNIT,str,tny_font,aligncenter)
void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawRightAlignedThinStringAtFixed(x,y,o,str) V_DrawAlignedFontStringAtFixed(x,y,o,FRACUNIT,FRACUNIT,str,tny_font,alignright)
// draw a string using the tny_font at fixed_t coordinates, 0.5x scale // draw a string using the tny_font at fixed_t coordinates, 0.5x scale
void V_DrawSmallThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawSmallThinStringAtFixed(x,y,o,str) V_DrawFontStringAtFixed(x,y,o,FRACUNIT/2,FRACUNIT/2,str,tny_font)
void V_DrawCenteredSmallThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawCenteredSmallThinStringAtFixed(x,y,o,str) V_DrawAlignedFontStringAtFixed(x,y,o,FRACUNIT/2,FRACUNIT/2,str,tny_font,aligncenter)
void V_DrawRightAlignedSmallThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string); #define V_DrawRightAlignedSmallThinStringAtFixed(x,y,o,str) V_DrawAlignedFontStringAtFixed(x,y,o,FRACUNIT/2,FRACUNIT/2,str,tny_font,alignright)
// draw a string using the credit font
#define V_DrawCreditString(x,y,o,str) V_DrawFontStringAtFixed(x,y,o,FRACUNIT,FRACUNIT,str,cred_font)
// draw a string using the level title font
#define V_DrawLevelTitle(x,y,o,str) V_DrawFontString(x,y,o|V_ALLOWLOWERCASE,FRACUNIT,FRACUNIT,str,lt_font)
// Draw tall nums, used for menu, HUD, intermission // Draw tall nums, used for menu, HUD, intermission
void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num); void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num);
void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits); void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits);
void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num); void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num);
// Find string width from lt_font chars
INT32 V_LevelNameWidth(const char *string);
INT32 V_LevelNameHeight(const char *string);
INT16 V_LevelActNumWidth(UINT8 num); // act number width 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);
// Draw a string using the nt_font // 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); void V_DrawNameTag(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string);
INT32 V_CountNameTagLines(const char *string); INT32 V_CountNameTagLines(const char *string);
INT32 V_NameTagWidth(const char *string);
// Find string width from hu_font chars // Find string width or height from supplied font chars
INT32 V_StringWidth(const char *string, INT32 option); INT32 V_FontStringWidth(const char *string, INT32 option, fontdef_t font);
// Find string width from hu_font chars, 0.5x scale INT32 V_FontStringHeight(const char *string, INT32 option, fontdef_t font);
INT32 V_SmallStringWidth(const char *string, INT32 option);
// Find string width from tny_font chars // Defines for old string width functions.
INT32 V_ThinStringWidth(const char *string, INT32 option); #define V_StringWidth(str,o) V_FontStringWidth(str,o,hu_font)
// Find string width from tny_font chars, 0.5x scale #define V_SmallStringWidth(str,o) V_FontStringWidth(str,o,hu_font)/2
INT32 V_SmallThinStringWidth(const char *string, INT32 option); #define V_ThinStringWidth(str,o) V_FontStringWidth(str,o,tny_font)
#define V_SmallThinStringWidth(str,o) V_FontStringWidth(str,o,tny_font)/2
#define V_CreditStringWidth(str) V_FontStringWidth(str,0,cred_font)
#define V_NameTagWidth(str) V_FontStringWidth(str,0,ntb_font)
#define V_LevelNameWidth(str) V_FontStringWidth(str,V_ALLOWLOWERCASE,lt_font)
#define V_LevelNameHeight(str) V_FontStringHeight(str,0,lt_font)
#define V_StringHeight(str,o) V_FontStringHeight(str,o,hu_font)
void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param); void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param);