Optimize all gametext calls.

git-svn-id: https://svn.eduke32.com/eduke32@6210 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
hendricks266 2017-06-20 09:28:42 +00:00
parent cb8dc04660
commit 611031d9e8
9 changed files with 85 additions and 94 deletions

View file

@ -422,7 +422,7 @@ static void Demo_DisplayProfStatus(void)
clearallviews(0);
Bsnprintf(buf, sizeof(buf), "timing... %d/%d game tics (%d %%)",
g_demo_cnt, g_demo_totalCnt, percent);
gametext(160,60, buf, 0, 2+8+16);
gametext_center(60, buf);
nextpage();
}
@ -872,23 +872,23 @@ nextdemo_nomenu:
if (!Demo_IsProfiling() && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0)
{
if (demoplay_showsync && outofsync)
gametext(160,100,"OUT OF SYNC",0,2+8+16);
gametext_center(100, "OUT OF SYNC");
if (g_demo_showStats)
{
#if 0
if (g_demo_cnt<tmpdifftime)
gametext(160,100,"DIFF",0,2+8+16);
gametext_center(100, "DIFF");
{
char buf[32];
Bsprintf(buf, "RC:%4d TC:%5d", ud.reccnt, g_demo_cnt);
gametext(160,100,buf,0,2+8+16);
gametext_center(100, buf);
}
#endif
j=g_demo_cnt/REALGAMETICSPERSEC;
Bsprintf(buf, "%02d:%02d", j/60, j%60);
gametext(18,16,buf,0,2+8+16+1024);
gametext_bits(18, 16, buf, 1024);
rotatesprite(60<<16,16<<16,32768,0,SLIDEBAR,0,0,2+8+16+1024,0,0,(xdim*95)/320,ydim-1);
rotatesprite(90<<16,16<<16,32768,0,SLIDEBAR,0,0,2+8+16+1024,(xdim*95)/320,0,(xdim*125)/320,ydim-1);
@ -900,7 +900,7 @@ nextdemo_nomenu:
j=(g_demo_totalCnt-g_demo_cnt)/REALGAMETICSPERSEC;
Bsprintf(buf, "-%02d:%02d%s", j/60, j%60, g_demo_paused?" ^15PAUSED":"");
gametext(194,16,buf,0,2+8+16+1024);
gametext_bits(194, 16, buf, 1024);
}
}
@ -908,7 +908,7 @@ nextdemo_nomenu:
Net_GetPackets();
if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex)
gametext(160,60,"Press F1 to Accept, F2 to Decline",0,2+8+16);
gametext_center(60, "Press F1 to Accept, F2 to Decline");
}
if ((g_player[myconnectindex].ps->gm&MODE_MENU) && (g_player[myconnectindex].ps->gm&MODE_EOL))

View file

@ -2940,7 +2940,7 @@ nullquote:
continue;
}
G_PrintGameText(0, tilenum, pos.x >> 1, pos.y, apStrings[nQuote], shade, pal, orientation, bound1.x, bound1.y, bound2.x, bound2.y, z, 0);
G_PrintGameText(tilenum, pos.x >> 1, pos.y, apStrings[nQuote], shade, pal, orientation, bound1.x, bound1.y, bound2.x, bound2.y, z, 0);
continue;
}

View file

