st_stuff.c 83.1 KB
Newer Older
Alam Ed Arias committed
1 2 3 4
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
James R. committed
5
// Copyright (C) 1999-2020 by Sonic Team Junior.
Alam Ed Arias committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file  st_stuff.c
/// \brief Status bar code
///        Does the face/direction indicator animatin.
///        Does palette indicators as well (red pain/berserk, bright pickup)

#include "doomdef.h"
#include "g_game.h"
#include "r_local.h"
#include "p_local.h"
#include "f_finale.h"
#include "st_stuff.h"
#include "i_video.h"
#include "v_video.h"
#include "z_zone.h"
#include "hu_stuff.h"
Jaime Ita Passos committed
26
#include "console.h"
Alam Ed Arias committed
27 28 29 30
#include "s_sound.h"
#include "i_system.h"
#include "m_menu.h"
#include "m_cheat.h"
toaster committed
31 32
#include "m_misc.h" // moviemode
#include "m_anigif.h" // cv_gif_downscale
Alam Ed Arias committed
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
#include "p_setup.h" // NiGHTS grading

//random index
#include "m_random.h"

// item finder
#include "m_cond.h"

#ifdef HWRENDER
#include "hardware/hw_main.h"
#endif

#include "lua_hud.h"

UINT16 objectsdrawn = 0;

//
// STATUS BAR DATA
//

patch_t *faceprefix[MAXSKINS]; // face status patches
patch_t *superprefix[MAXSKINS]; // super face status patches

// ------------------------------------------
//             status bar overlay
// ------------------------------------------

// icons for overlay
patch_t *sboscore; // Score logo
patch_t *sbotime; // Time logo
patch_t *sbocolon; // Colon for time
Alam Ed Arias committed
64
patch_t *sboperiod; // Period for time centiseconds
Alam Ed Arias committed
65
patch_t *livesback; // Lives icon background
66
patch_t *stlivex;
Alam Ed Arias committed
67
static patch_t *nrec_timer; // Timer for NiGHTS records
Alam Ed Arias committed
68
static patch_t *sborings;
69 70 71
static patch_t *slidgame;
static patch_t *slidtime;
static patch_t *slidover;
72
static patch_t *sboredrings;
73
static patch_t *sboredtime;
Alam Ed Arias committed
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
static patch_t *getall; // Special Stage HUD
static patch_t *timeup; // Special Stage HUD
static patch_t *hunthoming[6];
static patch_t *itemhoming[6];
static patch_t *race1;
static patch_t *race2;
static patch_t *race3;
static patch_t *racego;
static patch_t *nightslink;
static patch_t *curweapon;
static patch_t *normring;
static patch_t *bouncering;
static patch_t *infinityring;
static patch_t *autoring;
static patch_t *explosionring;
static patch_t *scatterring;
static patch_t *grenadering;
static patch_t *railring;
static patch_t *jumpshield;
static patch_t *forceshield;
static patch_t *ringshield;
static patch_t *watershield;
static patch_t *bombshield;
static patch_t *pityshield;
98
static patch_t *pinkshield;
99 100 101
static patch_t *flameshield;
static patch_t *bubbleshield;
static patch_t *thundershield;
Alam Ed Arias committed
102 103 104 105
static patch_t *invincibility;
static patch_t *sneakers;
static patch_t *gravboots;
static patch_t *nonicon;
toaster committed
106
static patch_t *nonicon2;
Alam Ed Arias committed
107 108 109 110 111 112
static patch_t *bluestat;
static patch_t *byelstat;
static patch_t *orngstat;
static patch_t *redstat;
static patch_t *yelstat;
static patch_t *nbracket;
113
static patch_t *nring;
Alam Ed Arias committed
114 115
static patch_t *nhud[12];
static patch_t *nsshud;
toaster committed
116 117
static patch_t *nbon[12];
static patch_t *nssbon;
Alam Ed Arias committed
118 119 120 121 122 123 124 125 126 127 128
static patch_t *narrow[9];
static patch_t *nredar[8]; // Red arrow
static patch_t *drillbar;
static patch_t *drillfill[3];
static patch_t *capsulebar;
static patch_t *capsulefill;
patch_t *ngradeletters[7];
static patch_t *minus5sec;
static patch_t *minicaps;
static patch_t *gotrflag;
static patch_t *gotbflag;
129
static patch_t *fnshico;
Alam Ed Arias committed
130 131 132 133 134

static boolean facefreed[MAXPLAYERS];

