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 // cg_info.c -- display information while data is being loading
25
26 #include "cg_local.h"
27
28 #define MAX_LOADING_PLAYER_ICONS 16
29 #define MAX_LOADING_ITEM_ICONS 26
30
31 //static int loadingPlayerIconCount;
32 //static qhandle_t loadingPlayerIcons[MAX_LOADING_PLAYER_ICONS];
33
34 void CG_LoadBar(void);
35
36 /*
37 ======================
38 CG_LoadingString
39
40 ======================
41 */
CG_LoadingString(const char * s)42 void CG_LoadingString( const char *s ) {
43 Q_strncpyz( cg.infoScreenText, s, sizeof( cg.infoScreenText ) );
44
45 trap->UpdateScreen();
46 }
47
48 /*
49 ===================
50 CG_LoadingItem
51 ===================
52 */
CG_LoadingItem(int itemNum)53 void CG_LoadingItem( int itemNum ) {
54 gitem_t *item;
55 char upperKey[1024];
56
57 item = &bg_itemlist[itemNum];
58
59 if (!item->classname || !item->classname[0])
60 {
61 // CG_LoadingString( "Unknown item" );
62 return;
63 }
64
65 strcpy(upperKey, item->classname);
66 CG_LoadingString( CG_GetStringEdString("SP_INGAME",Q_strupr(upperKey)) );
67 }
68
69 /*
70 ===================
71 CG_LoadingClient
72 ===================
73 */
CG_LoadingClient(int clientNum)74 void CG_LoadingClient( int clientNum ) {
75 const char *info;
76 char personality[MAX_QPATH];
77
78 info = CG_ConfigString( CS_PLAYERS + clientNum );
79
80 /*
81 char model[MAX_QPATH];
82 char iconName[MAX_QPATH];
83 char *skin;
84 if ( loadingPlayerIconCount < MAX_LOADING_PLAYER_ICONS ) {
85 Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) );
86 skin = Q_strrchr( model, '/' );
87 if ( skin ) {
88 *skin++ = '\0';
89 } else {
90 skin = "default";
91 }
92
93 Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", model, skin );
94
95 loadingPlayerIcons[loadingPlayerIconCount] = trap->R_RegisterShaderNoMip( iconName );
96 if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
97 Com_sprintf( iconName, MAX_QPATH, "models/players/characters/%s/icon_%s.tga", model, skin );
98 loadingPlayerIcons[loadingPlayerIconCount] = trap->R_RegisterShaderNoMip( iconName );
99 }
100 if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
101 Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", DEFAULT_MODEL, "default" );
102 loadingPlayerIcons[loadingPlayerIconCount] = trap->R_RegisterShaderNoMip( iconName );
103 }
104 if ( loadingPlayerIcons[loadingPlayerIconCount] ) {
105 loadingPlayerIconCount++;
106 }
107 }
108 */
109 Q_strncpyz( personality, Info_ValueForKey( info, "n" ), sizeof(personality) );
110 // Q_CleanStr( personality );
111
112 /*
113 if( cgs.gametype == GT_SINGLE_PLAYER ) {
114 trap->S_RegisterSound( va( "sound/player/announce/%s.wav", personality ));
115 }
116 */
117
118 CG_LoadingString( personality );
119 }
120
121
122 /*
123 ====================
124 CG_DrawInformation
125
126 Draw all the status / pacifier stuff during level loading
127 ====================
128 overlays UI_DrawConnectScreen
129 */
130 #define UI_INFOFONT (UI_BIGFONT)
CG_DrawInformation(void)131 void CG_DrawInformation( void ) {
132 const char *s;
133 const char *info;
134 const char *sysInfo;
135 int y;
136 int value, valueNOFP;
137 qhandle_t levelshot;
138 char buf[1024];
139 int iPropHeight = 18; // I know, this is total crap, but as a post release asian-hack.... -Ste
140
141 info = CG_ConfigString( CS_SERVERINFO );
142 sysInfo = CG_ConfigString( CS_SYSTEMINFO );
143
144 s = Info_ValueForKey( info, "mapname" );
145 levelshot = trap->R_RegisterShaderNoMip( va( "levelshots/%s", s ) );
146 if ( !levelshot ) {
147 levelshot = trap->R_RegisterShaderNoMip( "menu/art/unknownmap_mp" );
148 }
149 trap->R_SetColor( NULL );
150 CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, levelshot );
151
152 CG_LoadBar();
153
154 // draw the icons of things as they are loaded
155 // CG_DrawLoadingIcons();
156
157 // the first 150 rows are reserved for the client connection
158 // screen to write into
159 if ( cg.infoScreenText[0] ) {
160 const char *psLoading = CG_GetStringEdString("MENUS", "LOADING_MAPNAME");
161 CG_DrawProportionalString( 320, 128-32, va(/*"Loading... %s"*/ psLoading, cg.infoScreenText), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
162 } else {
163 const char *psAwaitingSnapshot = CG_GetStringEdString("MENUS", "AWAITING_SNAPSHOT");
164 CG_DrawProportionalString( 320, 128-32, /*"Awaiting snapshot..."*/psAwaitingSnapshot, UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
165 }
166
167 // draw info string information
168
169 y = 180-32;
170
171 // don't print server lines if playing a local game
172 trap->Cvar_VariableStringBuffer( "sv_running", buf, sizeof( buf ) );
173 if ( !atoi( buf ) ) {
174 // server hostname
175 Q_strncpyz(buf, Info_ValueForKey( info, "sv_hostname" ), sizeof( buf ) );
176 Q_CleanStr(buf);
177 CG_DrawProportionalString( 320, y, buf, UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
178 y += iPropHeight;
179
180 // pure server
181 s = Info_ValueForKey( sysInfo, "sv_pure" );
182 if ( s[0] == '1' ) {
183 const char *psPure = CG_GetStringEdString("MP_INGAME", "PURE_SERVER");
184 CG_DrawProportionalString( 320, y, psPure, UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
185 y += iPropHeight;
186 }
187
188 // server-specific message of the day
189 s = CG_ConfigString( CS_MOTD );
190 if ( s[0] ) {
191 CG_DrawProportionalString( 320, y, s, UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
192 y += iPropHeight;
193 }
194
195 { // display global MOTD at bottom (mirrors ui_main UI_DrawConnectScreen
196 char motdString[1024];
197 trap->Cvar_VariableStringBuffer( "cl_motdString", motdString, sizeof( motdString ) );
198
199 if (motdString[0])
200 {
201 CG_DrawProportionalString( 320, 425, motdString, UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
202 }
203 }
204
205 // some extra space after hostname and motd
206 y += 10;
207 }
208
209 // map-specific message (long map name)
210 s = CG_ConfigString( CS_MESSAGE );
211 if ( s[0] ) {
212 CG_DrawProportionalString( 320, y, s, UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
213 y += iPropHeight;
214 }
215
216 // cheats warning
217 s = Info_ValueForKey( sysInfo, "sv_cheats" );
218 if ( s[0] == '1' ) {
219 CG_DrawProportionalString( 320, y, CG_GetStringEdString("MP_INGAME", "CHEATSAREENABLED"), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
220 y += iPropHeight;
221 }
222
223 // game type
224 s = BG_GetGametypeString( cgs.gametype );
225 CG_DrawProportionalString( 320, y, s, UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
226 y += iPropHeight;
227
228 if (cgs.gametype != GT_SIEGE)
229 {
230 value = atoi( Info_ValueForKey( info, "timelimit" ) );
231 if ( value ) {
232 CG_DrawProportionalString( 320, y, va( "%s %i", CG_GetStringEdString("MP_INGAME", "TIMELIMIT"), value ), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
233 y += iPropHeight;
234 }
235
236 if (cgs.gametype < GT_CTF ) {
237 value = atoi( Info_ValueForKey( info, "fraglimit" ) );
238 if ( value ) {
239 CG_DrawProportionalString( 320, y, va( "%s %i", CG_GetStringEdString("MP_INGAME", "FRAGLIMIT"), value ), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
240 y += iPropHeight;
241 }
242
243 if (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL)
244 {
245 value = atoi( Info_ValueForKey( info, "duel_fraglimit" ) );
246 if ( value ) {
247 CG_DrawProportionalString( 320, y, va( "%s %i", CG_GetStringEdString("MP_INGAME", "WINLIMIT"), value ), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
248 y += iPropHeight;
249 }
250 }
251 }
252 }
253
254 if (cgs.gametype >= GT_CTF) {
255 value = atoi( Info_ValueForKey( info, "capturelimit" ) );
256 if ( value ) {
257 CG_DrawProportionalString( 320, y, va( "%s %i", CG_GetStringEdString("MP_INGAME", "CAPTURELIMIT"), value ), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
258 y += iPropHeight;
259 }
260 }
261
262 if (cgs.gametype >= GT_TEAM)
263 {
264 value = atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) );
265 if ( value ) {
266 CG_DrawProportionalString( 320, y, CG_GetStringEdString("MP_INGAME", "FORCEBASEDTEAMS"), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
267 y += iPropHeight;
268 }
269 }
270
271 if (cgs.gametype != GT_SIEGE)
272 {
273 valueNOFP = atoi( Info_ValueForKey( info, "g_forcePowerDisable" ) );
274
275 value = atoi( Info_ValueForKey( info, "g_maxForceRank" ) );
276 if ( value && !valueNOFP && (value < NUM_FORCE_MASTERY_LEVELS) ) {
277 char fmStr[1024];
278
279 trap->SE_GetStringTextString("MP_INGAME_MAXFORCERANK",fmStr, sizeof(fmStr));
280
281 CG_DrawProportionalString( 320, y, va( "%s %s", fmStr, CG_GetStringEdString("MP_INGAME", forceMasteryLevels[value]) ), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
282 y += iPropHeight;
283 }
284 else if (!valueNOFP)
285 {
286 char fmStr[1024];
287 trap->SE_GetStringTextString("MP_INGAME_MAXFORCERANK",fmStr, sizeof(fmStr));
288
289 CG_DrawProportionalString( 320, y, va( "%s %s", fmStr, (char *)CG_GetStringEdString("MP_INGAME", forceMasteryLevels[7]) ), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
290 y += iPropHeight;
291 }
292
293 if (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL)
294 {
295 value = atoi( Info_ValueForKey( info, "g_duelWeaponDisable" ) );
296 }
297 else
298 {
299 value = atoi( Info_ValueForKey( info, "g_weaponDisable" ) );
300 }
301 if ( cgs.gametype != GT_JEDIMASTER && value ) {
302 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "SABERONLYSET") ), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
303 y += iPropHeight;
304 }
305
306 if ( valueNOFP ) {
307 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "NOFPSET") ), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
308 y += iPropHeight;
309 }
310 }
311
312 // Display the rules based on type
313 y += iPropHeight;
314 switch ( cgs.gametype ) {
315 case GT_FFA:
316 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_FFA_1")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
317 y += iPropHeight;
318 break;
319 case GT_HOLOCRON:
320 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_HOLO_1")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
321 y += iPropHeight;
322 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_HOLO_2")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
323 y += iPropHeight;
324 break;
325 case GT_JEDIMASTER:
326 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_JEDI_1")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
327 y += iPropHeight;
328 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_JEDI_2")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
329 y += iPropHeight;
330 break;
331 case GT_SINGLE_PLAYER:
332 break;
333 case GT_DUEL:
334 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_DUEL_1")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
335 y += iPropHeight;
336 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_DUEL_2")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
337 y += iPropHeight;
338 break;
339 case GT_POWERDUEL:
340 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_POWERDUEL_1")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
341 y += iPropHeight;
342 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_POWERDUEL_2")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
343 y += iPropHeight;
344 break;
345 case GT_TEAM:
346 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_TEAM_1")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
347 y += iPropHeight;
348 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_TEAM_2")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
349 y += iPropHeight;
350 break;
351 case GT_SIEGE:
352 break;
353 case GT_CTF:
354 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_CTF_1")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
355 y += iPropHeight;
356 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_CTF_2")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
357 y += iPropHeight;
358 break;
359 case GT_CTY:
360 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_CTY_1")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
361 y += iPropHeight;
362 CG_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_CTY_2")), UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
363 y += iPropHeight;
364 break;
365 default:
366 break;
367 }
368 }
369
370 /*
371 ===================
372 CG_LoadBar
373 ===================
374 */
CG_LoadBar(void)375 void CG_LoadBar(void)
376 {
377 const int numticks = 9, tickwidth = 40, tickheight = 8;
378 const int tickpadx = 20, tickpady = 12;
379 const int capwidth = 8;
380 const int barwidth = numticks*tickwidth+tickpadx*2+capwidth*2, barleft = ((640-barwidth)/2);
381 const int barheight = tickheight + tickpady*2, bartop = 480-barheight;
382 const int capleft = barleft+tickpadx, tickleft = capleft+capwidth, ticktop = bartop+tickpady;
383
384 trap->R_SetColor( colorWhite );
385 // Draw background
386 CG_DrawPic(barleft, bartop, barwidth, barheight, cgs.media.loadBarLEDSurround);
387
388 // Draw left cap (backwards)
389 CG_DrawPic(tickleft, ticktop, -capwidth, tickheight, cgs.media.loadBarLEDCap);
390
391 // Draw bar
392 CG_DrawPic(tickleft, ticktop, tickwidth*cg.loadLCARSStage, tickheight, cgs.media.loadBarLED);
393
394 // Draw right cap
395 CG_DrawPic(tickleft+tickwidth*cg.loadLCARSStage, ticktop, capwidth, tickheight, cgs.media.loadBarLEDCap);
396 }
397
398