@ -707,9 +707,10 @@ void S_SetMusicPosition(int32_t position);
int32_t minitext_(int32_t x,int32_t y,const char *t,int32_t s,int32_t p,int32_t sb);
void G_DrawTXDigiNumZ(int32_t starttile, int32_t x,int32_t y,int32_t n,int32_t s,int32_t pal,
int32_t cs,int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z);
int32_t G_PrintGameText(int32_t f, int32_t tile, int32_t x, int32_t y, const char *t,
void G_PrintGameText(int32_t tile, int32_t x, int32_t y, const char *t,
int32_t s, int32_t p, int32_t o,
int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z);
int32_t x1, int32_t y1, int32_t x2, int32_t y2,
int32_t z, int32_t a);
vec2_t G_ScreenText(const int32_t font,
int32_t x, int32_t y, const int32_t z, const int32_t blockangle, const int32_t charangle,
const char *str, const int32_t shade, int32_t pal, int32_t o, int32_t alpha,

View file

@ -998,7 +998,7 @@ function _gametext(tilenum, x, y, qnum, shade, pal, orientation,
orientation = text_check_common(tilenum, orientation)
local cstr = bcheck.quote_idx(qnum)
ffiC.G_PrintGameText(0, tilenum, bit.arshift(x,1), y, cstr, shade, pal,
ffiC.G_PrintGameText(tilenum, bit.arshift(x,1), y, cstr, shade, pal,
orientation, cx1, cy1, cx2, cy2, zoom)
end
-- XXX: JIT-compiling FFI calls to G_PrintGameText crashes LuaJIT somewhere in

View file

@ -219,7 +219,7 @@ void Net_WaitForServer(void)
display_betascreen();
gametext(160,170,"Waiting for server",14,2);
gametext_center_shade(170, "Waiting for server", 14);
nextpage();
packbuf[0] = PACKET_PLAYER_PING;
@ -1743,7 +1743,7 @@ void Net_SendMessage(void)
else if (g_netClient) enet_peer_send(g_netClientPeer, CHAN_CHAT, enet_packet_create(tempbuf, j+2, 0));
G_AddUserQuote(recbuf);
quotebot += 8;
l = G_GameTextLen(USERQUOTE_LEFTOFFSET,OSD_StripColors(tempbuf,recbuf));
l = G_GameTextLen(USERQUOTE_LEFTOFFSET, recbuf);
while (l > (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET))
{
l -= (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET);
@ -1757,7 +1757,7 @@ void Net_SendMessage(void)
else if (g_chatPlayer == -1)
{
j = 50;
gametext(320>>1,j,"Send message to...",0,2+8+16);
gametext_center(j, "Send message to...");
j += 8;
for (TRAVERSE_CONNECT(i))
{
@ -1781,7 +1781,7 @@ void Net_SendMessage(void)
if (ud.screen_size > 0) j = 200-45;
else j = 200-8;
mpgametext(j,typebuf,0,2+8+16);
mpgametext(j, typebuf, 0, 0);
if (KB_KeyWaiting())
{

View file

@ -348,7 +348,7 @@ static void G_DoLoadScreen(const char *statustext, int32_t percent)
if (boardfilename[0] != 0 && ud.level_number == 7 && ud.volume_number == 0)
{
menutext_center(90,"Loading User Map");
gametextpal(160,90+10,boardfilename,14,2);
gametext_center_shade_pal(90+10, boardfilename, 14, 2);
}
else
{
@ -358,7 +358,7 @@ static void G_DoLoadScreen(const char *statustext, int32_t percent)
}
#ifndef EDUKE32_TOUCH_DEVICES
if (statustext) gametext(160,180,statustext,0,2+8+16);
if (statustext) gametext_center(180, statustext);
#endif
if (percent != -1)
@ -404,7 +404,7 @@ static void G_DoLoadScreen(const char *statustext, int32_t percent)
}
menutext_center(105,"Loading...");
if (statustext) gametext(160,180,statustext,0,2+8+16);
if (statustext) gametext_center(180, statustext);
VM_OnEventWithReturn(EVENT_DISPLAYLOADINGSCREEN, g_player[screenpeek].ps->i, screenpeek, percent);
nextpage();
}

View file

@ -180,8 +180,8 @@ static void G_ShowScores(void)
if (g_mostConcurrentPlayers > 1 && (g_gametypeFlags[ud.coop]&GAMETYPE_SCORESHEET))
{
gametext(160, SCORESHEETOFFSET+58+2, "Multiplayer Totals", 0, 2+8+16);
gametext(160, SCORESHEETOFFSET+58+10, g_mapInfo[G_LastMapInfoIndex()].name, 0, 2+8+16);
gametext_center(SCORESHEETOFFSET+58+2, "Multiplayer Totals");
gametext_center(SCORESHEETOFFSET+58+10, g_mapInfo[G_LastMapInfoIndex()].name);
t = 0;
minitext(70, SCORESHEETOFFSET+80, "Name", 8, 2+8+16+ROTATESPRITE_MAX);
@ -1229,10 +1229,10 @@ void G_DisplayRest(int32_t smoothratio)
if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex)
{
Bsprintf(tempbuf, "%s^00 has called a vote for map", g_player[voting].user_name);
gametext(160, 40, tempbuf, 0, 2+8+16);
gametext_center(40, tempbuf);
Bsprintf(tempbuf, "%s (E%dL%d)", g_mapInfo[vote_episode*MAXLEVELS + vote_map].name, vote_episode+1, vote_map+1);
gametext(160, 48, tempbuf, 0, 2+8+16);
gametext(160, 70, "Press F1 to Accept, F2 to Decline", 0, 2+8+16);
gametext_center(48, tempbuf);
gametext_center(70, "Press F1 to Accept, F2 to Decline");
}
if (BUTTON(gamefunc_Show_DukeMatch_Scores))
@ -1979,10 +1979,10 @@ static void G_DisplayMPResultsScreen(void)
rotatesprite_fs(160<<16, 34<<16, 65536L, 0, INGAMEDUKETHREEDEE, 0, 0, 10);
if (PLUTOPAK) // JBF 20030804
rotatesprite_fs((260)<<16, 36<<16, 65536L, 0, PLUTOPAKSPRITE+2, 0, 0, 2+8);
gametext(160, 58+2, "Multiplayer Totals", 0, 2+8+16);
gametext(160, 58+10, g_mapInfo[G_LastMapInfoIndex()].name, 0, 2+8+16);
gametext_center(58+2, "Multiplayer Totals");
gametext_center(58+10, g_mapInfo[G_LastMapInfoIndex()].name);
gametext(160, 165, "Press any key or button to continue", quotepulseshade, 2+8+16);
gametext_center_shade(165, "Press any key or button to continue", quotepulseshade);
minitext(23, 80, " Name Kills", 8, 2+8+16+128);
for (i=0; i<g_mostConcurrentPlayers; i++)
@ -2184,7 +2184,7 @@ void G_BonusScreen(int32_t bonusonly)
menutext_center(20-6, lastmapname);
menutext_center(36-6, "Completed");
gametext(160, 192, "Press any key or button to continue", quotepulseshade, 2+8+16);
gametext_center_shade(192, "Press any key or button to continue", quotepulseshade);
if (ud.config.MusicToggle)
S_PlaySound(BONUSMUSIC);
@ -2267,33 +2267,33 @@ void G_BonusScreen(int32_t bonusonly)
menutext_center(20-6, lastmapname);
menutext_center(36-6, "Completed");
gametext(160, 192, "Press any key or button to continue", quotepulseshade, 2+8+16);
gametext_center_shade(192, "Press any key or button to continue", quotepulseshade);
if (totalclock > (60*3))
{
yy = zz = 59;
gametext(10, yy+9, "Your Time:", 0, 2+8+16);
gametext(10, yy+9, "Your Time:");
yy+=10;
if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0]))
{
if (g_mapInfo[G_LastMapInfoIndex()].partime)
{
gametext(10, yy+9, "Par Time:", 0, 2+8+16);
gametext(10, yy+9, "Par Time:");
yy+=10;
}
if (!NAM_WW2GI && !DUKEBETA && g_mapInfo[G_LastMapInfoIndex()].designertime)
{
// EDuke 2.0 / NAM source suggests "Green Beret's Time:"
gametext(10, yy+9, "3D Realms' Time:", 0, 2+8+16);
gametext(10, yy+9, "3D Realms' Time:");
yy+=10;
}
}
if (ud.playerbest > 0)
{
gametext(10, yy+9, (g_player[myconnectindex].ps->player_par > 0 && g_player[myconnectindex].ps->player_par < ud.playerbest) ? "Prev Best Time:" : "Your Best Time:", 0, 2+8+16);
gametext(10, yy+9, (g_player[myconnectindex].ps->player_par > 0 && g_player[myconnectindex].ps->player_par < ud.playerbest) ? "Prev Best Time:" : "Your Best Time:");
yy += 10;
}
@ -2312,12 +2312,12 @@ void G_BonusScreen(int32_t bonusonly)
if (g_player[myconnectindex].ps->player_par > 0)
{
G_PrintYourTime();
gametext((320>>2)+71, yy+9, tempbuf, 0, 2+8+16);
gametext((320>>2)+71, yy+9, tempbuf);
if (g_player[myconnectindex].ps->player_par < ud.playerbest)
gametext((320>>2)+89+(clockpad*24), yy+9, "New record!", 0, 2+8+16);
gametext((320>>2)+89+(clockpad*24), yy+9, "New record!");
}
else
gametextpalbits((320>>2)+71, yy+9, "Cheated!", 0, 2, 2+8+16, 0);
gametext_pal((320>>2)+71, yy+9, "Cheated!", 2);
yy+=10;
if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0]))
@ -2325,13 +2325,13 @@ void G_BonusScreen(int32_t bonusonly)
if (g_mapInfo[G_LastMapInfoIndex()].partime)
{
G_PrintParTime();
gametext((320>>2)+71, yy+9, tempbuf, 0, 2+8+16);
gametext((320>>2)+71, yy+9, tempbuf);
yy+=10;
}
if (!NAM_WW2GI && !DUKEBETA && g_mapInfo[G_LastMapInfoIndex()].designertime)
{
G_PrintDesignerTime();
gametext((320>>2)+71, yy+9, tempbuf, 0, 2+8+16);
gametext((320>>2)+71, yy+9, tempbuf);
yy+=10;
}
}
@ -2339,7 +2339,7 @@ void G_BonusScreen(int32_t bonusonly)
if (ud.playerbest > 0)
{
G_PrintBestTime();
gametext((320>>2)+71, yy+9, tempbuf, 0, 2+8+16);
gametext((320>>2)+71, yy+9, tempbuf);
yy+=10;
}
}
@ -2348,9 +2348,9 @@ void G_BonusScreen(int32_t bonusonly)
zz = yy += 5;
if (totalclock > (60*6))
{
gametext(10, yy+9, "Enemies Killed:", 0, 2+8+16);
gametext(10, yy+9, "Enemies Killed:");
yy += 10;
gametext(10, yy+9, "Enemies Left:", 0, 2+8+16);
gametext(10, yy+9, "Enemies Left:");
yy += 10;
if (bonuscnt == 2)
@ -2369,12 +2369,11 @@ void G_BonusScreen(int32_t bonusonly)
S_PlaySound(PIPEBOMB_EXPLODE);
}
Bsprintf(tempbuf, "%-3d", g_player[myconnectindex].ps->actors_killed);
gametext((320>>2)+70, yy+9, tempbuf, 0, 2+8+16);
gametext((320>>2)+70, yy+9, tempbuf);
yy += 10;
if (ud.player_skill > 3)
{
Bsprintf(tempbuf, "N/A");
gametext((320>>2)+70, yy+9, tempbuf, 0, 2+8+16);
gametext((320>>2)+70, yy+9, "N/A");
yy += 10;
}
else
@ -2382,7 +2381,7 @@ void G_BonusScreen(int32_t bonusonly)
if ((g_player[myconnectindex].ps->max_actors_killed-g_player[myconnectindex].ps->actors_killed) < 0)
Bsprintf(tempbuf, "%-3d", 0);
else Bsprintf(tempbuf, "%-3d", g_player[myconnectindex].ps->max_actors_killed-g_player[myconnectindex].ps->actors_killed);
gametext((320>>2)+70, yy+9, tempbuf, 0, 2+8+16);
gametext((320>>2)+70, yy+9, tempbuf);
yy += 10;
}
}
@ -2391,9 +2390,9 @@ void G_BonusScreen(int32_t bonusonly)
zz = yy += 5;
if (totalclock > (60*9))
{
gametext(10, yy+9, "Secrets Found:", 0, 2+8+16);
gametext(10, yy+9, "Secrets Found:");
yy += 10;
gametext(10, yy+9, "Secrets Missed:", 0, 2+8+16);
gametext(10, yy+9, "Secrets Missed:");
yy += 10;
if (bonuscnt == 4) bonuscnt++;
@ -2406,12 +2405,15 @@ void G_BonusScreen(int32_t bonusonly)
S_PlaySound(PIPEBOMB_EXPLODE);
}
Bsprintf(tempbuf, "%-3d", g_player[myconnectindex].ps->secret_rooms);
gametext((320>>2)+70, yy+9, tempbuf, 0, 2+8+16);
gametext((320>>2)+70, yy+9, tempbuf);
yy += 10;
#if 0
// Always overwritten.
if (g_player[myconnectindex].ps->secret_rooms > 0)
Bsprintf(tempbuf, "%-3d%%", (100*g_player[myconnectindex].ps->secret_rooms/g_player[myconnectindex].ps->max_secret_rooms));
#endif
Bsprintf(tempbuf, "%-3d", g_player[myconnectindex].ps->max_secret_rooms-g_player[myconnectindex].ps->secret_rooms);
gametext((320>>2)+70, yy+9, tempbuf, 0, 2+8+16);
gametext((320>>2)+70, yy+9, tempbuf);
yy += 10;
}
}