hudinfo_t hudinfo[NUMHUDITEMS] =
{
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
	{  16, 176, V_SNAPTOLEFT|V_SNAPTOBOTTOM}, // HUD_LIVES

	{  16,  42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGS
	{  96,  42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGSNUM
	{ 120,  42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGSNUMTICS

	{  16,  10, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SCORE
	{ 120,  10, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SCORENUM

	{  16,  26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIME
	{  72,  26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_MINUTES
	{  72,  26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIMECOLON
	{  96,  26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SECONDS
	{  96,  26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIMETICCOLON
	{ 120,  26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TICS

	{   0,  56, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SS_TOTALRINGS

	{ 110,  93, 0}, // HUD_GETRINGS
	{ 160,  93, 0}, // HUD_GETRINGSNUM
	{ 124, 160, 0}, // HUD_TIMELEFT
	{ 168, 176, 0}, // HUD_TIMELEFTNUM
	{ 130,  93, 0}, // HUD_TIMEUP
	{ 152, 168, 0}, // HUD_HUNTPICS

toaster committed
160
	{ 288, 176, V_SNAPTORIGHT|V_SNAPTOBOTTOM}, // HUD_POWERUPS
Alam Ed Arias committed
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
};

//
// STATUS BAR CODE
//

boolean ST_SameTeam(player_t *a, player_t *b)
{
	// Just pipe team messages to everyone in co-op or race.
	if (!G_RingSlingerGametype())
		return true;

	// Spectator chat.
	if (a->spectator && b->spectator)
		return true;

	// Team chat.
	if (G_GametypeHasTeams())
		return a->ctfteam == b->ctfteam;

	if (G_TagGametype())
		return ((a->pflags & PF_TAGIT) == (b->pflags & PF_TAGIT));

	return false;
}

static boolean st_stopped = true;

Jaime Ita Passos committed
189
void ST_Ticker(boolean run)
Alam Ed Arias committed
190 191 192
{
	if (st_stopped)
		return;
Jaime Ita Passos committed
193 194 195

	if (run)
		ST_runTitleCard();
Alam Ed Arias committed
196 197 198
}

// 0 is default, any others are special palettes.
199
INT32 st_palette = 0;
200
INT32 st_translucency = 10;
Alam Ed Arias committed
201 202 203 204 205

void ST_doPaletteStuff(void)
{
	INT32 palette;

206
	if (stplyr && stplyr->flashcount)
Alam Ed Arias committed
207 208 209 210
		palette = stplyr->flashpal;
	else
		palette = 0;

211 212 213 214 215
#ifdef HWRENDER
	if (rendermode == render_opengl)
		palette = 0; // No flashpals here in OpenGL
#endif

Alam Ed Arias committed
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
	if (palette != st_palette)
	{
		st_palette = palette;

		if (rendermode != render_none)
		{
			V_SetPaletteLump(GetPalette()); // Reset the palette
			if (!splitscreen)
				V_SetPalette(palette);
		}
	}
}

void ST_UnloadGraphics(void)
{
231
	Patch_FreeTag(PU_HUDGFX);
Alam Ed Arias committed
232 233 234 235 236 237 238
}

void ST_LoadGraphics(void)
{
	int i;

	// SRB2 border patch
239 240
	// st_borderpatchnum = W_GetNumForName("GFZFLR01");
	// scr_borderpatch = W_CacheLumpNum(st_borderpatchnum, PU_HUDGFX);
Alam Ed Arias committed
241 242 243 244 245 246

	// the original Doom uses 'STF' as base name for all face graphics
	// Graue 04-08-2004: face/name graphics are now indexed by skins
	//                   but load them in R_AddSkins, that gets called
	//                   first anyway
	// cache the status bar overlay icons (fullscreen mode)
247 248 249 250 251 252

	// Prefix "STT" is whitelisted (doesn't trigger ISGAMEMODIFIED), btw
	sborings = W_CachePatchName("STTRINGS", PU_HUDGFX);
	sboredrings = W_CachePatchName("STTRRING", PU_HUDGFX);
	sboscore = W_CachePatchName("STTSCORE", PU_HUDGFX);
	sbotime = W_CachePatchName("STTTIME", PU_HUDGFX); // Time logo
253
	sboredtime = W_CachePatchName("STTRTIME", PU_HUDGFX);
254 255 256
	sbocolon = W_CachePatchName("STTCOLON", PU_HUDGFX); // Colon for time
	sboperiod = W_CachePatchName("STTPERIO", PU_HUDGFX); // Period for time centiseconds

257 258 259 260
	slidgame = W_CachePatchName("SLIDGAME", PU_HUDGFX);
	slidtime = W_CachePatchName("SLIDTIME", PU_HUDGFX);
	slidover = W_CachePatchName("SLIDOVER", PU_HUDGFX);

Alam Ed Arias committed
261 262
	stlivex = W_CachePatchName("STLIVEX", PU_HUDGFX);
	livesback = W_CachePatchName("STLIVEBK", PU_HUDGFX);
Alam Ed Arias committed
263
	nrec_timer = W_CachePatchName("NGRTIMER", PU_HUDGFX); // Timer for NiGHTS
Alam Ed Arias committed
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
	getall = W_CachePatchName("GETALL", PU_HUDGFX); // Special Stage HUD
	timeup = W_CachePatchName("TIMEUP", PU_HUDGFX); // Special Stage HUD
	race1 = W_CachePatchName("RACE1", PU_HUDGFX);
	race2 = W_CachePatchName("RACE2", PU_HUDGFX);
	race3 = W_CachePatchName("RACE3", PU_HUDGFX);
	racego = W_CachePatchName("RACEGO", PU_HUDGFX);
	nightslink = W_CachePatchName("NGHTLINK", PU_HUDGFX);

	for (i = 0; i < 6; ++i)
	{
		hunthoming[i] = W_CachePatchName(va("HOMING%d", i+1), PU_HUDGFX);
		itemhoming[i] = W_CachePatchName(va("HOMITM%d", i+1), PU_HUDGFX);
	}

	curweapon = W_CachePatchName("CURWEAP", PU_HUDGFX);
	normring = W_CachePatchName("RINGIND", PU_HUDGFX);
	bouncering = W_CachePatchName("BNCEIND", PU_HUDGFX);
	infinityring = W_CachePatchName("INFNIND", PU_HUDGFX);
	autoring = W_CachePatchName("AUTOIND", PU_HUDGFX);
	explosionring = W_CachePatchName("BOMBIND", PU_HUDGFX);
	scatterring = W_CachePatchName("SCATIND", PU_HUDGFX);
	grenadering = W_CachePatchName("GRENIND", PU_HUDGFX);
	railring = W_CachePatchName("RAILIND", PU_HUDGFX);
toaster committed
287 288 289 290 291 292
	jumpshield = W_CachePatchName("TVWWICON", PU_HUDGFX);
	forceshield = W_CachePatchName("TVFOICON", PU_HUDGFX);
	ringshield = W_CachePatchName("TVATICON", PU_HUDGFX);
	watershield = W_CachePatchName("TVELICON", PU_HUDGFX);
	bombshield = W_CachePatchName("TVARICON", PU_HUDGFX);
	pityshield = W_CachePatchName("TVPIICON", PU_HUDGFX);
293
	pinkshield = W_CachePatchName("TVPPICON", PU_HUDGFX);
toaster committed
294 295 296 297 298 299
	flameshield = W_CachePatchName("TVFLICON", PU_HUDGFX);
	bubbleshield = W_CachePatchName("TVBBICON", PU_HUDGFX);
	thundershield = W_CachePatchName("TVZPICON", PU_HUDGFX);
	invincibility = W_CachePatchName("TVIVICON", PU_HUDGFX);
	sneakers = W_CachePatchName("TVSSICON", PU_HUDGFX);
	gravboots = W_CachePatchName("TVGVICON", PU_HUDGFX);
Alam Ed Arias committed
300 301 302 303 304 305 306 307

	tagico = W_CachePatchName("TAGICO", PU_HUDGFX);
	rflagico = W_CachePatchName("RFLAGICO", PU_HUDGFX);
	bflagico = W_CachePatchName("BFLAGICO", PU_HUDGFX);
	rmatcico = W_CachePatchName("RMATCICO", PU_HUDGFX);
	bmatcico = W_CachePatchName("BMATCICO", PU_HUDGFX);
	gotrflag = W_CachePatchName("GOTRFLAG", PU_HUDGFX);
	gotbflag = W_CachePatchName("GOTBFLAG", PU_HUDGFX);
308
	fnshico = W_CachePatchName("FNSHICO", PU_HUDGFX);
Alam Ed Arias committed
309
	nonicon = W_CachePatchName("NONICON", PU_HUDGFX);
toaster committed
310
	nonicon2 = W_CachePatchName("NONICON2", PU_HUDGFX);
Alam Ed Arias committed
311 312 313 314 315 316 317 318

	// NiGHTS HUD things
	bluestat = W_CachePatchName("BLUESTAT", PU_HUDGFX);
	byelstat = W_CachePatchName("BYELSTAT", PU_HUDGFX);
	orngstat = W_CachePatchName("ORNGSTAT", PU_HUDGFX);
	redstat = W_CachePatchName("REDSTAT", PU_HUDGFX);
	yelstat = W_CachePatchName("YELSTAT", PU_HUDGFX);
	nbracket = W_CachePatchName("NBRACKET", PU_HUDGFX);
319
	nring = W_CachePatchName("NRNG1", PU_HUDGFX);
Alam Ed Arias committed
320
	for (i = 0; i < 12; ++i)
toaster committed
321
	{
Alam Ed Arias committed
322
		nhud[i] = W_CachePatchName(va("NHUD%d", i+1), PU_HUDGFX);
toaster committed
323 324
		nbon[i] = W_CachePatchName(va("NBON%d", i+1), PU_HUDGFX);
	}
Alam Ed Arias committed
325
	nsshud = W_CachePatchName("NSSHUD", PU_HUDGFX);
toaster committed
326
	nssbon = W_CachePatchName("NSSBON", PU_HUDGFX);
Alam Ed Arias committed
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
	minicaps = W_CachePatchName("MINICAPS", PU_HUDGFX);

	for (i = 0; i < 8; ++i)
	{
		narrow[i] = W_CachePatchName(va("NARROW%d", i+1), PU_HUDGFX);
		nredar[i] = W_CachePatchName(va("NREDAR%d", i+1), PU_HUDGFX);
	}

	// non-animated version
	narrow[8] = W_CachePatchName("NARROW9", PU_HUDGFX);

	drillbar = W_CachePatchName("DRILLBAR", PU_HUDGFX);
	for (i = 0; i < 3; ++i)
		drillfill[i] = W_CachePatchName(va("DRILLFI%d", i+1), PU_HUDGFX);
	capsulebar = W_CachePatchName("CAPSBAR", PU_HUDGFX);
	capsulefill = W_CachePatchName("CAPSFILL", PU_HUDGFX);
	minus5sec = W_CachePatchName("MINUS5", PU_HUDGFX);

	for (i = 0; i < 7; ++i)
		ngradeletters[i] = W_CachePatchName(va("GRADE%d", i), PU_HUDGFX);
}

// made separate so that skins code can reload custom face graphics
350
void ST_LoadFaceGraphics(INT32 skinnum)
Alam Ed Arias committed
351
{
352
	if (skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_LIFEPIC)
353 354
	{
		spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
Jaime Ita Passos committed
355
		spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_LIFEPIC];
356
		faceprefix[skinnum] = W_CachePatchNum(sprframe->lumppat[0], PU_HUDGFX);
357
		if (skins[skinnum].sprites[(SPR2_XTRA|FF_SPR2SUPER)].numframes > XTRA_LIFEPIC)
358 359 360 361 362 363 364 365 366 367
		{
			sprdef = &skins[skinnum].sprites[SPR2_XTRA|FF_SPR2SUPER];
			sprframe = &sprdef->spriteframes[0];
			superprefix[skinnum] = W_CachePatchNum(sprframe->lumppat[0], PU_HUDGFX);
		}
		else
			superprefix[skinnum] = faceprefix[skinnum]; // not manually freed, okay to set to same pointer
	}
	else
		faceprefix[skinnum] = superprefix[skinnum] = W_CachePatchName("MISSING", PU_HUDGFX); // ditto
Alam Ed Arias committed
368 369 370 371 372 373 374 375
	facefreed[skinnum] = false;
}

void ST_ReloadSkinFaceGraphics(void)
{
	INT32 i;

	for (i = 0; i < numskins; i++)
376
		ST_LoadFaceGraphics(i);
Alam Ed Arias committed
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
}

static inline void ST_InitData(void)
{
	// 'link' the statusbar display to a player, which could be
	// another player than consoleplayer, for example, when you
	// change the view in a multiplayer demo with F12.
	stplyr = &players[displayplayer];

	st_palette = -1;
}

static inline void ST_Stop(void)
{
	if (st_stopped)
		return;

	V_SetPalette(0);

	st_stopped = true;
}

void ST_Start(void)
{
	if (!st_stopped)
		ST_Stop();

	ST_InitData();
	st_stopped = false;
}

//
// Initializes the status bar, sets the defaults border patch for the window borders.
//

// used by OpenGL mode, holds lumpnum of flat used to fill space around the viewwindow
lumpnum_t st_borderpatchnum;

void ST_Init(void)
{
	INT32 i;

	for (i = 0; i < MAXPLAYERS; i++)
		facefreed[i] = true;

	if (dedicated)
		return;

	ST_LoadGraphics();
}

// change the status bar too, when pressing F12 while viewing a demo.
void ST_changeDemoView(void)
{
	// the same routine is called at multiplayer deathmatch spawn
	// so it can be called multiple times
	ST_Start();
}

// =========================================================================
//                         STATUS BAR OVERLAY
// =========================================================================

boolean st_overlay;

Alam Ed Arias committed
442 443 444
// =========================================================================
//                          INTERNAL DRAWING
// =========================================================================
toaster committed
445
#define ST_DrawTopLeftOverlayPatch(x,y,p)         V_DrawScaledPatch(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p)
446 447 448
#define ST_DrawNumFromHud(h,n,flags)        V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, n)
#define ST_DrawPadNumFromHud(h,n,q,flags)   V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, n, q)
#define ST_DrawPatchFromHud(h,p,flags)      V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, p)
Alam Ed Arias committed
449 450

// Draw a number, scaled, over the view, maybe with set translucency
Alam Ed Arias committed
451 452 453
// Always draw the number completely since it's overlay
//
// Supports different colors! woo!
454
static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fixed_t s, INT32 a,
James Hale committed
455
	UINT32 num, patch_t **numpat, skincolornum_t colornum)
Alam Ed Arias committed
456
{
457
	fixed_t w = numpat[0]->width * s;
Alam Ed Arias committed
458 459
	const UINT8 *colormap;

Alam Ed Arias committed
460 461
	// I want my V_SNAPTOx flags. :< -Red
	//a &= V_ALPHAMASK;
Alam Ed Arias committed
462 463 464 465 466 467

	if (colornum == 0)
		colormap = colormaps;
	else // Uses the player colors.
		colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE);

468
	//I_Assert(num >= 0); // this function does not draw negative numbers
Alam Ed Arias committed
469 470 471 472

	// draw the number
	do
	{
Alam Ed Arias committed
473
		x -= w;
474
		V_DrawFixedPatch(x, y, s, a, numpat[num % 10], colormap);
Alam Ed Arias committed
475 476 477 478
		num /= 10;
	} while (num);

	// Sorry chum, this function only draws UNSIGNED values!
479
	// then why is num not UINT32? ~toast
Alam Ed Arias committed
480 481 482 483 484
}

// Devmode information
static void ST_drawDebugInfo(void)
{
485 486
	INT32 height = 0, h = 8, w = 18, lowh;
	void (*textfunc)(INT32, INT32, INT32, const char *);
Alam Ed Arias committed
487

488
	if (!(stplyr->mo && cv_debug))
Alam Ed Arias committed
489 490
		return;

toaster committed
491
#define VFLAGS V_MONOSPACE|V_SNAPTOTOP|V_SNAPTORIGHT
492

toaster committed
493
	if ((moviemode == MM_GIF && cv_gif_downscale.value) || vid.dupx == 1)
Alam Ed Arias committed
494
	{
495 496
		textfunc = V_DrawRightAlignedString;
		lowh = ((vid.height/vid.dupy) - 16);
Alam Ed Arias committed
497
	}
toaster committed
498
	else
Alam Ed Arias committed
499
	{
500 501 502 503 504
		textfunc = V_DrawRightAlignedSmallString;
		h /= 2;
		w /= 2;
		lowh = 0;
	}
505

506 507 508 509 510 511 512
#define V_DrawDebugLine(str) if (lowh && (height > lowh))\
							{\
								V_DrawRightAlignedThinString(320,  8+lowh, VFLAGS|V_REDMAP, "SOME INFO NOT VISIBLE");\
								return;\
							}\
							textfunc(320, height, VFLAGS, str);\
							height += h;
Alam Ed Arias committed
513

514 515
#define V_DrawDebugFlag(f, str) textfunc(width, height, VFLAGS|f, str);\
								width -= w
Alam Ed Arias committed
516

517 518 519
	if (cv_debug & DBG_MEMORY)
	{
		V_DrawDebugLine(va("Heap: %8sKB", sizeu1(Z_TotalUsage()>>10)));
toaster committed
520

521 522
		height += h/2;
	}
toaster committed
523

524 525 526 527 528
	if (cv_debug & DBG_RANDOMIZER) // randomizer testing
	{
		fixed_t peekres = P_RandomPeek();
		peekres *= 10000;     // Change from fixed point
		peekres >>= FRACBITS; // to displayable decimal
toaster committed
529

530 531 532
		V_DrawDebugLine(va("Init: %08x", P_GetInitSeed()));
		V_DrawDebugLine(va("Seed: %08x", P_GetRandSeed()));
		V_DrawDebugLine(va("==  :    .%04d", peekres));
toaster committed
533

534 535
		height += h/2;
	}
toaster committed
536

537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608
	if (cv_debug & DBG_PLAYER)
	{
		INT32 width = 320;
		const fixed_t d = AngleFixed(stplyr->drawangle);

		V_DrawDebugLine(va("SHIELD: %5x", stplyr->powers[pw_shield]));
		V_DrawDebugLine(va("SCALE: %5d%%", (stplyr->mo->scale*100)>>FRACBITS));
		V_DrawDebugLine(va("CARRY: %5x", stplyr->powers[pw_carry]));
		V_DrawDebugLine(va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime]));
		V_DrawDebugLine(va("ABILITY: %3d, %3d", stplyr->charability, stplyr->charability2));
		V_DrawDebugLine(va("ACTIONSPD: %5d", stplyr->actionspd>>FRACBITS));
		V_DrawDebugLine(va("PEEL: %3d", stplyr->dashmode));
		V_DrawDebugLine(va("SCOREADD: %3d", stplyr->scoreadd));

		// Flags
		V_DrawDebugFlag(((stplyr->pflags & PF_SHIELDABILITY)  ? V_GREENMAP : V_REDMAP), "SH");
		V_DrawDebugFlag(((stplyr->pflags & PF_THOKKED)        ? V_GREENMAP : V_REDMAP), "TH");
		V_DrawDebugFlag(((stplyr->pflags & PF_STARTDASH)      ? V_GREENMAP : V_REDMAP), "ST");
		V_DrawDebugFlag(((stplyr->pflags & PF_SPINNING)       ? V_GREENMAP : V_REDMAP), "SP");
		V_DrawDebugFlag(((stplyr->pflags & PF_NOJUMPDAMAGE)   ? V_GREENMAP : V_REDMAP), "ND");
		V_DrawDebugFlag(((stplyr->pflags & PF_JUMPED)         ? V_GREENMAP : V_REDMAP), "JD");
		V_DrawDebugFlag(((stplyr->pflags & PF_STARTJUMP)      ? V_GREENMAP : V_REDMAP), "SJ");
		V_DrawDebugFlag(0, "PF/SF:");
		height += h;
		width = 320;
		V_DrawDebugFlag(((stplyr->pflags & PF_INVIS)          ? V_GREENMAP : V_REDMAP), "*I");
		V_DrawDebugFlag(((stplyr->pflags & PF_NOCLIP)         ? V_GREENMAP : V_REDMAP), "*C");
		V_DrawDebugFlag(((stplyr->pflags & PF_GODMODE)        ? V_GREENMAP : V_REDMAP), "*G");
		V_DrawDebugFlag(((stplyr->charflags & SF_SUPER)       ? V_GREENMAP : V_REDMAP), "SU");
		V_DrawDebugFlag(((stplyr->pflags & PF_APPLYAUTOBRAKE) ? V_GREENMAP : V_REDMAP), "AA");
		V_DrawDebugFlag(((stplyr->pflags & PF_SLIDING)        ? V_GREENMAP : V_REDMAP), "SL");
		V_DrawDebugFlag(((stplyr->pflags & PF_BOUNCING)       ? V_GREENMAP : V_REDMAP), "BO");
		V_DrawDebugFlag(((stplyr->pflags & PF_GLIDING)        ? V_GREENMAP : V_REDMAP), "GL");
		height += h;

		V_DrawDebugLine(va("DRAWANGLE: %6d", FixedInt(d)));

		height += h/2;
	}

	if (cv_debug & DBG_DETAILED)
	{
		INT32 width = 320;

		V_DrawDebugLine(va("CEILINGZ: %6d", stplyr->mo->ceilingz>>FRACBITS));
		V_DrawDebugLine(va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS));

		V_DrawDebugLine(va("CMOMX: %6d", stplyr->cmomx>>FRACBITS));
		V_DrawDebugLine(va("CMOMY: %6d", stplyr->cmomy>>FRACBITS));
		V_DrawDebugLine(va("PMOMZ: %6d", stplyr->mo->pmomz>>FRACBITS));

		width = 320;
		V_DrawDebugFlag(((stplyr->mo->eflags & MFE_APPLYPMOMZ)      ? V_GREENMAP : V_REDMAP), "AP");
		V_DrawDebugFlag(((stplyr->mo->eflags & MFE_SPRUNG)          ? V_GREENMAP : V_REDMAP), "SP");
		//V_DrawDebugFlag(((stplyr->mo->eflags & MFE_PUSHED)          ? V_GREENMAP : V_REDMAP), "PU"); -- not relevant to players
		V_DrawDebugFlag(((stplyr->mo->eflags & MFE_GOOWATER)        ? V_GREENMAP : V_REDMAP), "GW");
		V_DrawDebugFlag(((stplyr->mo->eflags & MFE_VERTICALFLIP)    ? V_GREENMAP : V_REDMAP), "VF");
		V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTSTEPPEDDOWN) ? V_GREENMAP : V_REDMAP), "JS");
		V_DrawDebugFlag(((stplyr->mo->eflags & MFE_UNDERWATER)      ? V_GREENMAP : V_REDMAP), "UW");
		V_DrawDebugFlag(((stplyr->mo->eflags & MFE_TOUCHWATER)      ? V_GREENMAP : V_REDMAP), "TW");
		V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTHITFLOOR)    ? V_GREENMAP : V_REDMAP), "JH");
		V_DrawDebugFlag(((stplyr->mo->eflags & MFE_ONGROUND)        ? V_GREENMAP : V_REDMAP), "OG");
		V_DrawDebugFlag(0, "MFE:");
		height += h;

		V_DrawDebugLine(va("MOMX: %6d", stplyr->rmomx>>FRACBITS));
		V_DrawDebugLine(va("MOMY: %6d", stplyr->rmomy>>FRACBITS));
		V_DrawDebugLine(va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS));

		V_DrawDebugLine(va("SPEED: %6d", stplyr->speed>>FRACBITS));

		height += h/2;
Alam Ed Arias committed
609
	}
