1 /*
2 ===========================================================================
3 Copyright (C) 1999 - 2005, Id Software, Inc.
4 Copyright (C) 2000 - 2013, Raven Software, Inc.
5 Copyright (C) 2001 - 2013, Activision, Inc.
6 Copyright (C) 2013 - 2015, OpenJK contributors
7 
8 This file is part of the OpenJK source code.
9 
10 OpenJK is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License version 2 as
12 published by the Free Software Foundation.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 ===========================================================================
22 */
23 
24 #include "cg_headers.h"
25 
26 #include "cg_media.h"
27 #include "../game/objectives.h"
28 
29 
30 // For printing objectives
31 static const short objectiveStartingYpos = 75;		// Y starting position for objective text
32 static const short objectiveStartingXpos = 60;		// X starting position for objective text
33 static const int objectiveTextBoxWidth = 500;		// Width (in pixels) of text box
34 static const int objectiveTextBoxHeight = 300;		// Height (in pixels) of text box
35 
36 const char *showLoadPowersName[] =
37 {
38 	"SP_INGAME_HEAL2",
39 	"SP_INGAME_JUMP2",
40 	"SP_INGAME_SPEED2",
41 	"SP_INGAME_PUSH2",
42 	"SP_INGAME_PULL2",
43 	"SP_INGAME_MINDTRICK2",
44 	"SP_INGAME_GRIP2",
45 	"SP_INGAME_LIGHTNING2",
46 	"SP_INGAME_SABER_THROW2",
47 	"SP_INGAME_SABER_OFFENSE2",
48 	"SP_INGAME_SABER_DEFENSE2",
49 	NULL,
50 };
51 
52 #define MAX_OBJ_GRAPHICS 4
53 #define OBJ_GRAPHIC_SIZE 240
54 int obj_graphics[MAX_OBJ_GRAPHICS];
55 
56 qboolean CG_ForcePower_Valid(int forceKnownBits, int index);
57 
58 /*
59 ====================
60 ObjectivePrint_Line
61 
62 Print a single mission objective
63 ====================
64 */
ObjectivePrint_Line(const int color,const int objectIndex,int & missionYcnt)65 static void ObjectivePrint_Line(const int color, const int objectIndex, int &missionYcnt)
66 {
67 	char *str,*strBegin;
68 	int y,pixelLen,charLen,i;
69 	const int maxHoldText = 1024;
70 	char holdText[maxHoldText];
71 	char finalText[2048];
72 	qhandle_t	graphic;
73 
74 	int iYPixelsPerLine = cgi_R_Font_HeightPixels(cgs.media.qhFontMedium, 1.0f);
75 
76 	cgi_SP_GetStringTextString( va("OBJECTIVES_%s",objectiveTable[objectIndex].name) , finalText, sizeof(finalText) );
77 
78 	// A hack to be able to count prisoners
79 	if (objectIndex==T2_RANCOR_OBJ5)
80 	{
81 		char value[64];
82 		int	currTotal, minTotal;
83 
84 		gi.Cvar_VariableStringBuffer("ui_prisonerobj_currtotal",value,sizeof(value));
85 		currTotal = atoi(value);
86 		gi.Cvar_VariableStringBuffer("ui_prisonerobj_maxtotal",value,sizeof(value));
87 		minTotal = atoi(value);
88 
89 		Q_strncpyz(finalText, va(finalText,currTotal,minTotal), sizeof(finalText));
90 	}
91 
92 	pixelLen = cgi_R_Font_StrLenPixels(finalText, cgs.media.qhFontMedium, 1.0f);
93 
94 	str = finalText;
95 
96 	if (cgi_Language_IsAsian())
97 	{
98 		// this is execrable, and should NOT have had to've been done now, but...
99 		//
100 		extern const char *CG_DisplayBoxedText(	int iBoxX, int iBoxY, int iBoxWidth, int iBoxHeight,
101 												const char *psText, int iFontHandle, float fScale,
102 												const vec4_t v4Color);
103 		extern int giLinesOutput;
104 		extern float gfAdvanceHack;
105 
106 		gfAdvanceHack = 1.0f;	// override internal vertical advance
107 		y = objectiveStartingYpos + (iYPixelsPerLine * missionYcnt);
108 
109 		// Advance line if a graphic has printed
110 		for (i=0;i<MAX_OBJ_GRAPHICS;i++)
111 		{
112 			if (obj_graphics[i])
113 			{
114 				y += OBJ_GRAPHIC_SIZE + 4;
115 			}
116 		}
117 
118 		CG_DisplayBoxedText(
119 			objectiveStartingXpos,
120 			y,
121 			objectiveTextBoxWidth,
122 			objectiveTextBoxHeight,
123 			finalText,	// int iBoxX, int iBoxY, int iBoxWidth, int iBoxHeight, const char *psText
124 			cgs.media.qhFontMedium,		// int iFontHandle,
125 			1.0f,						// float fScale,
126 			colorTable[color]			// const vec4_t v4Color
127 			);
128 
129 		gfAdvanceHack = 0.0f;	// restore
130 		missionYcnt += giLinesOutput;
131 	}
132 	else
133 	{
134 		// western...
135 		//
136 		if (pixelLen < objectiveTextBoxWidth)	// One shot - small enough to print entirely on one line
137 		{
138 			y =objectiveStartingYpos + (iYPixelsPerLine * (missionYcnt));
139 
140 			cgi_R_Font_DrawString (
141 				objectiveStartingXpos,
142 				y,
143 				str,
144 				colorTable[color],
145 				cgs.media.qhFontMedium,
146 				-1,
147 				1.0f);
148 
149 			++missionYcnt;
150 		}
151 		// Text is too long, break into lines.
152 		else
153 		{
154 			char holdText2[2];
155 			pixelLen = 0;
156 			charLen = 0;
157 			holdText2[1] = '\0';
158 			strBegin = str;
159 
160 			while( *str )
161 			{
162 				holdText2[0] = *str;
163 				pixelLen += cgi_R_Font_StrLenPixels(holdText2, cgs.media.qhFontMedium, 1.0f);
164 
165 				pixelLen += 2; // For kerning
166 				++charLen;
167 
168 				if (pixelLen > objectiveTextBoxWidth )
169 				{	//Reached max length of this line
170 					//step back until we find a space
171 					while ((charLen>10) && (*str != ' ' ))
172 					{
173 						--str;
174 						--charLen;
175 					}
176 
177 					if (*str==' ')
178 					{
179 						++str;	// To get past space
180 					}
181 
182 					assert( charLen<maxHoldText );	// Too big?
183 
184 					Q_strncpyz( holdText, strBegin, charLen);
185 					holdText[charLen] = '\0';
186 					strBegin = str;
187 					pixelLen = 0;
188 					charLen = 1;
189 
190 					y = objectiveStartingYpos + (iYPixelsPerLine * missionYcnt);
191 
192 					CG_DrawProportionalString(
193 						objectiveStartingXpos,
194 						y,
195 						holdText,
196 						CG_SMALLFONT,
197 						colorTable[color] );
198 
199 					++missionYcnt;
200 				}
201 				else if (*(str+1) == '\0')
202 				{
203 					++charLen;
204 
205 					assert( charLen<maxHoldText );	// Too big?
206 
207 					y = objectiveStartingYpos + (iYPixelsPerLine * missionYcnt);
208 
209 					Q_strncpyz( holdText, strBegin, charLen);
210 					CG_DrawProportionalString(
211 						objectiveStartingXpos,
212 						y, holdText,
213 						CG_SMALLFONT,
214 						colorTable[color] );
215 
216 					++missionYcnt;
217 					break;
218 				}
219 				++str;
220 
221 
222 			}
223 		}
224 	}
225 
226 	if (objectIndex == T3_BOUNTY_OBJ1)
227 	{
228 		y =objectiveStartingYpos + (iYPixelsPerLine * missionYcnt);
229 		if (obj_graphics[1])
230 		{
231 			y += OBJ_GRAPHIC_SIZE + 4;
232 		}
233 		if (obj_graphics[2])
234 		{
235 			y += OBJ_GRAPHIC_SIZE + 4;
236 		}
237 		graphic = cgi_R_RegisterShaderNoMip("textures/system/viewscreen1");
238 		CG_DrawPic( 355, 50, OBJ_GRAPHIC_SIZE, OBJ_GRAPHIC_SIZE, graphic );
239 		obj_graphics[3] = qtrue;
240 	}
241 
242 }
243 
244 /*
245 ====================
246 CG_DrawDataPadObjectives
247 
248 Draw routine for the objective info screen of the data pad.
249 ====================
250 */
CG_DrawDataPadObjectives(const centity_t * cent)251 void CG_DrawDataPadObjectives(const centity_t *cent )
252 {
253 	int		i,totalY;
254 	int		iYPixelsPerLine = cgi_R_Font_HeightPixels(cgs.media.qhFontMedium, 1.0f);
255 
256 	const short titleXPos = objectiveStartingXpos - 22;		// X starting position for title text
257 	const short titleYPos = objectiveStartingYpos - 23;		// Y starting position for title text
258 	const short graphic_size = 16;							// Size (width and height) of graphic used to show status of objective
259 	const short graphicXpos = objectiveStartingXpos - graphic_size - 8;	// Amount of X to backup from text starting position
260 	const short graphicYOffset = (iYPixelsPerLine - graphic_size)/2;	// Amount of Y to raise graphic so it's in the center of the text line
261 
262 	missionInfo_Updated = qfalse;		// This will stop the text from flashing
263 	cg.missionInfoFlashTime = 0;
264 
265 	// zero out objective graphics
266 	for (i=0;i<MAX_OBJ_GRAPHICS;i++)
267 	{
268 		obj_graphics[i] = qfalse;
269 	}
270 
271 	// Title Text at the top
272 	char text[1024]={0};
273 	cgi_SP_GetStringTextString( "SP_INGAME_OBJECTIVES", text, sizeof(text) );
274 	cgi_R_Font_DrawString (titleXPos, titleYPos, text, colorTable[CT_TITLE], cgs.media.qhFontMedium, -1, 1.0f);
275 
276 	int missionYcnt = 0;
277 
278 	// Print all active objectives
279 	for (i=0;i<MAX_OBJECTIVES;i++)
280 	{
281 		// Is there an objective to see?
282 		if (cent->gent->client->sess.mission_objectives[i].display)
283 		{
284 			// Calculate the Y position
285 			totalY = objectiveStartingYpos + (iYPixelsPerLine * (missionYcnt))+(iYPixelsPerLine/2);
286 
287 			//	Draw graphics that show if mission has been accomplished or not
288 			cgi_R_SetColor(colorTable[CT_BLUE3]);
289 			CG_DrawPic( (graphicXpos),   (totalY-graphicYOffset),   graphic_size,  graphic_size, cgs.media.messageObjCircle);	// Circle in front
290 			if (cent->gent->client->sess.mission_objectives[i].status == OBJECTIVE_STAT_SUCCEEDED)
291 			{
292 				CG_DrawPic( (graphicXpos),   (totalY-graphicYOffset),   graphic_size,  graphic_size, cgs.media.messageLitOn);	// Center Dot
293 			}
294 
295 			// Print current objective text
296 			ObjectivePrint_Line(CT_WHITE, i, missionYcnt );
297 		}
298 	}
299 
300 	// No mission text?
301 	if (!missionYcnt)
302 	{
303 		// Set the message a quarter of the way down and in the center of the text box
304 		int messageYPosition = objectiveStartingYpos + (objectiveTextBoxHeight / 4);
305 
306 		cgi_SP_GetStringTextString( "SP_INGAME_OBJNONE", text, sizeof(text) );
307 		int messageXPosition = objectiveStartingXpos + (objectiveTextBoxWidth/2) -  (cgi_R_Font_StrLenPixels(text, cgs.media.qhFontMedium, 1.0f) /2);
308 
309 		cgi_R_Font_DrawString (
310 			messageXPosition,
311 			messageYPosition,
312 			text,
313 			colorTable[CT_WHITE],
314 			cgs.media.qhFontMedium,
315 			-1,
316 			1.0f);
317 	}
318 }
319 
320 /*
321 
322 //-------------------------------------------------------
323 static void CG_DrawForceCount( const int force, int x, float *y, const int pad,qboolean *hasForcePowers )
324 {
325 	char	s[MAX_STRING_CHARS];
326 	int		val, textColor;
327 	char	text[1024]={0};
328 
329 	gi.Cvar_VariableStringBuffer( va("playerfplvl%d", force ),s, sizeof(s) );
330 
331 	sscanf( s, "%d",&val );
332 
333 	if ((val<1) || (val> NUM_FORCE_POWERS))
334 	{
335 		return;
336 	}
337 
338 	textColor = CT_ICON_BLUE;
339 
340 	// Draw title
341 	cgi_SP_GetStringTextString( showLoadPowersName[force], text, sizeof(text) );
342 	CG_DrawProportionalString( x, *y, text, CG_BIGFONT, colorTable[textColor] );
343 
344 
345 	// Draw icons
346 	cgi_R_SetColor( colorTable[CT_WHITE]);
347 	const int iconSize = 30;
348 	if ( val >= 0 )
349 	{
350 		x -= 10;	// Back up from title a little
351 
352 		for ( int i = 0; i < val; i++ )
353 		{
354 			CG_DrawPic( x - iconSize - i * (iconSize + 10) , *y, iconSize, iconSize, force_icons[force] );
355 		}
356 	}
357 
358 	*y += pad;
359 
360 	*hasForcePowers = qtrue;
361 }
362 
363 
364 / *
365 ====================
366 CG_LoadScreen_PersonalInfo
367 ====================
368 */
369 /*
370 static void CG_LoadScreen_PersonalInfo(void)
371 {
372 	float	x, y;
373 	int		pad = 25;
374 	char	text[1024]={0};
375 	qboolean	hasForcePowers;
376 
377 	y = 65 + 30;
378 
379 	pad = 28;
380 	x = 300;
381 	hasForcePowers=qfalse;
382 
383 	CG_DrawForceCount( FP_HEAL, x, &y, pad,&hasForcePowers);
384 	CG_DrawForceCount( FP_LEVITATION, x, &y, pad,&hasForcePowers );
385 	CG_DrawForceCount( FP_SPEED, x, &y, pad,&hasForcePowers );
386 	CG_DrawForceCount( FP_PUSH, x, &y, pad,&hasForcePowers );
387 	CG_DrawForceCount( FP_PULL, x, &y, pad,&hasForcePowers );
388 	CG_DrawForceCount( FP_TELEPATHY, x, &y, pad,&hasForcePowers );
389 	CG_DrawForceCount( FP_GRIP, x, &y, pad,&hasForcePowers );
390 	CG_DrawForceCount( FP_LIGHTNING, x, &y, pad,&hasForcePowers );
391 	CG_DrawForceCount( FP_SABERTHROW, x, &y, pad,&hasForcePowers );
392 	CG_DrawForceCount( FP_SABER_OFFENSE, x, &y, pad,&hasForcePowers );
393 	CG_DrawForceCount( FP_SABER_DEFENSE, x, &y, pad,&hasForcePowers );
394 
395 	if (hasForcePowers)
396 	{
397 		cgi_SP_GetStringTextString( "SP_INGAME_CURRENTFORCEPOWERS", text, sizeof(text) );
398 		CG_DrawProportionalString( 200, 65, text, CG_CENTER | CG_BIGFONT, colorTable[CT_WHITE] );
399 	}
400 	else
401 	{	//you are only totally empty on the very first map?
402 //		cgi_SP_GetStringTextString( "SP_INGAME_NONE", text, sizeof(text) );
403 //		CG_DrawProportionalString( 320, y+30, text, CG_CENTER | CG_BIGFONT, colorTable[CT_ICON_BLUE] );
404 		cgi_SP_GetStringTextString( "SP_INGAME_ALONGTIME", text, sizeof(text) );
405 		int w = cgi_R_Font_StrLenPixels(text,cgs.media.qhFontMedium, 1.5f);
406 		cgi_R_Font_DrawString((320)-(w/2), y+40, text,  colorTable[CT_ICON_BLUE], cgs.media.qhFontMedium, -1, 1.5f);
407 	}
408 
409 }
410 */
411 
CG_LoadBar(void)412 static void CG_LoadBar(void)
413 {
414 	const int numticks = 9, tickwidth = 40, tickheight = 8;
415 	const int tickpadx = 20, tickpady = 12;
416 	const int capwidth = 8;
417 	const int barwidth = numticks*tickwidth+tickpadx*2+capwidth*2, barleft = ((640-barwidth)/2);
418 	const int barheight = tickheight + tickpady*2, bartop = 475-barheight;
419 	const int capleft = barleft+tickpadx, tickleft = capleft+capwidth, ticktop = bartop+tickpady;
420 
421 	cgi_R_SetColor( colorTable[CT_WHITE]);
422 	// Draw background
423 	CG_DrawPic(barleft, bartop, barwidth, barheight, cgs.media.levelLoad);
424 
425 	// Draw left cap (backwards)
426 	CG_DrawPic(tickleft, ticktop, -capwidth, tickheight, cgs.media.loadTickCap);
427 
428 	// Draw bar
429 	CG_DrawPic(tickleft, ticktop, tickwidth*cg.loadLCARSStage, tickheight, cgs.media.loadTick);
430 
431 	// Draw right cap
432 	CG_DrawPic(tickleft+tickwidth*cg.loadLCARSStage, ticktop, capwidth, tickheight, cgs.media.loadTickCap);
433 }
434 
435 int CG_WeaponCheck( int weaponIndex );
436 
437 // For printing load screen icons
438 const int	MAXLOADICONSPERROW = 8;		// Max icons displayed per row
439 const int	MAXLOADWEAPONS = 16;
440 const int	MAXLOAD_FORCEICONSIZE = 40;	// Size of force power icons
441 const int	MAXLOAD_FORCEICONPAD = 12;	// Padding space between icons
442 
CG_DrawLoadWeaponsPrintRow(const char * itemName,int weaponsBits,int rowIconCnt,int startIndex)443 static int CG_DrawLoadWeaponsPrintRow( const char *itemName, int weaponsBits,int rowIconCnt, int startIndex)
444 {
445 	int		i,endIndex=0, printedIconCnt=0;
446 	int		iconSize;
447 	int		holdX,x,y,pad;
448 	int		yOffset = 0;
449 	int		width,height;
450 	vec4_t	color;
451 	qhandle_t	background;
452 
453 	if (!cgi_UI_GetMenuItemInfo(
454 		"loadScreen",
455 		itemName,
456 		&x,
457 		&y,
458 		&width,
459 		&height,
460 		color,
461 		&background))
462 	{
463 		return(0);
464 	}
465 
466 	cgi_R_SetColor( color );
467 
468 	iconSize = 60;
469 	pad = 12;
470 
471 	// calculate placement of weapon icons
472 	holdX = x + (width - ((iconSize*rowIconCnt) + (pad * (rowIconCnt-1))))/2;
473 
474 	for (i=startIndex;i<MAXLOADWEAPONS;i++)
475 	{
476 		if ( !(weaponsBits & ( 1 << i )))	// Does he have this weapon?
477 		{
478 			continue;
479 		}
480 
481 		if (weaponData[i].weaponIcon[0])
482 		{
483 			weaponInfo_t	*weaponInfo;
484 			CG_RegisterWeapon( i );
485 			weaponInfo = &cg_weapons[i];
486 			endIndex = i;
487 
488 	// NOTE : during loading screen always show the have ammo icon
489 	//		if (!CG_WeaponCheck(i))
490 	//		{
491 	//			CG_DrawPic( holdX, y+yOffset, iconSize, iconSize, weaponInfo->weaponIconNoAmmo );
492 	//		}
493 	//		else
494 			{
495 				CG_DrawPic( holdX, y+yOffset, iconSize, iconSize, weaponInfo->weaponIcon );
496 			}
497 
498 			printedIconCnt++;
499 			if (printedIconCnt==MAXLOADICONSPERROW)
500 			{
501 				break;
502 			}
503 
504 			holdX += (iconSize+pad);
505 		}
506 	}
507 
508 	return (endIndex);
509 }
510 
511 // Print weapons the player is carrying
512 // Two rows print if there are too many
CG_DrawLoadWeapons(int weaponBits)513 static void CG_DrawLoadWeapons( int weaponBits )
514 {
515 	int		i,endIndex=0;
516 	int		iconCnt,rowIconCnt;
517 
518 	// count the number of weapons owned
519 	iconCnt = 0;
520 	for ( i = 1 ; i < MAXLOADWEAPONS ; i++ )
521 	{
522 		if ( weaponBits & ( 1 << i ) )
523 		{
524 			iconCnt++;
525 		}
526 	}
527 
528 	if (!iconCnt)	// If no weapons, don't display
529 	{
530 		return;
531 	}
532 
533 	// Single line of icons
534 	if (iconCnt<=MAXLOADICONSPERROW)
535 	{
536 		CG_DrawLoadWeaponsPrintRow("weaponicons_singlerow", weaponBits, iconCnt,0);
537 	}
538 	// Two lines of icons
539 	else
540 	{
541 		// Print top row
542 		endIndex = CG_DrawLoadWeaponsPrintRow("weaponicons_row1", weaponBits, MAXLOADICONSPERROW,0);
543 
544 		// Print second row
545 		rowIconCnt = iconCnt - MAXLOADICONSPERROW;
546 		CG_DrawLoadWeaponsPrintRow("weaponicons_row2", weaponBits, rowIconCnt,endIndex+1);
547 	}
548 
549 	cgi_R_SetColor( NULL );
550 }
551 
552 
CG_DrawLoadForcePrintRow(const char * itemName,int forceBits,int rowIconCnt,int startIndex)553 static int CG_DrawLoadForcePrintRow( const char *itemName, int forceBits,int rowIconCnt, int startIndex)
554 {
555 	int		i,endIndex=0, printedIconCnt=0;
556 	int		holdX,x,y;
557 	int		yOffset = 0;
558 	int		width,height;
559 	vec4_t	color;
560 	qhandle_t	background;
561 
562 	if (!cgi_UI_GetMenuItemInfo(
563 		"loadScreen",
564 		itemName,
565 		&x,
566 		&y,
567 		&width,
568 		&height,
569 		color,
570 		&background))
571 	{
572 		return(0);
573 	}
574 
575 	cgi_R_SetColor( color );
576 
577 	// calculate placement of weapon icons
578 	holdX = x + (width - ((MAXLOAD_FORCEICONSIZE*rowIconCnt) + (MAXLOAD_FORCEICONPAD * (rowIconCnt-1))))/2;
579 
580 	for (i=startIndex;i<MAX_SHOWPOWERS;i++)
581 	{
582 		if (!CG_ForcePower_Valid(forceBits,i))	// Does he have this power?
583 		{
584 			continue;
585 		}
586 
587 		if (force_icons[showPowers[i]])
588 		{
589 			endIndex = i;
590 
591 			CG_DrawPic( holdX, y+yOffset, MAXLOAD_FORCEICONSIZE, MAXLOAD_FORCEICONSIZE, force_icons[showPowers[i]] );
592 
593 			printedIconCnt++;
594 			if (printedIconCnt==MAXLOADICONSPERROW)
595 			{
596 				break;
597 			}
598 
599 			holdX += (MAXLOAD_FORCEICONSIZE+MAXLOAD_FORCEICONPAD);
600 		}
601 	}
602 
603 	return (endIndex);
604 }
605 
606 int			loadForcePowerLevel[NUM_FORCE_POWERS];
607 
608 /*
609 ===============
610 ForcePowerDataPad_Valid
611 ===============
612 */
CG_ForcePower_Valid(int forceKnownBits,int index)613 qboolean CG_ForcePower_Valid(int forceKnownBits, int index)
614 {
615 	if ((forceKnownBits & (1 << showPowers[index])) &&
616 		loadForcePowerLevel[showPowers[index]])	// Does he have the force power?
617 	{
618 		return qtrue;
619 	}
620 
621 	return qfalse;
622 }
623 
624 // Print force powers the player is using
625 // Two rows print if there are too many
CG_DrawLoadForcePowers(int forceBits)626 static void CG_DrawLoadForcePowers( int forceBits )
627 {
628 	int		i,endIndex=0;
629 	int		iconCnt=0,rowIconCnt;
630 
631 	// Count the number of force powers known
632 	for (i=0; i<MAX_SHOWPOWERS; ++i)
633 	{
634 		if (CG_ForcePower_Valid(forceBits, i))
635 		{
636 			iconCnt++;
637 		}
638 	}
639 
640 	if (!iconCnt)	// If no force powers, don't display
641 	{
642 		return;
643 	}
644 
645 	// Single line of icons
646 	if (iconCnt<=MAXLOADICONSPERROW)
647 	{
648 		CG_DrawLoadForcePrintRow("forceicons_singlerow", forceBits, iconCnt,0);
649 	}
650 	// Two lines of icons
651 	else
652 	{
653 		// Print top row
654 		endIndex = CG_DrawLoadForcePrintRow("forceicons_row1", forceBits, MAXLOADICONSPERROW,0);
655 
656 		// Print second row
657 		rowIconCnt = iconCnt - MAXLOADICONSPERROW;
658 		CG_DrawLoadForcePrintRow("forceicons_row2", forceBits, rowIconCnt,endIndex+1);
659 	}
660 
661 	cgi_R_SetColor( NULL );
662 }
663 
664 // Get the player weapons and force power info
CG_GetLoadScreenInfo(int * weaponBits,int * forceBits)665 static void CG_GetLoadScreenInfo(int *weaponBits,int *forceBits)
666 {
667 	char	s[MAX_STRING_CHARS];
668 	int		iDummy,i;
669 	float	fDummy;
670 	const char	*var;
671 
672 	gi.Cvar_VariableStringBuffer( sCVARNAME_PLAYERSAVE, s, sizeof(s) );
673 
674 	// Get player weapons and force powers known
675 	if (s[0])
676 	{
677 	//				|general info				  |-force powers
678 		sscanf( s, "%i %i %i %i %i %i %i %f %f %f %i %i",
679 				&iDummy,	//	&client->ps.stats[STAT_HEALTH],
680 				&iDummy,	//	&client->ps.stats[STAT_ARMOR],
681 				&*weaponBits,//	&client->ps.stats[STAT_WEAPONS],
682 				&iDummy,	//	&client->ps.stats[STAT_ITEMS],
683 				&iDummy,	//	&client->ps.weapon,
684 				&iDummy,	//	&client->ps.weaponstate,
685 				&iDummy,	//	&client->ps.batteryCharge,
686 				&fDummy,	//	&client->ps.viewangles[0],
687 				&fDummy,	//	&client->ps.viewangles[1],
688 				&fDummy,	//	&client->ps.viewangles[2],
689 							//force power data
690 				&*forceBits,	//	&client->ps.forcePowersKnown,
691 				&iDummy		//	&client->ps.forcePower,
692 
693 				);
694 	}
695 
696 	// the new JK2 stuff - force powers, etc...
697 	//
698 	gi.Cvar_VariableStringBuffer( "playerfplvl", s, sizeof(s) );
699 	i=0;
700 	var = strtok( s, " " );
701 	while( var != NULL )
702 	{
703 		/* While there are tokens in "s" */
704 		loadForcePowerLevel[i++] = atoi(var);
705 		/* Get next token: */
706 		var = strtok( NULL, " " );
707 	}
708 }
709 
710 /*
711 ====================
712 CG_DrawLoadingScreen
713 
714 Load screen displays the map pic, the mission briefing and weapons/force powers
715 ====================
716 */
CG_DrawLoadingScreen(qhandle_t levelshot,const char * mapName)717 static void CG_DrawLoadingScreen( qhandle_t	levelshot ,const char *mapName)
718 {
719 	int xPos,yPos,width,height;
720 	vec4_t	color;
721 	qhandle_t	background;
722 	int weapons=0, forcepowers=0;
723 
724 	// Get mission briefing for load screen
725 	if (cgi_SP_GetStringTextString( va("BRIEFINGS_%s",mapName), NULL, 0 ) == 0)
726 	{
727 		cgi_Cvar_Set( "ui_missionbriefing", "@BRIEFINGS_NONE" );
728 	}
729 	else
730 	{
731 		cgi_Cvar_Set( "ui_missionbriefing", va("@BRIEFINGS_%s",mapName) );
732 	}
733 
734 	// Print background
735 	if (cgi_UI_GetMenuItemInfo(
736 		"loadScreen",
737 		"background",
738 		&xPos,
739 		&yPos,
740 		&width,
741 		&height,
742 		color,
743 		&background))
744 	{
745 		cgi_R_SetColor( color );
746 		CG_DrawPic( xPos, yPos, width, height, background );
747 	}
748 
749 	// Print level pic
750 	if (cgi_UI_GetMenuItemInfo(
751 		"loadScreen",
752 		"mappic",
753 		&xPos,
754 		&yPos,
755 		&width,
756 		&height,
757 		color,
758 		&background))
759 	{
760 		//if (!levelshot)
761 		//{// No level shot so use screenshot.
762  	//		CG_DrawPic( xPos, yPos, 1, 1, 0);	//force the tess to flush
763 		//	cgi_R_DrawScreenShot( xPos, yPos+height, width, -height );
764 		//}
765 		//else
766 		{
767 			cgi_R_SetColor( color );
768 			CG_DrawPic( xPos, yPos, width, height, levelshot );
769 		}
770 	}
771 
772 	// Get player weapons and force power info
773 	CG_GetLoadScreenInfo(&weapons,&forcepowers);
774 
775 	// Print weapon icons
776 	if (weapons)
777 	{
778 		CG_DrawLoadWeapons(weapons);
779 	}
780 
781 	// Print force power icons
782 	if (forcepowers)
783 	{
784 		CG_DrawLoadForcePowers(forcepowers);
785 	}
786 }
787 
788 /*
789 ====================
790 CG_DrawInformation
791 
792 Draw all the status / pacifier stuff during level loading
793 ====================
794 */
CG_DrawInformation(void)795 void CG_DrawInformation( void ) {
796 	int		y;
797 
798 	// draw the dialog background
799 	const char	*info	= CG_ConfigString( CS_SERVERINFO );
800 	const char	*s		= Info_ValueForKey( info, "mapname" );
801 
802 	qhandle_t	levelshot;
803 
804 	extern SavedGameJustLoaded_e g_eSavedGameJustLoaded;	// hack! (hey, it's the last week of coding, ok?
805 //	if ( g_eSavedGameJustLoaded == eFULL )
806 //	{
807 //		levelshot = 0;	//use the loaded thumbnail instead of the levelshot
808 //	}
809 //	else
810 	{
811 		levelshot = cgi_R_RegisterShaderNoMip( va( "levelshots/%s", s ) );
812 	#ifndef FINAL_BUILD
813 		if (!levelshot && !strncmp(s, "work/",5) )
814 		{
815 			levelshot = cgi_R_RegisterShaderNoMip( va( "levelshots/%s", s+5 ) );
816 		}
817 	#endif
818 		if (!levelshot) {
819 			levelshot = cgi_R_RegisterShaderNoMip( "menu/art/unknownmap" );
820 		}
821 	}
822 
823 	if ( g_eSavedGameJustLoaded != eFULL && !strcmp(s,"yavin1") )//special case for first map!
824 	{
825 		char	text[1024]={0};
826 
827 		//
828 		cgi_R_SetColor( colorTable[CT_BLACK] );
829 		CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, cgs.media.whiteShader );
830 
831 		cgi_SP_GetStringTextString( "SP_INGAME_ALONGTIME", text, sizeof(text) );
832 
833 		int w = cgi_R_Font_StrLenPixels(text,cgs.media.qhFontMedium, 1.0f);
834 		cgi_R_Font_DrawString((320)-(w/2), 140, text,  colorTable[CT_ICON_BLUE], cgs.media.qhFontMedium, -1, 1.0f);
835 	}
836 	else
837 	{
838 		CG_DrawLoadingScreen(levelshot, s);
839 		cgi_UI_Menu_Paint( cgi_UI_GetMenuByName( "loadscreen" ), qtrue );
840 		//cgi_UI_MenuPaintAll();
841 	}
842 
843 	CG_LoadBar();
844 
845 
846 	// the first 150 rows are reserved for the client connection
847 	// screen to write into
848 //	if ( cg.processedSnapshotNum == 0 )
849 	{
850 		// still loading
851 		// print the current item being loaded
852 
853 #ifdef _DEBUG
854 		cgi_R_Font_DrawString( 40, 416, va("LOADING ... %s",cg.infoScreenText),colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 1.0f );
855 #endif
856 	}
857 
858 	// draw info string information
859 
860 	y = 20;
861 	// map-specific message (long map name)
862 	s = CG_ConfigString( CS_MESSAGE );
863 
864 	if ( s[0] )
865 	{
866 		if (s[0] == '@')
867 		{
868 			char text[1024]={0};
869 			cgi_SP_GetStringTextString( s+1, text, sizeof(text) );
870 			cgi_R_Font_DrawString( 15, y, va("\"%s\"",text),colorTable[CT_WHITE],cgs.media.qhFontMedium, -1, 1.0f );
871 		}
872 		else
873 		{
874 			cgi_R_Font_DrawString( 15, y, va("\"%s\"",s),colorTable[CT_WHITE],cgs.media.qhFontMedium, -1, 1.0f );
875 		}
876 		y += 20;
877 	}
878 }
879