View file

@ -900,19 +900,15 @@ vec2_t G_ScreenTextShadow(int32_t sx, int32_t sy,
return size;
}
// flags
// 4: small font, wrap strings?
int32_t G_PrintGameText(int32_t hack, int32_t tile, int32_t x, int32_t y, const char *t,
void G_PrintGameText(int32_t tile, int32_t x, int32_t y, const char *t,
int32_t s, int32_t p, int32_t o,
int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, int32_t a)
int32_t x1, int32_t y1, int32_t x2, int32_t y2,
int32_t z, int32_t a)
{
vec2_t dim;
int32_t f = TEXT_GAMETEXTNUMHACK;
int32_t xbetween = 0;
const int32_t orient = (hack & 4) || (hack & 1) ? (8|16|(o&1)|(o&32)) : (2|o);
if (t == NULL)
return -1;
return;
if (!(o & ROTATESPRITE_FULL16))
{
@ -920,34 +916,19 @@ int32_t G_PrintGameText(int32_t hack, int32_t tile, int32_t x, int32_t y, const
y <<= 16;
}
if (hack & 4)
{
x = textsc(x);
z = textsc(z);
f |= TEXT_LINEWRAP;
}
if (hack & 8)
{
f |= TEXT_XOFFSETZERO;
xbetween = 8;
}
// order is important, this bit comes after the rest
if ((hack & 2) && !NAM_WW2GI) // squishtext
--xbetween;
if (x == (160<<16))
f |= TEXT_XCENTER;
dim = G_ScreenText(tile, x, y, z, 0, 0, t, s, p, orient|ROTATESPRITE_FULL16, a, (5<<16), (8<<16), (xbetween<<16), 0, f, x1, y1, x2, y2);
G_ScreenText(tile, x, y, z, 0, 0, t, s, p, 2|o|ROTATESPRITE_FULL16, a, 5<<16, 8<<16, 0, 0, f, x1, y1, x2, y2);
}
x += dim.x;
if (!(o & ROTATESPRITE_FULL16))
x >>= 16;
return x;
void gametext_(int32_t x, int32_t y, int32_t z, const char *t, int32_t s, int32_t p, int32_t o, int32_t a, int32_t f)
{
G_ScreenText(STARTALPHANUM, x, y, z, 0, 0, t, s, p, o|2|8|16|ROTATESPRITE_FULL16, a, 5<<16, 8<<16, 0, 0, f|TEXT_GAMETEXTNUMHACK, 0, 0, xdim-1, ydim-1);
}
void gametext_simple(int32_t x, int32_t y, const char *t)
{
G_ScreenText(STARTALPHANUM, x, y, 65536, 0, 0, t, 0, 0, 2|8|16|ROTATESPRITE_FULL16, 0, 5<<16, 8<<16, 0, 0, TEXT_GAMETEXTNUMHACK, 0, 0, xdim-1, ydim-1);
}
int32_t G_GameTextLen(int32_t x, const char *t)
@ -1032,9 +1013,9 @@ void G_AddUserQuote(const char *daquote)
// orientation flags depending on time that a quote has still to be displayed
static inline int32_t texto(int32_t t)
{
if (t > 4) return 2+8+16;
if (t > 2) return 2+8+16+1;
return 2+8+16+1+32;
if (t > 4) return 0;
if (t > 2) return 1;
return 1|32;
}
static inline int32_t texta(int32_t t)
@ -1108,7 +1089,7 @@ void G_PrintGameQuotes(int32_t snum)
mpgametext(j, user_quote[i], sh, texto(k));
j += textsc(k > 4 ? 8 : (k<<1));
l = G_GameTextLen(USERQUOTE_LEFTOFFSET, OSD_StripColors(tempbuf, user_quote[i]));
l = G_GameTextLen(USERQUOTE_LEFTOFFSET, user_quote[i]);
while (l > (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET))
{
l -= (ud.config.ScreenWidth-USERQUOTE_RIGHTOFFSET);
@ -1181,7 +1162,7 @@ void G_PrintGameQuotes(int32_t snum)
}
#endif
gametextpalbits(160, k, apStrings[ps->ftq], ftapulseshade, pal, 2 + 8 + 16, texta(ps->fta));
gametext_center_shade_pal_alpha(k, apStrings[ps->ftq], ftapulseshade, pal, texta(ps->fta));
}
void P_DoQuote(int32_t q, DukePlayer_t *p)