610

611 612 613 614 615 616 617 618 619 620 621 622
	if (cv_debug & DBG_BASIC)
	{
		const fixed_t d = AngleFixed(stplyr->mo->angle);
		V_DrawDebugLine(va("X: %6d", stplyr->mo->x>>FRACBITS));
		V_DrawDebugLine(va("Y: %6d", stplyr->mo->y>>FRACBITS));
		V_DrawDebugLine(va("Z: %6d", stplyr->mo->z>>FRACBITS));
		V_DrawDebugLine(va("A: %6d", FixedInt(d)));

		//height += h/2;
	}

#undef V_DrawDebugFlag
toaster committed
623 624
#undef V_DrawDebugLine
#undef VFLAGS
Alam Ed Arias committed
625 626 627 628
}

static void ST_drawScore(void)
{
629 630 631
	if (F_GetPromptHideHud(hudinfo[HUD_SCORE].y))
		return;

Alam Ed Arias committed
632
	// SCORE:
toaster committed
633
	ST_DrawPatchFromHud(HUD_SCORE, sboscore, V_HUDTRANS);
Alam Ed Arias committed
634 635 636
	if (objectplacing)
	{
		if (op_displayflags > UINT16_MAX)
toaster committed
637
			ST_DrawTopLeftOverlayPatch((hudinfo[HUD_SCORENUM].x-tallminus->width), hudinfo[HUD_SCORENUM].y, tallminus);
Alam Ed Arias committed
638
		else
toaster committed
639
			ST_DrawNumFromHud(HUD_SCORENUM, op_displayflags, V_HUDTRANS);
Alam Ed Arias committed
640 641
	}
	else
toaster committed
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
		ST_DrawNumFromHud(HUD_SCORENUM, stplyr->score, V_HUDTRANS);
}

static void ST_drawRaceNum(INT32 time)
{
	INT32 height, bounce;
	patch_t *racenum;

	time += TICRATE;
	height = ((3*BASEVIDHEIGHT)>>2) - 8;
	bounce = TICRATE - (1 + (time % TICRATE));

	switch (time/TICRATE)
	{
		case 3:
			racenum = race3;
			break;
		case 2:
			racenum = race2;
			break;
		case 1:
			racenum = race1;
			break;
		default:
			racenum = racego;
			break;
	}
	if (bounce < 3)
	{
		height -= (2 - bounce);
		if (!(P_AutoPause() || paused) && !bounce)
				S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7));
	}
675
	V_DrawScaledPatch(((BASEVIDWIDTH - racenum->width)/2), height, V_PERPLAYER, racenum);
Alam Ed Arias committed
676 677 678 679 680
}

static void ST_drawTime(void)
{
	INT32 seconds, minutes, tictrn, tics;
toaster committed
681
	boolean downwards = false;
Alam Ed Arias committed
682 683 684 685 686 687 688 689 690 691

	if (objectplacing)
	{
		tics    = objectsdrawn;
		seconds = objectsdrawn%100;
		minutes = objectsdrawn/100;
		tictrn  = 0;
	}
	else
	{
toaster committed
692
		// Counting down the hidetime?
693
		if ((gametyperules & GTR_STARTCOUNTDOWN) && (stplyr->realtime <= (hidetime*TICRATE)))
toaster committed
694
		{
695 696 697 698
			tics = (hidetime*TICRATE - stplyr->realtime);
			if (tics < 3*TICRATE)
				ST_drawRaceNum(tics);
			tics += (TICRATE-1); // match the race num
toaster committed
699 700 701 702 703
			downwards = true;
		}
		else
		{
			// Hidetime finish!
704
			if ((gametyperules & GTR_STARTCOUNTDOWN) && (stplyr->realtime < ((hidetime+1)*TICRATE)))
toaster committed
705
				ST_drawRaceNum(hidetime*TICRATE - stplyr->realtime);
toaster committed
706 707

			// Time limit?
708
			if ((gametyperules & GTR_TIMELIMIT) && cv_timelimit.value && timelimitintics > 0)
toaster committed
709
			{
710
				if (timelimitintics > stplyr->realtime)
toaster committed
711
				{
712 713 714 715
					tics = (timelimitintics - stplyr->realtime);
					if (tics < 3*TICRATE)
						ST_drawRaceNum(tics);
					tics += (TICRATE-1); // match the race num
toaster committed
716 717 718 719 720 721
				}
				else // Overtime!
					tics = 0;
				downwards = true;
			}
			// Post-hidetime normal.
722
			else if (gametyperules & GTR_STARTCOUNTDOWN)
toaster committed
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
				tics = stplyr->realtime - hidetime*TICRATE;
			// "Shadow! What are you doing? Hurry and get back here
			// right now before the island blows up with you on it!"
			// "Blows up??" *awkward silence* "I've got to get outta
			// here and find Amy and Tails right away!"
			else if (mapheaderinfo[gamemap-1]->countdown)
			{
				tics = countdowntimer;
				downwards = true;
			}
			// Normal.
			else
				tics = stplyr->realtime;
		}

Alam Ed Arias committed
738
		minutes = G_TicsToMinutes(tics, true);
toaster committed
739
		seconds = G_TicsToSeconds(tics);
Alam Ed Arias committed
740 741 742
		tictrn  = G_TicsToCentiseconds(tics);
	}

743 744 745
	if (F_GetPromptHideHud(hudinfo[HUD_TIME].y))
		return;

746 747
	downwards = (downwards && (tics < 30*TICRATE) && (leveltime/5 & 1) && !stoppedclock); // overtime?

toaster committed
748
	// TIME:
749
	ST_DrawPatchFromHud(HUD_TIME, (downwards ? sboredtime : sbotime), V_HUDTRANS);
toaster committed
750

751
	if (downwards) // overtime!
toaster committed
752 753
		return;

toaster committed
754
	if (cv_timetic.value == 3) // Tics only -- how simple is this?
755
		ST_DrawNumFromHud(HUD_SECONDS, tics, V_HUDTRANS);
Alam Ed Arias committed
756 757
	else
	{
758 759 760
		ST_DrawNumFromHud(HUD_MINUTES, minutes, V_HUDTRANS); // Minutes
		ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon
		ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds
Alam Ed Arias committed
761

762
		if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking || marathonmode)
Alam Ed Arias committed
763
		{
toaster committed
764 765
			ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod, V_HUDTRANS); // Period
			ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2, V_HUDTRANS); // Tics