View file

@ -60,21 +60,28 @@ enum ScreenTextFlags_t {
extern int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb);
extern void menutext_(int32_t x, int32_t y, int32_t s, char const *t, int32_t o, int32_t f);
extern void gametext_(int32_t x, int32_t y, int32_t z, const char *t, int32_t s, int32_t p, int32_t o, int32_t a, int32_t f);
extern void gametext_simple(int32_t x, int32_t y, const char *t);
extern int32_t textsc(int32_t sc);
#define minitextshade(x, y, t, s, p, sb) minitext_(x,y,t,s,p,sb)
#define minitext(x, y, t, p, sb) minitext_(x,y,t,0,p,sb)
#define menutext(x, y, t) menutext_((x), (y), 0, (t), 10|16, 0)
#define menutext_center(y, t) menutext_(160<<16, (y)<<16, 0, (t), 10|16, TEXT_XCENTER)
#define gametext(x,y,t,s,dabits) G_PrintGameText(0,STARTALPHANUM, x,y,t,s,0,dabits,0, 0, xdim-1, ydim-1, 65536, 0)
#define gametextscaled(x,y,t,s,dabits) G_PrintGameText(1,STARTALPHANUM, x,y,t,s,0,dabits,0, 0, xdim-1, ydim-1, 65536, 0)
#define gametextpal(x,y,t,s,p) G_PrintGameText(0,STARTALPHANUM, x,y,t,s,p,26,0, 0, xdim-1, ydim-1, 65536, 0)
#define gametextpalbits(x,y,t,s,p,dabits,a) G_PrintGameText(0,STARTALPHANUM, x,y,t,s,p,dabits,0, 0, xdim-1, ydim-1, 65536, a)
#define mpgametext(y, t, s, dabits) G_PrintGameText(4,STARTALPHANUM, 5,y,t,s,0,dabits,0, 0, xdim-1, ydim-1, 65536, 0);
#define gametext(x, y, t) gametext_simple((x)<<16, (y)<<16, (t))
#define gametext_bits(x, y, t, o) gametext_((x)<<16, (y)<<16, 65536, (t), 0, 0, (o), 0, 0)
#define gametext_pal(x, y, t, p) gametext_((x)<<16, (y)<<16, 65536, (t), 0, (p), 0, 0, 0)
#define gametext_center(y, t) gametext_(160<<16, (y)<<16, 65536, (t), 0, 0, 0, 0, TEXT_XCENTER)
#define gametext_center_shade(y, t, s) gametext_(160<<16, (y)<<16, 65536, (t), (s), 0, 0, 0, TEXT_XCENTER)
#define gametext_center_shade_pal(y, t, s, p) gametext_(160<<16, (y)<<16, 65536, (t), (s), (p), 0, 0, TEXT_XCENTER)
#define gametext_center_shade_pal_alpha(y, t, s, p, a) gametext_(160<<16, (y)<<16, 65536, (t), (s), (p), 0, (a), TEXT_XCENTER)
#define mpgametext(y, t, s, o) gametext_(textsc(5<<16), (y)<<16, textsc(65536), (t), (s), 0, (o), 0, TEXT_LINEWRAP)
extern int32_t G_GameTextLen(int32_t x, const char *t);
extern int32_t G_PrintGameText(int32_t hack, int32_t tile, int32_t x, int32_t y, const char *t, int32_t s, int32_t p,
int32_t o, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, int32_t a);
extern void G_PrintGameText(int32_t tile, int32_t x, int32_t y, const char *t,
int32_t s, int32_t p, int32_t o,
int32_t x1, int32_t y1, int32_t x2, int32_t y2,
int32_t z, int32_t a);
extern int32_t G_GetStringLineLength(const char *text, const char *end, const int32_t iter);
extern int32_t G_GetStringNumLines(const char *text, const char *end, const int32_t iter);