Alam Ed Arias committed
766 767 768 769 770 771
		}
	}
}

static inline void ST_drawRings(void)
{
772
	INT32 ringnum;
Alam Ed Arias committed
773

774 775 776
	if (F_GetPromptHideHud(hudinfo[HUD_RINGS].y))
		return;

777
	ST_DrawPatchFromHud(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS));
Alam Ed Arias committed
778

toaster committed
779 780 781 782 783 784
	if (objectplacing)
		ringnum = op_currentdoomednum;
	else if (stplyr->rings < 0 || stplyr->spectator || stplyr->playerstate == PST_REBORN)
		ringnum = 0;
	else
		ringnum = stplyr->rings;
Alam Ed Arias committed
785

toaster committed
786
	if (cv_timetic.value == 2) // Yes, even in modeattacking
toaster committed
787
		ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS));
788
	else
789
		ST_DrawNumFromHud(HUD_RINGSNUM, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS));
Alam Ed Arias committed
790 791
}

toaster committed
792
static void ST_drawLivesArea(void)
Alam Ed Arias committed
793
{
toaster committed
794 795
	INT32 v_colmap = V_YELLOWMAP, livescount;
	boolean notgreyedout;
Alam Ed Arias committed
796 797 798 799

	if (!stplyr->skincolor)
		return; // Just joined a server, skin isn't loaded yet!

800 801 802
	if (F_GetPromptHideHud(hudinfo[HUD_LIVES].y))
		return;

Alam Ed Arias committed
803
	// face background
toaster committed
804
	V_DrawSmallScaledPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y,
805
		hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, livesback);
Alam Ed Arias committed
806 807

	// face
808 809 810 811
	if (stplyr->spectator)
	{
		// spectator face
		UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, SKINCOLOR_CLOUDY, GTC_CACHE);
toaster committed
812
		V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y,
813
			hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap);
814 815
	}
	else if (stplyr->mo && stplyr->mo->color)
Alam Ed Arias committed
816 817 818 819
	{
		// skincolor face/super
		UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->color, GTC_CACHE);
		patch_t *face = faceprefix[stplyr->skin];
lachwright committed
820
		if (stplyr->powers[pw_super] && !(stplyr->charflags & SF_NOSUPERSPRITES))
Alam Ed Arias committed
821
			face = superprefix[stplyr->skin];
toaster committed
822
		V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y,
823
			hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, face, colormap);
Jaime Ita Passos committed
824
		if (st_translucency == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer)
825 826 827 828 829 830
		{
			INT32 v_supertrans = (stplyr->mo->tracer->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
			if (v_supertrans < 10)
			{
				v_supertrans <<= V_ALPHASHIFT;
				colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->tracer->color, GTC_CACHE);
toaster committed
831
				V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y,
832
					hudinfo[HUD_LIVES].f|V_PERPLAYER|v_supertrans, face, colormap);
833 834
			}
		}
Alam Ed Arias committed
835 836 837 838 839
	}
	else if (stplyr->skincolor)
	{
		// skincolor face
		UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE);
toaster committed
840
		V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y,
841
			hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, faceprefix[stplyr->skin], colormap);
Alam Ed Arias committed
842
	}
843

844
	// Metal Sonic recording
845 846 847 848 849 850
	if (metalrecording)
	{
		if (((2*leveltime)/TICRATE) & 1)
			V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8,
				hudinfo[HUD_LIVES].f|V_PERPLAYER|V_REDMAP|V_HUDTRANS, "REC");
	}
toaster committed
851 852 853 854
	// Spectator
	else if (stplyr->spectator)
		v_colmap = V_GRAYMAP;
	// Tag
855
	else if (gametyperules & GTR_TAG)
toaster committed
856 857 858
	{
		if (stplyr->pflags & PF_TAGIT)
		{
859
			V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "IT!");
toaster committed
860 861
			v_colmap = V_ORANGEMAP;
		}
862
	}
toaster committed
863 864 865 866 867
	// Team name
	else if (G_GametypeHasTeams())
	{
		if (stplyr->ctfteam == 1)
		{
868
			V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED");
toaster committed
869 870 871 872
			v_colmap = V_REDMAP;
		}
		else if (stplyr->ctfteam == 2)
		{
873
			V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE");
toaster committed
874 875 876
			v_colmap = V_BLUEMAP;
		}
	}
877 878 879 880 881 882 883 884 885
	// Lives number
	else
	{
		boolean candrawlives = true;

		// Co-op and Competition, normal life counter
		if (G_GametypeUsesLives())
		{
			// Handle cooplives here
886
			if ((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 3)
887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912
			{
				INT32 i;
				livescount = 0;
				notgreyedout = (stplyr->lives > 0);
				for (i = 0; i < MAXPLAYERS; i++)
				{
					if (!playeringame[i])
						continue;

					if (players[i].lives < 1)
						continue;

					if (players[i].lives > 1)
						notgreyedout = true;

					if (players[i].lives == INFLIVES)
					{
						livescount = INFLIVES;
						break;
					}
					else if (livescount < 99)
						livescount += (players[i].lives);
				}
			}
			else
			{
913
				livescount = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives);
914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
				notgreyedout = true;
			}
		}
		// Infinity symbol (Race)
		else if (G_PlatformGametype() && !(gametyperules & GTR_LIVES))
		{
			livescount = INFLIVES;
			notgreyedout = true;
		}
		// Otherwise nothing, sorry.
		// Special Stages keep not showing lives,
		// as G_GametypeUsesLives() returns false in
		// Special Stages, and the infinity symbol
		// cannot show up because Special Stages
		// still have the GTR_LIVES gametype rule
		// by default.
		else
			candrawlives = false;

		// Draw the lives counter here.
		if (candrawlives)
		{
			// x
			V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex);
			if (livescount == INFLIVES)
				V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8,
					'\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false);
			else
			{
943
				if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1)) && !(stplyr->pflags & PF_FINISHED))
944 945 946 947 948 949 950 951 952
					livescount++;
				if (livescount > 99)
					livescount = 99;
				V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8,
					hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount));
			}
		}
#undef ST_drawLivesX
	}
953

toaster committed
954
	// name
955
	v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER);
toaster committed
956 957
	if (strlen(skins[stplyr->skin].hudname) <= 5)
		V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname);
958 959
	else if (V_StringWidth(skins[stplyr->skin].hudname, v_colmap) <= 48)
		V_DrawString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname);
toaster committed
960 961
	else if (V_ThinStringWidth(skins[stplyr->skin].hudname, v_colmap) <= 40)
		V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname);
962
	else
toaster committed
963 964 965
		V_DrawThinString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname);

	// Power Stones collected
966
	if (G_RingSlingerGametype() && LUA_HudEnabled(hud_powerstones))
967
	{
toaster committed
968 969 970 971 972
		INT32 workx = hudinfo[HUD_LIVES].x+1, j;
		if ((leveltime & 1) && stplyr->powers[pw_invulnerability] && (stplyr->powers[pw_sneakers] == stplyr->powers[pw_invulnerability])) // hack; extremely unlikely to be activated unintentionally
		{
			for (j = 0; j < 7; ++j) // "super" indicator
			{
973
				V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, emeraldpics[1][j]);
toaster committed
974 975 976 977 978 979 980 981
				workx += 8;
			}
		}
		else
		{
			for (j = 0; j < 7; ++j) // powerstones
			{
				if (stplyr->powers[pw_emeralds] & (1 << j))
982
					V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, emeraldpics[1][j]);
toaster committed
983 984 985
				workx += 8;
			}
		}
986
	}
Alam Ed Arias committed
987 988
}

toaster committed
989 990
static void ST_drawInput(void)
{
James Hale committed
991
	const INT32 accent = V_SNAPTOLEFT|V_SNAPTOBOTTOM|(stplyr->skincolor ? skincolors[stplyr->skincolor].ramp[4] : 0);
toaster committed
992 993
	INT32 col;
	UINT8 offs;
toaster committed
994

toaster committed
995
	INT32 x = hudinfo[HUD_LIVES].x, y = hudinfo[HUD_LIVES].y;
996

997 998 999
	if (stplyr->powers[pw_carry] == CR_NIGHTSMODE)
		y -= 16;

1000 1001 1002
	if (F_GetPromptHideHud(y))
		return;

1003
	// O backing
1004 1005
	V_DrawFill(x, y-1, 16, 16, hudinfo[HUD_LIVES].f|20);
	V_DrawFill(x, y+15, 16, 1, hudinfo[HUD_LIVES].f|29);
toaster committed
1006 1007 1008

	if (cv_showinputjoy.value) // joystick render!
	{
1009 1010 1011 1012
		/*V_DrawFill(x   , y   , 16,  1, hudinfo[HUD_LIVES].f|16);
		V_DrawFill(x   , y+15, 16,  1, hudinfo[HUD_LIVES].f|16);
		V_DrawFill(x   , y+ 1,  1, 14, hudinfo[HUD_LIVES].f|16);
		V_DrawFill(x+15, y+ 1,  1, 14, hudinfo[HUD_LIVES].f|16); -- red's outline*/
toaster committed
1013 1014
		if (stplyr->cmd.sidemove || stplyr->cmd.forwardmove)
		{
1015
			// joystick hole
1016
			V_DrawFill(x+5, y+4, 6, 6, hudinfo[HUD_LIVES].f|29);
1017 1018 1019
			// joystick top
			V_DrawFill(x+3+stplyr->cmd.sidemove/12,
				y+2-stplyr->cmd.forwardmove/12,
1020
				10, 10, hudinfo[HUD_LIVES].f|29);
1021 1022 1023 1024 1025 1026 1027
			V_DrawFill(x+3+stplyr->cmd.sidemove/9,
				y+1-stplyr->cmd.forwardmove/9,
				10, 10, accent);
		}
		else
		{
			// just a limited, greyed out joystick top
1028
			V_DrawFill(x+3, y+11, 10, 1, hudinfo[HUD_LIVES].f|29);
1029 1030
			V_DrawFill(x+3,
				y+1,
1031
				10, 10, hudinfo[HUD_LIVES].f|16);
toaster committed
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
		}
	}
	else // arrows!
	{
		// <
		if (stplyr->cmd.sidemove < 0)
		{
			offs = 0;
			col = accent;
		}
		else
		{
			offs = 1;
1045 1046 1047 1048
			col = hudinfo[HUD_LIVES].f|16;
			V_DrawFill(x- 2, y+10,  6,  1, hudinfo[HUD_LIVES].f|29);
			V_DrawFill(x+ 4, y+ 9,  1,  1, hudinfo[HUD_LIVES].f|29);
			V_DrawFill(x+ 5, y+ 8,  1,  1, hudinfo[HUD_LIVES].f|29);
toaster committed
1049
		}
1050 1051 1052
		V_DrawFill(x- 2, y+ 5-offs,  6,  6, col);
		V_DrawFill(x+ 4, y+ 6-offs,  1,  4, col);
		V_DrawFill(x+ 5, y+ 7-offs,  1,  2, col);
toaster committed
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062

		// ^
		if (stplyr->cmd.forwardmove > 0)
		{
			offs = 0;
			col = accent;
		}
		else
		{
			offs = 1;
1063 1064 1065 1066 1067 1068
			col = hudinfo[HUD_LIVES].f|16;
			V_DrawFill(x+ 5, y+ 3,  1,  1, hudinfo[HUD_LIVES].f|29);
			V_DrawFill(x+ 6, y+ 4,  1,  1, hudinfo[HUD_LIVES].f|29);
			V_DrawFill(x+ 7, y+ 5,  2,  1, hudinfo[HUD_LIVES].f|29);
			V_DrawFill(x+ 9, y+ 4,  1,  1, hudinfo[HUD_LIVES].f|29);
			V_DrawFill(x+10, y+ 3,  1,  1, hudinfo[HUD_LIVES].f|29);
toaster committed
1069
		}
1070 1071 1072
		V_DrawFill(x+ 5, y- 2-offs,  6,  6, col);
		V_DrawFill(x+ 6, y+ 4-offs,  4,  1, col);
		V_DrawFill(x+ 7, y+ 5-offs,  2,  1, col);
toaster committed
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082

		// >
		if (stplyr->cmd.sidemove > 0)
		{
			offs = 0;
			col = accent;
		}
		else
		{
			offs = 1;
1083 1084 1085 1086
			col = hudinfo[HUD_LIVES].f|16;
			V_DrawFill(x+12, y+10,  6,  1, hudinfo[HUD_LIVES].f|29);
			V_DrawFill(x+11, y+ 9,  1,  1, hudinfo[HUD_LIVES].f|29);
			V_DrawFill(x+10, y+ 8,  1,  1, hudinfo[HUD_LIVES].f|29);
toaster committed
1087
		}
1088 1089 1090
		V_DrawFill(x+12, y+ 5-offs,  6,  6, col);
		V_DrawFill(x+11, y+ 6-offs,  1,  4, col);
		V_DrawFill(x+10, y+ 7-offs,  1,  2, col);
toaster committed
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100

		// v
		if (stplyr->cmd.forwardmove < 0)
		{
			offs = 0;
			col = accent;
		}
		else
		{
			offs = 1;
1101 1102
			col = hudinfo[HUD_LIVES].f|16;
			V_DrawFill(x+ 5, y+17,  6,  1, hudinfo[HUD_LIVES].f|29);
toaster committed
1103
		}
1104 1105 1106
		V_DrawFill(x+ 5, y+12-offs,  6,  6, col);
		V_DrawFill(x+ 6, y+11-offs,  4,  1, col);
		V_DrawFill(x+ 7, y+10-offs,  2,  1, col);
toaster committed
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
	}

#define drawbutt(xoffs, yoffs, butt, symb)\
	if (stplyr->cmd.buttons & butt)\
	{\
		offs = 0;\
		col = accent;\
	}\
	else\
	{\
		offs = 1;\
1118 1119
		col = hudinfo[HUD_LIVES].f|16;\
		V_DrawFill(x+16+(xoffs), y+9+(yoffs), 10, 1, hudinfo[HUD_LIVES].f|29);\
toaster committed
1120
	}\
1121
	V_DrawFill(x+16+(xoffs), y+(yoffs)-offs, 10, 10, col);\
1122
	V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, hudinfo[HUD_LIVES].f|symb, false)
toaster committed
1123 1124

	drawbutt( 4,-3, BT_JUMP, 'J');
1125
	drawbutt(15,-3, BT_SPIN, 'S');
toaster committed
1126

1127
	V_DrawFill(x+16+4, y+8, 21, 10, hudinfo[HUD_LIVES].f|20); // sundial backing
toaster committed
1128 1129 1130
	if (stplyr->mo)
	{
		UINT8 i, precision;
1131 1132 1133
		angle_t ang = (stplyr->powers[pw_carry] == CR_NIGHTSMODE)
		? (FixedAngle((stplyr->flyangle-90)<<FRACBITS)>>ANGLETOFINESHIFT)
		: (stplyr->mo->angle - R_PointToAngle(stplyr->mo->x, stplyr->mo->y))>>ANGLETOFINESHIFT;
toaster committed
1134 1135 1136 1137 1138 1139
		fixed_t xcomp = FINESINE(ang)>>13;
		fixed_t ycomp = FINECOSINE(ang)>>14;
		if (ycomp == 4)
			ycomp = 3;

		if (ycomp > 0)
1140
			V_DrawFill(x+16+13-xcomp, y+11-ycomp, 3, 3, accent); // point (behind)
toaster committed
1141 1142

		precision = max(3, abs(xcomp));
1143
		for (i = 0; i < precision; i++) // line
toaster committed
1144
		{
1145 1146
			V_DrawFill(x+16+14-(i*xcomp)/precision,
				y+12-(i*ycomp)/precision,
1147
				1, 1, hudinfo[HUD_LIVES].f|16);
toaster committed
1148 1149 1150
		}

		if (ycomp <= 0)
1151
			V_DrawFill(x+16+13-xcomp, y+11-ycomp, 3, 3, accent); // point (in front)
toaster committed
1152 1153 1154
	}

#undef drawbutt
1155 1156 1157 1158

	// text above
	x -= 2;
	y -= 13;
1159
	if (stplyr->powers[pw_carry] != CR_NIGHTSMODE)
1160
	{
1161 1162 1163
		if (stplyr->pflags & PF_AUTOBRAKE)
		{
			V_DrawThinString(x, y,
1164
				hudinfo[HUD_LIVES].f|
1165 1166 1167
				((!stplyr->powers[pw_carry]
				&& (stplyr->pflags & PF_APPLYAUTOBRAKE)
				&& !(stplyr->cmd.sidemove || stplyr->cmd.forwardmove)
1168 1169
				&& (stplyr->rmomx || stplyr->rmomy)
				&& (!stplyr->capsule || (stplyr->capsule->reactiontime != (stplyr-players)+1)))
1170 1171 1172 1173
				? 0 : V_GRAYMAP),
				"AUTOBRAKE");
			y -= 8;
		}
1174
		switch (P_ControlStyle(stplyr))
1175
		{
1176
		case CS_LMAOGALOG:
1177
			V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "ANALOG");
1178
			y -= 8;
1179 1180 1181 1182 1183 1184 1185 1186 1187
			break;

		case CS_SIMPLE:
			V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "SIMPLE");
			y -= 8;
			break;

		default:
			break;
1188
		}
1189 1190
	}
	if (!demosynced) // should always be last, so it doesn't push anything else around
1191
		V_DrawThinString(x, y, hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!");
toaster committed
1192 1193
}

Jaime Ita Passos committed
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
static patch_t *lt_patches[3];
static INT32 lt_scroll = 0;
static INT32 lt_mom = 0;
static INT32 lt_zigzag = 0;

tic_t lt_ticker = 0, lt_lasttic = 0;
tic_t lt_exitticker = 0, lt_endtime = 0;

//
// Load the graphics for the title card.
1204
// Don't let LJ see this
Jaime Ita Passos committed
1205 1206 1207
//
static void ST_cacheLevelTitle(void)
{
1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230
#define SETPATCH(default, warning, custom, idx) \
{ \
	lumpnum_t patlumpnum = LUMPERROR; \
	if (mapheaderinfo[gamemap-1]->custom[0] != '\0') \
	{ \
		patlumpnum = W_CheckNumForName(mapheaderinfo[gamemap-1]->custom); \
		if (patlumpnum != LUMPERROR) \
			lt_patches[idx] = (patch_t *)W_CachePatchNum(patlumpnum, PU_HUDGFX); \
	} \
	if (patlumpnum == LUMPERROR) \
	{ \
		if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE)) \
			lt_patches[idx] = (patch_t *)W_CachePatchName(default, PU_HUDGFX); \
		else \
			lt_patches[idx] = (patch_t *)W_CachePatchName(warning, PU_HUDGFX); \
	} \
}

	SETPATCH("LTACTBLU", "LTACTRED", ltactdiamond, 0)
	SETPATCH("LTZIGZAG", "LTZIGRED", ltzzpatch, 1)
	SETPATCH("LTZZTEXT", "LTZZWARN", ltzztext, 2)

#undef SETPATCH
Jaime Ita Passos committed
1231 1232 1233 1234 1235 1236 1237
}

//
// Start the title card.
//
void ST_startTitleCard(void)
{
Jaime Ita Passos committed
1238
	// cache every HUD patch used
Jaime Ita Passos committed
1239
	ST_cacheLevelTitle();
Jaime Ita Passos committed
1240 1241

	// initialize HUD variables
Jaime Ita Passos committed
1242
	lt_ticker = lt_exitticker = lt_lasttic = 0;
Jaime Ita Passos committed
1243
	lt_endtime = 2*TICRATE + (10*NEWTICRATERATIO);
Jaime Ita Passos committed
1244 1245 1246 1247 1248 1249
	lt_scroll = BASEVIDWIDTH * FRACUNIT;
	lt_zigzag = -((lt_patches[1])->width * FRACUNIT);
	lt_mom = 0;
}

//
Jaime Ita Passos committed
1250
// What happens before drawing the title card.
Jaime Ita Passos committed
1251 1252 1253 1254
// Which is just setting the HUD translucency.
//
void ST_preDrawTitleCard(void)
{
Jaime Ita Passos committed
1255 1256 1257
	if (!G_IsTitleCardAvailable())
		return;

Jaime Ita Passos committed
1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272
	if (lt_ticker >= (lt_endtime + TICRATE))
		return;

	if (!lt_exitticker)
		st_translucency = 0;
	else
		st_translucency = max(0, min((INT32)lt_exitticker-4, cv_translucenthud.value));
}

//
// Run the title card.
// Called from ST_Ticker.
//
void ST_runTitleCard(void)
{
1273 1274
	boolean run = !(paused || P_AutoPause());

Jaime Ita Passos committed
1275 1276 1277
	if (!G_IsTitleCardAvailable())
		return;

Jaime Ita Passos committed
1278 1279 1280
	if (lt_ticker >= (lt_endtime + TICRATE))
		return;

1281
	if (run || (lt_ticker < PRELEVELTIME))
Jaime Ita Passos committed
1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320
	{
		// tick
		lt_ticker++;
		if (lt_ticker >= lt_endtime)
			lt_exitticker++;

		// scroll to screen (level title)
		if (!lt_exitticker)
		{
			if (abs(lt_scroll) > FRACUNIT)
				lt_scroll -= (lt_scroll>>2);
			else
				lt_scroll = 0;
		}
		// scroll away from screen (level title)
		else
		{
			lt_mom -= FRACUNIT*6;
			lt_scroll += lt_mom;
		}

		// scroll to screen (zigzag)
		if (!lt_exitticker)
		{
			if (abs(lt_zigzag) > FRACUNIT)
				lt_zigzag -= (lt_zigzag>>2);
			else
				lt_zigzag = 0;
		}
		// scroll away from screen (zigzag)
		else
			lt_zigzag += lt_mom;
	}
}

//
// Draw the title card itself.
//
void ST_drawTitleCard(void)
Alam Ed Arias committed
1321 1322 1323
{
	char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl;
	char *subttl = mapheaderinfo[gamemap-1]->subttl;
1324
	UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
Jaime Ita Passos committed
1325
	INT32 lvlttlxpos, ttlnumxpos, zonexpos;
Alam Ed Arias committed
1326
	INT32 subttlxpos = BASEVIDWIDTH/2;
Jaime Ita Passos committed
1327 1328 1329
	INT32 ttlscroll = FixedInt(lt_scroll);
	INT32 zzticker;
	patch_t *actpat, *zigzag, *zztext;
Tatsuru committed
1330 1331
	UINT8 colornum;
	const UINT8 *colormap;
1332 1333 1334

	if (players[consoleplayer].skincolor)
		colornum = players[consoleplayer].skincolor;
Tatsuru committed
1335 1336
	else
		colornum = cv_playercolor.value;
1337

Tatsuru committed
1338
	colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE);
Alam Ed Arias committed
1339

Jaime Ita Passos committed
1340 1341 1342
	if (!G_IsTitleCardAvailable())
		return;

Jaime Ita Passos committed
1343 1344
	if (!LUA_HudEnabled(hud_stagetitle))
		goto luahook;
Alam Ed Arias committed
1345

Jaime Ita Passos committed
1346
	if (lt_ticker >= (lt_endtime + TICRATE))
Jaime Ita Passos committed
1347
		goto luahook;
Alam Ed Arias committed
1348

Jaime Ita Passos committed
1349 1350 1351 1352 1353 1354 1355
	if ((lt_ticker-lt_lasttic) > 1)
		lt_ticker = lt_lasttic+1;

	ST_cacheLevelTitle();
	actpat = lt_patches[0];
	zigzag = lt_patches[1];
	zztext = lt_patches[2];
Alam Ed Arias committed
1356

1357 1358
	lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2));

Alam Ed Arias committed
1359
	if (actnum > 0)
1360
		lvlttlxpos -= V_LevelActNumWidth(actnum);
Alam Ed Arias committed
1361 1362

	ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl);
Nev3r committed
1363
	zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("Zone"));
1364
	ttlnumxpos++;
Alam Ed Arias committed
1365 1366 1367 1368

	if (lvlttlxpos < 0)
		lvlttlxpos = 0;

Jaime Ita Passos committed
1369
	if (!splitscreen || (splitscreen && stplyr == &players[displayplayer]))
1370
	{
1371
		zzticker = lt_ticker;
Tatsuru committed
1372 1373 1374 1375
		V_DrawMappedPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap);
		V_DrawMappedPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap);
		V_DrawMappedPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap);
		V_DrawMappedPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap);
1376 1377
	}

Jaime Ita Passos committed
1378
	if (actnum)
1379
	{
1380
		if (!splitscreen)
1381
		{
1382
			if (actnum > 9) // slightly offset the act diamond for two-digit act numbers
1383 1384 1385 1386
				V_DrawMappedPatch(ttlnumxpos + (V_LevelActNumWidth(actnum)/4) + ttlscroll, 104 - ttlscroll, 0, actpat, colormap);
			else
				V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap);
		}
Jaime Ita Passos committed
1387
		V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum);
1388 1389
	}

Jaime Ita Passos committed
1390 1391
	V_DrawLevelTitle(lvlttlxpos - ttlscroll, 80, V_PERPLAYER, lvlttl);
	if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
1392
		V_DrawLevelTitle(zonexpos + ttlscroll, 104, V_PERPLAYER, M_GetText("Zone"));
1393
	V_DrawCenteredString(subttlxpos - ttlscroll, 135, V_PERPLAYER|V_ALLOWLOWERCASE, subttl);
Alam Ed Arias committed
1394

Jaime Ita Passos committed
1395
	lt_lasttic = lt_ticker;
Jaime Ita Passos committed
1396 1397 1398

luahook:
	LUAh_TitleCardHUD(stplyr);
Jaime Ita Passos committed
1399
}
Alam Ed Arias committed
1400

Jaime Ita Passos committed
1401
//
Jaime Ita Passos committed
1402
// Drawer for G_PreLevelTitleCard.
Jaime Ita Passos committed
1403
//
1404
void ST_preLevelTitleCardDrawer(void)
Jaime Ita Passos committed
1405 1406
{
	V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
1407
	ST_drawWipeTitleCard();
Jaime Ita Passos committed
1408 1409 1410
	I_OsPolling();
	I_UpdateNoBlit();
}
Alam Ed Arias committed
1411

Jaime Ita Passos committed
1412 1413
//
// Draw the title card while on a wipe.
Jaime Ita Passos committed
1414
// Also used in G_PreLevelTitleCard.
Jaime Ita Passos committed
1415 1416 1417 1418 1419 1420 1421
//
void ST_drawWipeTitleCard(void)
{
	stplyr = &players[consoleplayer];
	ST_preDrawTitleCard();
	ST_drawTitleCard();
	if (splitscreen)
SteelT committed
1422
	{
Jaime Ita Passos committed
1423 1424 1425
		stplyr = &players[secondarydisplayplayer];
		ST_preDrawTitleCard();
		ST_drawTitleCard();
SteelT committed
1426
	}
Alam Ed Arias committed
1427 1428
}

toaster committed
1429
static void ST_drawPowerupHUD(void)
Alam Ed Arias committed
1430 1431
{
	patch_t *p = NULL;
Alam Ed Arias committed
1432
	UINT16 invulntime = 0;
toaster committed
1433
	INT32 offs = hudinfo[HUD_POWERUPS].x;
1434
	const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0);
1435
	static INT32 flagoffs[2] = {0, 0}, shieldoffs[2] = {0, 0}, finishoffs[2] = {0, 0};
toaster committed
1436
#define ICONSEP (16+4) // matches weapon rings HUD
Alam Ed Arias committed
1437

1438 1439 1440
	if (F_GetPromptHideHud(hudinfo[HUD_POWERUPS].y))
		return;

toaster committed
1441
	if (stplyr->spectator || stplyr->playerstate != PST_LIVE)
Alam Ed Arias committed
1442
		return;
1443

1444 1445 1446 1447 1448
// ---------
// Finish icon
// ---------

	// Let's have a power-like icon to represent finishing the level!
1449
	if (stplyr->pflags & PF_FINISHED && cv_exitmove.value && multiplayer)
1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462
	{
		finishoffs[q] = ICONSEP;
		V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, fnshico);
	}
	else if (finishoffs[q])
	{
		if (finishoffs[q] > 1)
			finishoffs[q] = 2*finishoffs[q]/3;
		else
			finishoffs[q] = 0;
	}

	offs -= finishoffs[q];
Alam Ed Arias committed
1463

1464 1465 1466 1467
// -------
// Shields
// -------

Alam Ed Arias committed
1468
	// Graue 06-18-2004: no V_NOSCALESTART, no SCX, no SCY, snap to right
toaster committed
1469
	if (stplyr->powers[pw_shield] & SH_NOSTACK)
toaster committed
1470
	{
1471
		shieldoffs[q] = ICONSEP;
toaster committed
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481

		if ((stplyr->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE)
		{
			UINT8 i, max = (stplyr->powers[pw_shield] & SH_FORCEHP);
			for (i = 0; i <= max; i++)
			{
				V_DrawSmallScaledPatch(offs-(i<<1), hudinfo[HUD_POWERUPS].y-(i<<1), (V_PERPLAYER|hudinfo[HUD_POWERUPS].f)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF), forceshield);
			}
		}
		else
toaster committed
1482
		{
toaster committed
1483 1484 1485 1486 1487 1488 1489
			switch (stplyr->powers[pw_shield] & SH_NOSTACK)
			{
				case SH_WHIRLWIND:   p = jumpshield;    break;
				case SH_ELEMENTAL:   p = watershield;   break;
				case SH_ARMAGEDDON:  p = bombshield;    break;
				case SH_ATTRACT:     p = ringshield;    break;
				case SH_PITY:        p = pityshield;    break;
1490
				case SH_PINK:        p = pinkshield;    break;
toaster committed
1491 1492 1493 1494 1495 1496 1497 1498
				case SH_FLAMEAURA:   p = flameshield;   break;
				case SH_BUBBLEWRAP:  p = bubbleshield;  break;
				case SH_THUNDERCOIN: p = thundershield; break;
				default: break;
			}

			if (p)
				V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p);
toaster committed
1499 1500
		}
	}
1501
	else if (shieldoffs[q])
Alam Ed Arias committed
1502
	{
1503 1504
		if (shieldoffs[q] > 1)
			shieldoffs[q] = 2*shieldoffs[q]/3;
toaster committed
1505
		else
1506
			shieldoffs[q] = 0;
Alam Ed Arias committed
1507 1508
	}

1509
	offs -= shieldoffs[q];
toaster committed
1510

1511 1512 1513 1514
// ---------
// CTF flags
// ---------