1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4
5 This file is part of Quake III Arena source code.
6
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 ===========================================================================
21 */
22 //
23 // cg_main.c -- initialization and primary entry point for cgame
24 #include "cg_local.h"
25
26 #ifdef MISSIONPACK
27 #include "../ui/ui_shared.h"
28 // display context for new ui stuff
29 displayContextDef_t cgDC;
30 #endif
31
32 int forceModelModificationCount = -1;
33
34 void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum );
35 void CG_Shutdown( void );
36
37
38 /*
39 ================
40 vmMain
41
42 This is the only way control passes into the module.
43 This must be the very first function compiled into the .q3vm file
44 ================
45 */
vmMain(int command,int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11)46 intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) {
47
48 switch ( command ) {
49 case CG_INIT:
50 CG_Init( arg0, arg1, arg2 );
51 return 0;
52 case CG_SHUTDOWN:
53 CG_Shutdown();
54 return 0;
55 case CG_CONSOLE_COMMAND:
56 return CG_ConsoleCommand();
57 case CG_DRAW_ACTIVE_FRAME:
58 CG_DrawActiveFrame( arg0, arg1, arg2 );
59 return 0;
60 case CG_CROSSHAIR_PLAYER:
61 return CG_CrosshairPlayer();
62 case CG_LAST_ATTACKER:
63 return CG_LastAttacker();
64 case CG_KEY_EVENT:
65 CG_KeyEvent(arg0, arg1);
66 return 0;
67 case CG_MOUSE_EVENT:
68 #ifdef MISSIONPACK
69 cgDC.cursorx = cgs.cursorX;
70 cgDC.cursory = cgs.cursorY;
71 #endif
72 CG_MouseEvent(arg0, arg1);
73 return 0;
74 case CG_EVENT_HANDLING:
75 CG_EventHandling(arg0);
76 return 0;
77 default:
78 CG_Error( "vmMain: unknown command %i", command );
79 break;
80 }
81 return -1;
82 }
83
84
85 cg_t cg;
86 cgs_t cgs;
87 centity_t cg_entities[MAX_GENTITIES];
88 weaponInfo_t cg_weapons[MAX_WEAPONS];
89 itemInfo_t cg_items[MAX_ITEMS];
90
91
92 vmCvar_t cg_railTrailTime;
93 vmCvar_t cg_centertime;
94 vmCvar_t cg_runpitch;
95 vmCvar_t cg_runroll;
96 vmCvar_t cg_bobup;
97 vmCvar_t cg_bobpitch;
98 vmCvar_t cg_bobroll;
99 vmCvar_t cg_swingSpeed;
100 vmCvar_t cg_shadows;
101 vmCvar_t cg_gibs;
102 vmCvar_t cg_drawTimer;
103 vmCvar_t cg_drawFPS;
104 vmCvar_t cg_drawSnapshot;
105 vmCvar_t cg_draw3dIcons;
106 vmCvar_t cg_drawIcons;
107 vmCvar_t cg_drawAmmoWarning;
108 vmCvar_t cg_drawCrosshair;
109 vmCvar_t cg_drawCrosshairNames;
110 vmCvar_t cg_drawRewards;
111 vmCvar_t cg_crosshairSize;
112 vmCvar_t cg_crosshairX;
113 vmCvar_t cg_crosshairY;
114 vmCvar_t cg_crosshairHealth;
115 vmCvar_t cg_draw2D;
116 vmCvar_t cg_drawStatus;
117 vmCvar_t cg_animSpeed;
118 vmCvar_t cg_debugAnim;
119 vmCvar_t cg_debugPosition;
120 vmCvar_t cg_debugEvents;
121 vmCvar_t cg_errorDecay;
122 vmCvar_t cg_nopredict;
123 vmCvar_t cg_noPlayerAnims;
124 vmCvar_t cg_showmiss;
125 vmCvar_t cg_footsteps;
126 vmCvar_t cg_addMarks;
127 vmCvar_t cg_brassTime;
128 vmCvar_t cg_viewsize;
129 vmCvar_t cg_drawGun;
130 vmCvar_t cg_gun_frame;
131 vmCvar_t cg_gun_x;
132 vmCvar_t cg_gun_y;
133 vmCvar_t cg_gun_z;
134 vmCvar_t cg_tracerChance;
135 vmCvar_t cg_tracerWidth;
136 vmCvar_t cg_tracerLength;
137 vmCvar_t cg_autoswitch;
138 vmCvar_t cg_ignore;
139 vmCvar_t cg_simpleItems;
140 vmCvar_t cg_fov;
141 vmCvar_t cg_zoomFov;
142 vmCvar_t cg_thirdPerson;
143 vmCvar_t cg_thirdPersonRange;
144 vmCvar_t cg_thirdPersonAngle;
145 vmCvar_t cg_lagometer;
146 vmCvar_t cg_drawAttacker;
147 vmCvar_t cg_synchronousClients;
148 vmCvar_t cg_teamChatTime;
149 vmCvar_t cg_teamChatHeight;
150 vmCvar_t cg_stats;
151 vmCvar_t cg_buildScript;
152 vmCvar_t cg_forceModel;
153 vmCvar_t cg_paused;
154 vmCvar_t cg_blood;
155 vmCvar_t cg_predictItems;
156 vmCvar_t cg_deferPlayers;
157 vmCvar_t cg_drawTeamOverlay;
158 vmCvar_t cg_teamOverlayUserinfo;
159 vmCvar_t cg_drawFriend;
160 vmCvar_t cg_teamChatsOnly;
161 vmCvar_t cg_noVoiceChats;
162 vmCvar_t cg_noVoiceText;
163 vmCvar_t cg_hudFiles;
164 vmCvar_t cg_scorePlum;
165 vmCvar_t cg_smoothClients;
166 vmCvar_t pmove_fixed;
167 //vmCvar_t cg_pmove_fixed;
168 vmCvar_t pmove_msec;
169 vmCvar_t cg_pmove_msec;
170 vmCvar_t cg_cameraMode;
171 vmCvar_t cg_cameraOrbit;
172 vmCvar_t cg_cameraOrbitDelay;
173 vmCvar_t cg_timescaleFadeEnd;
174 vmCvar_t cg_timescaleFadeSpeed;
175 vmCvar_t cg_timescale;
176 vmCvar_t cg_smallFont;
177 vmCvar_t cg_bigFont;
178 vmCvar_t cg_noTaunt;
179 vmCvar_t cg_noProjectileTrail;
180 vmCvar_t cg_oldRail;
181 vmCvar_t cg_oldRocket;
182 vmCvar_t cg_oldPlasma;
183 vmCvar_t cg_trueLightning;
184
185 #ifdef MISSIONPACK
186 vmCvar_t cg_redTeamName;
187 vmCvar_t cg_blueTeamName;
188 vmCvar_t cg_currentSelectedPlayer;
189 vmCvar_t cg_currentSelectedPlayerName;
190 vmCvar_t cg_singlePlayer;
191 vmCvar_t cg_enableDust;
192 vmCvar_t cg_enableBreath;
193 vmCvar_t cg_singlePlayerActive;
194 vmCvar_t cg_recordSPDemo;
195 vmCvar_t cg_recordSPDemoName;
196 vmCvar_t cg_obeliskRespawnDelay;
197 #endif
198
199 typedef struct {
200 vmCvar_t *vmCvar;
201 char *cvarName;
202 char *defaultString;
203 int cvarFlags;
204 } cvarTable_t;
205
206 static cvarTable_t cvarTable[] = {
207 { &cg_ignore, "cg_ignore", "0", 0 }, // used for debugging
208 { &cg_autoswitch, "cg_autoswitch", "1", CVAR_ARCHIVE },
209 { &cg_drawGun, "cg_drawGun", "1", CVAR_ARCHIVE },
210 { &cg_zoomFov, "cg_zoomfov", "22.5", CVAR_ARCHIVE },
211 { &cg_fov, "cg_fov", "90", CVAR_ARCHIVE },
212 { &cg_viewsize, "cg_viewsize", "100", CVAR_ARCHIVE },
213 { &cg_shadows, "cg_shadows", "1", CVAR_ARCHIVE },
214 { &cg_gibs, "cg_gibs", "1", CVAR_ARCHIVE },
215 { &cg_draw2D, "cg_draw2D", "1", CVAR_ARCHIVE },
216 { &cg_drawStatus, "cg_drawStatus", "1", CVAR_ARCHIVE },
217 { &cg_drawTimer, "cg_drawTimer", "0", CVAR_ARCHIVE },
218 { &cg_drawFPS, "cg_drawFPS", "0", CVAR_ARCHIVE },
219 { &cg_drawSnapshot, "cg_drawSnapshot", "0", CVAR_ARCHIVE },
220 { &cg_draw3dIcons, "cg_draw3dIcons", "1", CVAR_ARCHIVE },
221 { &cg_drawIcons, "cg_drawIcons", "1", CVAR_ARCHIVE },
222 { &cg_drawAmmoWarning, "cg_drawAmmoWarning", "1", CVAR_ARCHIVE },
223 { &cg_drawAttacker, "cg_drawAttacker", "1", CVAR_ARCHIVE },
224 { &cg_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE },
225 { &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE },
226 { &cg_drawRewards, "cg_drawRewards", "1", CVAR_ARCHIVE },
227 { &cg_crosshairSize, "cg_crosshairSize", "24", CVAR_ARCHIVE },
228 { &cg_crosshairHealth, "cg_crosshairHealth", "1", CVAR_ARCHIVE },
229 { &cg_crosshairX, "cg_crosshairX", "0", CVAR_ARCHIVE },
230 { &cg_crosshairY, "cg_crosshairY", "0", CVAR_ARCHIVE },
231 { &cg_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE },
232 { &cg_simpleItems, "cg_simpleItems", "0", CVAR_ARCHIVE },
233 { &cg_addMarks, "cg_marks", "1", CVAR_ARCHIVE },
234 { &cg_lagometer, "cg_lagometer", "1", CVAR_ARCHIVE },
235 { &cg_railTrailTime, "cg_railTrailTime", "400", CVAR_ARCHIVE },
236 { &cg_gun_x, "cg_gunX", "0", CVAR_CHEAT },
237 { &cg_gun_y, "cg_gunY", "0", CVAR_CHEAT },
238 { &cg_gun_z, "cg_gunZ", "0", CVAR_CHEAT },
239 { &cg_centertime, "cg_centertime", "3", CVAR_CHEAT },
240 { &cg_runpitch, "cg_runpitch", "0.002", CVAR_ARCHIVE},
241 { &cg_runroll, "cg_runroll", "0.005", CVAR_ARCHIVE },
242 { &cg_bobup , "cg_bobup", "0.005", CVAR_CHEAT },
243 { &cg_bobpitch, "cg_bobpitch", "0.002", CVAR_ARCHIVE },
244 { &cg_bobroll, "cg_bobroll", "0.002", CVAR_ARCHIVE },
245 { &cg_swingSpeed, "cg_swingSpeed", "0.3", CVAR_CHEAT },
246 { &cg_animSpeed, "cg_animspeed", "1", CVAR_CHEAT },
247 { &cg_debugAnim, "cg_debuganim", "0", CVAR_CHEAT },
248 { &cg_debugPosition, "cg_debugposition", "0", CVAR_CHEAT },
249 { &cg_debugEvents, "cg_debugevents", "0", CVAR_CHEAT },
250 { &cg_errorDecay, "cg_errordecay", "100", 0 },
251 { &cg_nopredict, "cg_nopredict", "0", 0 },
252 { &cg_noPlayerAnims, "cg_noplayeranims", "0", CVAR_CHEAT },
253 { &cg_showmiss, "cg_showmiss", "0", 0 },
254 { &cg_footsteps, "cg_footsteps", "1", CVAR_CHEAT },
255 { &cg_tracerChance, "cg_tracerchance", "0.4", CVAR_CHEAT },
256 { &cg_tracerWidth, "cg_tracerwidth", "1", CVAR_CHEAT },
257 { &cg_tracerLength, "cg_tracerlength", "100", CVAR_CHEAT },
258 { &cg_thirdPersonRange, "cg_thirdPersonRange", "40", CVAR_CHEAT },
259 { &cg_thirdPersonAngle, "cg_thirdPersonAngle", "0", CVAR_CHEAT },
260 { &cg_thirdPerson, "cg_thirdPerson", "0", 0 },
261 { &cg_teamChatTime, "cg_teamChatTime", "3000", CVAR_ARCHIVE },
262 { &cg_teamChatHeight, "cg_teamChatHeight", "0", CVAR_ARCHIVE },
263 { &cg_forceModel, "cg_forceModel", "0", CVAR_ARCHIVE },
264 { &cg_predictItems, "cg_predictItems", "1", CVAR_ARCHIVE },
265 #ifdef MISSIONPACK
266 { &cg_deferPlayers, "cg_deferPlayers", "0", CVAR_ARCHIVE },
267 #else
268 { &cg_deferPlayers, "cg_deferPlayers", "1", CVAR_ARCHIVE },
269 #endif
270 { &cg_drawTeamOverlay, "cg_drawTeamOverlay", "0", CVAR_ARCHIVE },
271 { &cg_teamOverlayUserinfo, "teamoverlay", "0", CVAR_ROM | CVAR_USERINFO },
272 { &cg_stats, "cg_stats", "0", 0 },
273 { &cg_drawFriend, "cg_drawFriend", "1", CVAR_ARCHIVE },
274 { &cg_teamChatsOnly, "cg_teamChatsOnly", "0", CVAR_ARCHIVE },
275 { &cg_noVoiceChats, "cg_noVoiceChats", "0", CVAR_ARCHIVE },
276 { &cg_noVoiceText, "cg_noVoiceText", "0", CVAR_ARCHIVE },
277 // the following variables are created in other parts of the system,
278 // but we also reference them here
279 { &cg_buildScript, "com_buildScript", "0", 0 }, // force loading of all possible data amd error on failures
280 { &cg_paused, "cl_paused", "0", CVAR_ROM },
281 { &cg_blood, "com_blood", "1", CVAR_ARCHIVE },
282 { &cg_synchronousClients, "g_synchronousClients", "0", 0 }, // communicated by systeminfo
283 #ifdef MISSIONPACK
284 { &cg_redTeamName, "g_redteam", DEFAULT_REDTEAM_NAME, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_USERINFO },
285 { &cg_blueTeamName, "g_blueteam", DEFAULT_BLUETEAM_NAME, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_USERINFO },
286 { &cg_currentSelectedPlayer, "cg_currentSelectedPlayer", "0", CVAR_ARCHIVE},
287 { &cg_currentSelectedPlayerName, "cg_currentSelectedPlayerName", "", CVAR_ARCHIVE},
288 { &cg_singlePlayer, "ui_singlePlayerActive", "0", CVAR_USERINFO},
289 { &cg_enableDust, "g_enableDust", "0", CVAR_SERVERINFO},
290 { &cg_enableBreath, "g_enableBreath", "0", CVAR_SERVERINFO},
291 { &cg_singlePlayerActive, "ui_singlePlayerActive", "0", CVAR_USERINFO},
292 { &cg_recordSPDemo, "ui_recordSPDemo", "0", CVAR_ARCHIVE},
293 { &cg_recordSPDemoName, "ui_recordSPDemoName", "", CVAR_ARCHIVE},
294 { &cg_obeliskRespawnDelay, "g_obeliskRespawnDelay", "10", CVAR_SERVERINFO},
295 { &cg_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE},
296 #endif
297 { &cg_cameraOrbit, "cg_cameraOrbit", "0", CVAR_CHEAT},
298 { &cg_cameraOrbitDelay, "cg_cameraOrbitDelay", "50", CVAR_ARCHIVE},
299 { &cg_timescaleFadeEnd, "cg_timescaleFadeEnd", "1", 0},
300 { &cg_timescaleFadeSpeed, "cg_timescaleFadeSpeed", "0", 0},
301 { &cg_timescale, "timescale", "1", 0},
302 { &cg_scorePlum, "cg_scorePlums", "1", CVAR_USERINFO | CVAR_ARCHIVE},
303 { &cg_smoothClients, "cg_smoothClients", "0", CVAR_USERINFO | CVAR_ARCHIVE},
304 { &cg_cameraMode, "com_cameraMode", "0", CVAR_CHEAT},
305
306 { &pmove_fixed, "pmove_fixed", "0", 0},
307 { &pmove_msec, "pmove_msec", "8", 0},
308 { &cg_noTaunt, "cg_noTaunt", "0", CVAR_ARCHIVE},
309 { &cg_noProjectileTrail, "cg_noProjectileTrail", "0", CVAR_ARCHIVE},
310 { &cg_smallFont, "ui_smallFont", "0.25", CVAR_ARCHIVE},
311 { &cg_bigFont, "ui_bigFont", "0.4", CVAR_ARCHIVE},
312 { &cg_oldRail, "cg_oldRail", "1", CVAR_ARCHIVE},
313 { &cg_oldRocket, "cg_oldRocket", "1", CVAR_ARCHIVE},
314 { &cg_oldPlasma, "cg_oldPlasma", "1", CVAR_ARCHIVE},
315 { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE}
316 // { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE }
317 };
318
319 static int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] );
320
321 /*
322 =================
323 CG_RegisterCvars
324 =================
325 */
CG_RegisterCvars(void)326 void CG_RegisterCvars( void ) {
327 int i;
328 cvarTable_t *cv;
329 char var[MAX_TOKEN_CHARS];
330
331 for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
332 trap_Cvar_Register( cv->vmCvar, cv->cvarName,
333 cv->defaultString, cv->cvarFlags );
334 }
335
336 // see if we are also running the server on this machine
337 trap_Cvar_VariableStringBuffer( "sv_running", var, sizeof( var ) );
338 cgs.localServer = atoi( var );
339
340 forceModelModificationCount = cg_forceModel.modificationCount;
341
342 trap_Cvar_Register(NULL, "model", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
343 trap_Cvar_Register(NULL, "headmodel", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
344 trap_Cvar_Register(NULL, "team_model", DEFAULT_TEAM_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
345 trap_Cvar_Register(NULL, "team_headmodel", DEFAULT_TEAM_HEAD, CVAR_USERINFO | CVAR_ARCHIVE );
346 }
347
348 /*
349 ===================
350 CG_ForceModelChange
351 ===================
352 */
CG_ForceModelChange(void)353 static void CG_ForceModelChange( void ) {
354 int i;
355
356 for (i=0 ; i<MAX_CLIENTS ; i++) {
357 const char *clientInfo;
358
359 clientInfo = CG_ConfigString( CS_PLAYERS+i );
360 if ( !clientInfo[0] ) {
361 continue;
362 }
363 CG_NewClientInfo( i );
364 }
365 }
366
367 /*
368 =================
369 CG_UpdateCvars
370 =================
371 */
CG_UpdateCvars(void)372 void CG_UpdateCvars( void ) {
373 int i;
374 cvarTable_t *cv;
375
376 for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
377 trap_Cvar_Update( cv->vmCvar );
378 }
379
380 // check for modications here
381
382 // If team overlay is on, ask for updates from the server. If its off,
383 // let the server know so we don't receive it
384 if ( drawTeamOverlayModificationCount != cg_drawTeamOverlay.modificationCount ) {
385 drawTeamOverlayModificationCount = cg_drawTeamOverlay.modificationCount;
386
387 if ( cg_drawTeamOverlay.integer > 0 ) {
388 trap_Cvar_Set( "teamoverlay", "1" );
389 } else {
390 trap_Cvar_Set( "teamoverlay", "0" );
391 }
392 }
393
394 // if force model changed
395 if ( forceModelModificationCount != cg_forceModel.modificationCount ) {
396 forceModelModificationCount = cg_forceModel.modificationCount;
397 CG_ForceModelChange();
398 }
399 }
400
CG_CrosshairPlayer(void)401 int CG_CrosshairPlayer( void ) {
402 if ( cg.time > ( cg.crosshairClientTime + 1000 ) ) {
403 return -1;
404 }
405 return cg.crosshairClientNum;
406 }
407
CG_LastAttacker(void)408 int CG_LastAttacker( void ) {
409 if ( !cg.attackerTime ) {
410 return -1;
411 }
412 return cg.snap->ps.persistant[PERS_ATTACKER];
413 }
414
CG_Printf(const char * msg,...)415 void QDECL CG_Printf( const char *msg, ... ) {
416 va_list argptr;
417 char text[1024];
418
419 va_start (argptr, msg);
420 Q_vsnprintf (text, sizeof(text), msg, argptr);
421 va_end (argptr);
422
423 trap_Print( text );
424 }
425
CG_Error(const char * msg,...)426 void QDECL CG_Error( const char *msg, ... ) {
427 va_list argptr;
428 char text[1024];
429
430 va_start (argptr, msg);
431 Q_vsnprintf (text, sizeof(text), msg, argptr);
432 va_end (argptr);
433
434 trap_Error( text );
435 }
436
Com_Error(int level,const char * error,...)437 void QDECL Com_Error( int level, const char *error, ... ) {
438 va_list argptr;
439 char text[1024];
440
441 va_start (argptr, error);
442 Q_vsnprintf (text, sizeof(text), error, argptr);
443 va_end (argptr);
444
445 CG_Error( "%s", text);
446 }
447
Com_Printf(const char * msg,...)448 void QDECL Com_Printf( const char *msg, ... ) {
449 va_list argptr;
450 char text[1024];
451
452 va_start (argptr, msg);
453 Q_vsnprintf (text, sizeof(text), msg, argptr);
454 va_end (argptr);
455
456 CG_Printf ("%s", text);
457 }
458
459 /*
460 ================
461 CG_Argv
462 ================
463 */
CG_Argv(int arg)464 const char *CG_Argv( int arg ) {
465 static char buffer[MAX_STRING_CHARS];
466
467 trap_Argv( arg, buffer, sizeof( buffer ) );
468
469 return buffer;
470 }
471
472
473 //========================================================================
474
475 /*
476 =================
477 CG_RegisterItemSounds
478
479 The server says this item is used on this level
480 =================
481 */
CG_RegisterItemSounds(int itemNum)482 static void CG_RegisterItemSounds( int itemNum ) {
483 gitem_t *item;
484 char data[MAX_QPATH];
485 char *s, *start;
486 int len;
487
488 item = &bg_itemlist[ itemNum ];
489
490 if( item->pickup_sound ) {
491 trap_S_RegisterSound( item->pickup_sound, qfalse );
492 }
493
494 // parse the space seperated precache string for other media
495 s = item->sounds;
496 if (!s || !s[0])
497 return;
498
499 while (*s) {
500 start = s;
501 while (*s && *s != ' ') {
502 s++;
503 }
504
505 len = s-start;
506 if (len >= MAX_QPATH || len < 5) {
507 CG_Error( "PrecacheItem: %s has bad precache string",
508 item->classname);
509 return;
510 }
511 memcpy (data, start, len);
512 data[len] = 0;
513 if ( *s ) {
514 s++;
515 }
516
517 if ( !strcmp(data+len-3, "wav" )) {
518 trap_S_RegisterSound( data, qfalse );
519 }
520 }
521 }
522
523
524 /*
525 =================
526 CG_RegisterSounds
527
528 called during a precache command
529 =================
530 */
CG_RegisterSounds(void)531 static void CG_RegisterSounds( void ) {
532 int i;
533 char items[MAX_ITEMS+1];
534 char name[MAX_QPATH];
535 const char *soundName;
536
537 // voice commands
538 #ifdef MISSIONPACK
539 CG_LoadVoiceChats();
540 #endif
541
542 cgs.media.oneMinuteSound = trap_S_RegisterSound( "sound/feedback/1_minute.wav", qtrue );
543 cgs.media.fiveMinuteSound = trap_S_RegisterSound( "sound/feedback/5_minute.wav", qtrue );
544 cgs.media.suddenDeathSound = trap_S_RegisterSound( "sound/feedback/sudden_death.wav", qtrue );
545 cgs.media.oneFragSound = trap_S_RegisterSound( "sound/feedback/1_frag.wav", qtrue );
546 cgs.media.twoFragSound = trap_S_RegisterSound( "sound/feedback/2_frags.wav", qtrue );
547 cgs.media.threeFragSound = trap_S_RegisterSound( "sound/feedback/3_frags.wav", qtrue );
548 cgs.media.count3Sound = trap_S_RegisterSound( "sound/feedback/three.wav", qtrue );
549 cgs.media.count2Sound = trap_S_RegisterSound( "sound/feedback/two.wav", qtrue );
550 cgs.media.count1Sound = trap_S_RegisterSound( "sound/feedback/one.wav", qtrue );
551 cgs.media.countFightSound = trap_S_RegisterSound( "sound/feedback/fight.wav", qtrue );
552 cgs.media.countPrepareSound = trap_S_RegisterSound( "sound/feedback/prepare.wav", qtrue );
553 #ifdef MISSIONPACK
554 cgs.media.countPrepareTeamSound = trap_S_RegisterSound( "sound/feedback/prepare_team.wav", qtrue );
555 #endif
556
557 if ( cgs.gametype >= GT_TEAM || cg_buildScript.integer ) {
558
559 cgs.media.captureAwardSound = trap_S_RegisterSound( "sound/teamplay/flagcapture_yourteam.wav", qtrue );
560 cgs.media.redLeadsSound = trap_S_RegisterSound( "sound/feedback/redleads.wav", qtrue );
561 cgs.media.blueLeadsSound = trap_S_RegisterSound( "sound/feedback/blueleads.wav", qtrue );
562 cgs.media.teamsTiedSound = trap_S_RegisterSound( "sound/feedback/teamstied.wav", qtrue );
563 cgs.media.hitTeamSound = trap_S_RegisterSound( "sound/feedback/hit_teammate.wav", qtrue );
564
565 cgs.media.redScoredSound = trap_S_RegisterSound( "sound/teamplay/voc_red_scores.wav", qtrue );
566 cgs.media.blueScoredSound = trap_S_RegisterSound( "sound/teamplay/voc_blue_scores.wav", qtrue );
567
568 cgs.media.captureYourTeamSound = trap_S_RegisterSound( "sound/teamplay/flagcapture_yourteam.wav", qtrue );
569 cgs.media.captureOpponentSound = trap_S_RegisterSound( "sound/teamplay/flagcapture_opponent.wav", qtrue );
570
571 cgs.media.returnYourTeamSound = trap_S_RegisterSound( "sound/teamplay/flagreturn_yourteam.wav", qtrue );
572 cgs.media.returnOpponentSound = trap_S_RegisterSound( "sound/teamplay/flagreturn_opponent.wav", qtrue );
573
574 cgs.media.takenYourTeamSound = trap_S_RegisterSound( "sound/teamplay/flagtaken_yourteam.wav", qtrue );
575 cgs.media.takenOpponentSound = trap_S_RegisterSound( "sound/teamplay/flagtaken_opponent.wav", qtrue );
576
577 if ( cgs.gametype == GT_CTF || cg_buildScript.integer ) {
578 cgs.media.redFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/voc_red_returned.wav", qtrue );
579 cgs.media.blueFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/voc_blue_returned.wav", qtrue );
580 cgs.media.enemyTookYourFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_enemy_flag.wav", qtrue );
581 cgs.media.yourTeamTookEnemyFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_team_flag.wav", qtrue );
582 }
583
584 #ifdef MISSIONPACK
585 if ( cgs.gametype == GT_1FCTF || cg_buildScript.integer ) {
586 // FIXME: get a replacement for this sound ?
587 cgs.media.neutralFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/flagreturn_opponent.wav", qtrue );
588 cgs.media.yourTeamTookTheFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_team_1flag.wav", qtrue );
589 cgs.media.enemyTookTheFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_enemy_1flag.wav", qtrue );
590 }
591
592 if ( cgs.gametype == GT_1FCTF || cgs.gametype == GT_CTF || cg_buildScript.integer ) {
593 cgs.media.youHaveFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_you_flag.wav", qtrue );
594 cgs.media.holyShitSound = trap_S_RegisterSound("sound/feedback/voc_holyshit.wav", qtrue);
595 }
596
597 if ( cgs.gametype == GT_OBELISK || cg_buildScript.integer ) {
598 cgs.media.yourBaseIsUnderAttackSound = trap_S_RegisterSound( "sound/teamplay/voc_base_attack.wav", qtrue );
599 }
600 #else
601 cgs.media.youHaveFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_you_flag.wav", qtrue );
602 cgs.media.holyShitSound = trap_S_RegisterSound("sound/feedback/voc_holyshit.wav", qtrue);
603 cgs.media.neutralFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/flagreturn_opponent.wav", qtrue );
604 cgs.media.yourTeamTookTheFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_team_1flag.wav", qtrue );
605 cgs.media.enemyTookTheFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_enemy_1flag.wav", qtrue );
606 #endif
607 }
608
609 cgs.media.tracerSound = trap_S_RegisterSound( "sound/weapons/machinegun/buletby1.wav", qfalse );
610 cgs.media.selectSound = trap_S_RegisterSound( "sound/weapons/change.wav", qfalse );
611 cgs.media.wearOffSound = trap_S_RegisterSound( "sound/items/wearoff.wav", qfalse );
612 cgs.media.useNothingSound = trap_S_RegisterSound( "sound/items/use_nothing.wav", qfalse );
613 cgs.media.gibSound = trap_S_RegisterSound( "sound/player/gibsplt1.wav", qfalse );
614 cgs.media.gibBounce1Sound = trap_S_RegisterSound( "sound/player/gibimp1.wav", qfalse );
615 cgs.media.gibBounce2Sound = trap_S_RegisterSound( "sound/player/gibimp2.wav", qfalse );
616 cgs.media.gibBounce3Sound = trap_S_RegisterSound( "sound/player/gibimp3.wav", qfalse );
617
618 #ifdef MISSIONPACK
619 cgs.media.useInvulnerabilitySound = trap_S_RegisterSound( "sound/items/invul_activate.wav", qfalse );
620 cgs.media.invulnerabilityImpactSound1 = trap_S_RegisterSound( "sound/items/invul_impact_01.wav", qfalse );
621 cgs.media.invulnerabilityImpactSound2 = trap_S_RegisterSound( "sound/items/invul_impact_02.wav", qfalse );
622 cgs.media.invulnerabilityImpactSound3 = trap_S_RegisterSound( "sound/items/invul_impact_03.wav", qfalse );
623 cgs.media.invulnerabilityJuicedSound = trap_S_RegisterSound( "sound/items/invul_juiced.wav", qfalse );
624 cgs.media.obeliskHitSound1 = trap_S_RegisterSound( "sound/items/obelisk_hit_01.wav", qfalse );
625 cgs.media.obeliskHitSound2 = trap_S_RegisterSound( "sound/items/obelisk_hit_02.wav", qfalse );
626 cgs.media.obeliskHitSound3 = trap_S_RegisterSound( "sound/items/obelisk_hit_03.wav", qfalse );
627 cgs.media.obeliskRespawnSound = trap_S_RegisterSound( "sound/items/obelisk_respawn.wav", qfalse );
628
629 cgs.media.ammoregenSound = trap_S_RegisterSound("sound/items/cl_ammoregen.wav", qfalse);
630 cgs.media.doublerSound = trap_S_RegisterSound("sound/items/cl_doubler.wav", qfalse);
631 cgs.media.guardSound = trap_S_RegisterSound("sound/items/cl_guard.wav", qfalse);
632 cgs.media.scoutSound = trap_S_RegisterSound("sound/items/cl_scout.wav", qfalse);
633 #endif
634
635 cgs.media.teleInSound = trap_S_RegisterSound( "sound/world/telein.wav", qfalse );
636 cgs.media.teleOutSound = trap_S_RegisterSound( "sound/world/teleout.wav", qfalse );
637 cgs.media.respawnSound = trap_S_RegisterSound( "sound/items/respawn1.wav", qfalse );
638
639 cgs.media.noAmmoSound = trap_S_RegisterSound( "sound/weapons/noammo.wav", qfalse );
640
641 cgs.media.talkSound = trap_S_RegisterSound( "sound/player/talk.wav", qfalse );
642 cgs.media.landSound = trap_S_RegisterSound( "sound/player/land1.wav", qfalse);
643
644 cgs.media.hitSound = trap_S_RegisterSound( "sound/feedback/hit.wav", qfalse );
645 #ifdef MISSIONPACK
646 cgs.media.hitSoundHighArmor = trap_S_RegisterSound( "sound/feedback/hithi.wav", qfalse );
647 cgs.media.hitSoundLowArmor = trap_S_RegisterSound( "sound/feedback/hitlo.wav", qfalse );
648 #endif
649
650 cgs.media.impressiveSound = trap_S_RegisterSound( "sound/feedback/impressive.wav", qtrue );
651 cgs.media.excellentSound = trap_S_RegisterSound( "sound/feedback/excellent.wav", qtrue );
652 cgs.media.deniedSound = trap_S_RegisterSound( "sound/feedback/denied.wav", qtrue );
653 cgs.media.humiliationSound = trap_S_RegisterSound( "sound/feedback/humiliation.wav", qtrue );
654 cgs.media.assistSound = trap_S_RegisterSound( "sound/feedback/assist.wav", qtrue );
655 cgs.media.defendSound = trap_S_RegisterSound( "sound/feedback/defense.wav", qtrue );
656 #ifdef MISSIONPACK
657 cgs.media.firstImpressiveSound = trap_S_RegisterSound( "sound/feedback/first_impressive.wav", qtrue );
658 cgs.media.firstExcellentSound = trap_S_RegisterSound( "sound/feedback/first_excellent.wav", qtrue );
659 cgs.media.firstHumiliationSound = trap_S_RegisterSound( "sound/feedback/first_gauntlet.wav", qtrue );
660 #endif
661
662 cgs.media.takenLeadSound = trap_S_RegisterSound( "sound/feedback/takenlead.wav", qtrue);
663 cgs.media.tiedLeadSound = trap_S_RegisterSound( "sound/feedback/tiedlead.wav", qtrue);
664 cgs.media.lostLeadSound = trap_S_RegisterSound( "sound/feedback/lostlead.wav", qtrue);
665
666 #ifdef MISSIONPACK
667 cgs.media.voteNow = trap_S_RegisterSound( "sound/feedback/vote_now.wav", qtrue);
668 cgs.media.votePassed = trap_S_RegisterSound( "sound/feedback/vote_passed.wav", qtrue);
669 cgs.media.voteFailed = trap_S_RegisterSound( "sound/feedback/vote_failed.wav", qtrue);
670 #endif
671
672 cgs.media.watrInSound = trap_S_RegisterSound( "sound/player/watr_in.wav", qfalse);
673 cgs.media.watrOutSound = trap_S_RegisterSound( "sound/player/watr_out.wav", qfalse);
674 cgs.media.watrUnSound = trap_S_RegisterSound( "sound/player/watr_un.wav", qfalse);
675
676 cgs.media.jumpPadSound = trap_S_RegisterSound ("sound/world/jumppad.wav", qfalse );
677
678 for (i=0 ; i<4 ; i++) {
679 Com_sprintf (name, sizeof(name), "sound/player/footsteps/step%i.wav", i+1);
680 cgs.media.footsteps[FOOTSTEP_NORMAL][i] = trap_S_RegisterSound (name, qfalse);
681
682 Com_sprintf (name, sizeof(name), "sound/player/footsteps/boot%i.wav", i+1);
683 cgs.media.footsteps[FOOTSTEP_BOOT][i] = trap_S_RegisterSound (name, qfalse);
684
685 Com_sprintf (name, sizeof(name), "sound/player/footsteps/flesh%i.wav", i+1);
686 cgs.media.footsteps[FOOTSTEP_FLESH][i] = trap_S_RegisterSound (name, qfalse);
687
688 Com_sprintf (name, sizeof(name), "sound/player/footsteps/mech%i.wav", i+1);
689 cgs.media.footsteps[FOOTSTEP_MECH][i] = trap_S_RegisterSound (name, qfalse);
690
691 Com_sprintf (name, sizeof(name), "sound/player/footsteps/energy%i.wav", i+1);
692 cgs.media.footsteps[FOOTSTEP_ENERGY][i] = trap_S_RegisterSound (name, qfalse);
693
694 Com_sprintf (name, sizeof(name), "sound/player/footsteps/splash%i.wav", i+1);
695 cgs.media.footsteps[FOOTSTEP_SPLASH][i] = trap_S_RegisterSound (name, qfalse);
696
697 Com_sprintf (name, sizeof(name), "sound/player/footsteps/clank%i.wav", i+1);
698 cgs.media.footsteps[FOOTSTEP_METAL][i] = trap_S_RegisterSound (name, qfalse);
699 }
700
701 // only register the items that the server says we need
702 Q_strncpyz(items, CG_ConfigString(CS_ITEMS), sizeof(items));
703
704 for ( i = 1 ; i < bg_numItems ; i++ ) {
705 // if ( items[ i ] == '1' || cg_buildScript.integer ) {
706 CG_RegisterItemSounds( i );
707 // }
708 }
709
710 for ( i = 1 ; i < MAX_SOUNDS ; i++ ) {
711 soundName = CG_ConfigString( CS_SOUNDS+i );
712 if ( !soundName[0] ) {
713 break;
714 }
715 if ( soundName[0] == '*' ) {
716 continue; // custom sound
717 }
718 cgs.gameSounds[i] = trap_S_RegisterSound( soundName, qfalse );
719 }
720
721 // FIXME: only needed with item
722 cgs.media.flightSound = trap_S_RegisterSound( "sound/items/flight.wav", qfalse );
723 cgs.media.medkitSound = trap_S_RegisterSound ("sound/items/use_medkit.wav", qfalse);
724 cgs.media.quadSound = trap_S_RegisterSound("sound/items/damage3.wav", qfalse);
725 cgs.media.sfx_ric1 = trap_S_RegisterSound ("sound/weapons/machinegun/ric1.wav", qfalse);
726 cgs.media.sfx_ric2 = trap_S_RegisterSound ("sound/weapons/machinegun/ric2.wav", qfalse);
727 cgs.media.sfx_ric3 = trap_S_RegisterSound ("sound/weapons/machinegun/ric3.wav", qfalse);
728 cgs.media.sfx_railg = trap_S_RegisterSound ("sound/weapons/railgun/railgf1a.wav", qfalse);
729 cgs.media.sfx_rockexp = trap_S_RegisterSound ("sound/weapons/rocket/rocklx1a.wav", qfalse);
730 cgs.media.sfx_plasmaexp = trap_S_RegisterSound ("sound/weapons/plasma/plasmx1a.wav", qfalse);
731 #ifdef MISSIONPACK
732 cgs.media.sfx_proxexp = trap_S_RegisterSound( "sound/weapons/proxmine/wstbexpl.wav" , qfalse);
733 cgs.media.sfx_nghit = trap_S_RegisterSound( "sound/weapons/nailgun/wnalimpd.wav" , qfalse);
734 cgs.media.sfx_nghitflesh = trap_S_RegisterSound( "sound/weapons/nailgun/wnalimpl.wav" , qfalse);
735 cgs.media.sfx_nghitmetal = trap_S_RegisterSound( "sound/weapons/nailgun/wnalimpm.wav", qfalse );
736 cgs.media.sfx_chghit = trap_S_RegisterSound( "sound/weapons/vulcan/wvulimpd.wav", qfalse );
737 cgs.media.sfx_chghitflesh = trap_S_RegisterSound( "sound/weapons/vulcan/wvulimpl.wav", qfalse );
738 cgs.media.sfx_chghitmetal = trap_S_RegisterSound( "sound/weapons/vulcan/wvulimpm.wav", qfalse );
739 cgs.media.weaponHoverSound = trap_S_RegisterSound( "sound/weapons/weapon_hover.wav", qfalse );
740 cgs.media.kamikazeExplodeSound = trap_S_RegisterSound( "sound/items/kam_explode.wav", qfalse );
741 cgs.media.kamikazeImplodeSound = trap_S_RegisterSound( "sound/items/kam_implode.wav", qfalse );
742 cgs.media.kamikazeFarSound = trap_S_RegisterSound( "sound/items/kam_explode_far.wav", qfalse );
743 cgs.media.winnerSound = trap_S_RegisterSound( "sound/feedback/voc_youwin.wav", qfalse );
744 cgs.media.loserSound = trap_S_RegisterSound( "sound/feedback/voc_youlose.wav", qfalse );
745 cgs.media.youSuckSound = trap_S_RegisterSound( "sound/misc/yousuck.wav", qfalse );
746
747 cgs.media.wstbimplSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpl.wav", qfalse);
748 cgs.media.wstbimpmSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpm.wav", qfalse);
749 cgs.media.wstbimpdSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpd.wav", qfalse);
750 cgs.media.wstbactvSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbactv.wav", qfalse);
751 #endif
752
753 cgs.media.regenSound = trap_S_RegisterSound("sound/items/regen.wav", qfalse);
754 cgs.media.protectSound = trap_S_RegisterSound("sound/items/protect3.wav", qfalse);
755 cgs.media.n_healthSound = trap_S_RegisterSound("sound/items/n_health.wav", qfalse );
756 cgs.media.hgrenb1aSound = trap_S_RegisterSound("sound/weapons/grenade/hgrenb1a.wav", qfalse);
757 cgs.media.hgrenb2aSound = trap_S_RegisterSound("sound/weapons/grenade/hgrenb2a.wav", qfalse);
758
759 #ifdef MISSIONPACK
760 trap_S_RegisterSound("sound/player/james/death1.wav", qfalse );
761 trap_S_RegisterSound("sound/player/james/death2.wav", qfalse );
762 trap_S_RegisterSound("sound/player/james/death3.wav", qfalse );
763 trap_S_RegisterSound("sound/player/james/jump1.wav", qfalse );
764 trap_S_RegisterSound("sound/player/james/pain25_1.wav", qfalse );
765 trap_S_RegisterSound("sound/player/james/pain75_1.wav", qfalse );
766 trap_S_RegisterSound("sound/player/james/pain100_1.wav", qfalse );
767 trap_S_RegisterSound("sound/player/james/falling1.wav", qfalse );
768 trap_S_RegisterSound("sound/player/james/gasp.wav", qfalse );
769 trap_S_RegisterSound("sound/player/james/drown.wav", qfalse );
770 trap_S_RegisterSound("sound/player/james/fall1.wav", qfalse );
771 trap_S_RegisterSound("sound/player/james/taunt.wav", qfalse );
772
773 trap_S_RegisterSound("sound/player/janet/death1.wav", qfalse );
774 trap_S_RegisterSound("sound/player/janet/death2.wav", qfalse );
775 trap_S_RegisterSound("sound/player/janet/death3.wav", qfalse );
776 trap_S_RegisterSound("sound/player/janet/jump1.wav", qfalse );
777 trap_S_RegisterSound("sound/player/janet/pain25_1.wav", qfalse );
778 trap_S_RegisterSound("sound/player/janet/pain75_1.wav", qfalse );
779 trap_S_RegisterSound("sound/player/janet/pain100_1.wav", qfalse );
780 trap_S_RegisterSound("sound/player/janet/falling1.wav", qfalse );
781 trap_S_RegisterSound("sound/player/janet/gasp.wav", qfalse );
782 trap_S_RegisterSound("sound/player/janet/drown.wav", qfalse );
783 trap_S_RegisterSound("sound/player/janet/fall1.wav", qfalse );
784 trap_S_RegisterSound("sound/player/janet/taunt.wav", qfalse );
785 #endif
786
787 }
788
789
790 //===================================================================================
791
792
793 /*
794 =================
795 CG_RegisterGraphics
796
797 This function may execute for a couple of minutes with a slow disk.
798 =================
799 */
CG_RegisterGraphics(void)800 static void CG_RegisterGraphics( void ) {
801 int i;
802 char items[MAX_ITEMS+1];
803 static char *sb_nums[11] = {
804 "gfx/2d/numbers/zero_32b",
805 "gfx/2d/numbers/one_32b",
806 "gfx/2d/numbers/two_32b",
807 "gfx/2d/numbers/three_32b",
808 "gfx/2d/numbers/four_32b",
809 "gfx/2d/numbers/five_32b",
810 "gfx/2d/numbers/six_32b",
811 "gfx/2d/numbers/seven_32b",
812 "gfx/2d/numbers/eight_32b",
813 "gfx/2d/numbers/nine_32b",
814 "gfx/2d/numbers/minus_32b",
815 };
816
817 // clear any references to old media
818 memset( &cg.refdef, 0, sizeof( cg.refdef ) );
819 trap_R_ClearScene();
820
821 CG_LoadingString( cgs.mapname );
822
823 trap_R_LoadWorldMap( cgs.mapname );
824
825 // precache status bar pics
826 CG_LoadingString( "game media" );
827
828 for ( i=0 ; i<11 ; i++) {
829 cgs.media.numberShaders[i] = trap_R_RegisterShader( sb_nums[i] );
830 }
831
832 cgs.media.botSkillShaders[0] = trap_R_RegisterShader( "menu/art/skill1.tga" );
833 cgs.media.botSkillShaders[1] = trap_R_RegisterShader( "menu/art/skill2.tga" );
834 cgs.media.botSkillShaders[2] = trap_R_RegisterShader( "menu/art/skill3.tga" );
835 cgs.media.botSkillShaders[3] = trap_R_RegisterShader( "menu/art/skill4.tga" );
836 cgs.media.botSkillShaders[4] = trap_R_RegisterShader( "menu/art/skill5.tga" );
837
838 cgs.media.viewBloodShader = trap_R_RegisterShader( "viewBloodBlend" );
839
840 cgs.media.deferShader = trap_R_RegisterShaderNoMip( "gfx/2d/defer.tga" );
841
842 cgs.media.scoreboardName = trap_R_RegisterShaderNoMip( "menu/tab/name.tga" );
843 cgs.media.scoreboardPing = trap_R_RegisterShaderNoMip( "menu/tab/ping.tga" );
844 cgs.media.scoreboardScore = trap_R_RegisterShaderNoMip( "menu/tab/score.tga" );
845 cgs.media.scoreboardTime = trap_R_RegisterShaderNoMip( "menu/tab/time.tga" );
846
847 cgs.media.smokePuffShader = trap_R_RegisterShader( "smokePuff" );
848 cgs.media.smokePuffRageProShader = trap_R_RegisterShader( "smokePuffRagePro" );
849 cgs.media.shotgunSmokePuffShader = trap_R_RegisterShader( "shotgunSmokePuff" );
850 #ifdef MISSIONPACK
851 cgs.media.nailPuffShader = trap_R_RegisterShader( "nailtrail" );
852 cgs.media.blueProxMine = trap_R_RegisterModel( "models/weaphits/proxmineb.md3" );
853 #endif
854 cgs.media.plasmaBallShader = trap_R_RegisterShader( "sprites/plasma1" );
855 cgs.media.bloodTrailShader = trap_R_RegisterShader( "bloodTrail" );
856 cgs.media.lagometerShader = trap_R_RegisterShader("lagometer" );
857 cgs.media.connectionShader = trap_R_RegisterShader( "disconnected" );
858
859 cgs.media.waterBubbleShader = trap_R_RegisterShader( "waterBubble" );
860
861 cgs.media.tracerShader = trap_R_RegisterShader( "gfx/misc/tracer" );
862 cgs.media.selectShader = trap_R_RegisterShader( "gfx/2d/select" );
863
864 for ( i = 0 ; i < NUM_CROSSHAIRS ; i++ ) {
865 cgs.media.crosshairShader[i] = trap_R_RegisterShader( va("gfx/2d/crosshair%c", 'a'+i) );
866 }
867
868 cgs.media.backTileShader = trap_R_RegisterShader( "gfx/2d/backtile" );
869 cgs.media.noammoShader = trap_R_RegisterShader( "icons/noammo" );
870
871 // powerup shaders
872 cgs.media.quadShader = trap_R_RegisterShader("powerups/quad" );
873 cgs.media.quadWeaponShader = trap_R_RegisterShader("powerups/quadWeapon" );
874 cgs.media.battleSuitShader = trap_R_RegisterShader("powerups/battleSuit" );
875 cgs.media.battleWeaponShader = trap_R_RegisterShader("powerups/battleWeapon" );
876 cgs.media.invisShader = trap_R_RegisterShader("powerups/invisibility" );
877 cgs.media.regenShader = trap_R_RegisterShader("powerups/regen" );
878 cgs.media.hastePuffShader = trap_R_RegisterShader("hasteSmokePuff" );
879
880 #ifdef MISSIONPACK
881 if ( cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF || cgs.gametype == GT_HARVESTER || cg_buildScript.integer ) {
882 #else
883 if ( cgs.gametype == GT_CTF || cg_buildScript.integer ) {
884 #endif
885 cgs.media.redCubeModel = trap_R_RegisterModel( "models/powerups/orb/r_orb.md3" );
886 cgs.media.blueCubeModel = trap_R_RegisterModel( "models/powerups/orb/b_orb.md3" );
887 cgs.media.redCubeIcon = trap_R_RegisterShader( "icons/skull_red" );
888 cgs.media.blueCubeIcon = trap_R_RegisterShader( "icons/skull_blue" );
889 }
890
891 #ifdef MISSIONPACK
892 if ( cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF || cgs.gametype == GT_HARVESTER || cg_buildScript.integer ) {
893 #else
894 if ( cgs.gametype == GT_CTF || cg_buildScript.integer ) {
895 #endif
896 cgs.media.redFlagModel = trap_R_RegisterModel( "models/flags/r_flag.md3" );
897 cgs.media.blueFlagModel = trap_R_RegisterModel( "models/flags/b_flag.md3" );
898 cgs.media.redFlagShader[0] = trap_R_RegisterShaderNoMip( "icons/iconf_red1" );
899 cgs.media.redFlagShader[1] = trap_R_RegisterShaderNoMip( "icons/iconf_red2" );
900 cgs.media.redFlagShader[2] = trap_R_RegisterShaderNoMip( "icons/iconf_red3" );
901 cgs.media.blueFlagShader[0] = trap_R_RegisterShaderNoMip( "icons/iconf_blu1" );
902 cgs.media.blueFlagShader[1] = trap_R_RegisterShaderNoMip( "icons/iconf_blu2" );
903 cgs.media.blueFlagShader[2] = trap_R_RegisterShaderNoMip( "icons/iconf_blu3" );
904 #ifdef MISSIONPACK
905 cgs.media.flagPoleModel = trap_R_RegisterModel( "models/flag2/flagpole.md3" );
906 cgs.media.flagFlapModel = trap_R_RegisterModel( "models/flag2/flagflap3.md3" );
907
908 cgs.media.redFlagFlapSkin = trap_R_RegisterSkin( "models/flag2/red.skin" );
909 cgs.media.blueFlagFlapSkin = trap_R_RegisterSkin( "models/flag2/blue.skin" );
910 cgs.media.neutralFlagFlapSkin = trap_R_RegisterSkin( "models/flag2/white.skin" );
911
912 cgs.media.redFlagBaseModel = trap_R_RegisterModel( "models/mapobjects/flagbase/red_base.md3" );
913 cgs.media.blueFlagBaseModel = trap_R_RegisterModel( "models/mapobjects/flagbase/blue_base.md3" );
914 cgs.media.neutralFlagBaseModel = trap_R_RegisterModel( "models/mapobjects/flagbase/ntrl_base.md3" );
915 #endif
916 }
917
918 #ifdef MISSIONPACK
919 if ( cgs.gametype == GT_1FCTF || cg_buildScript.integer ) {
920 cgs.media.neutralFlagModel = trap_R_RegisterModel( "models/flags/n_flag.md3" );
921 cgs.media.flagShader[0] = trap_R_RegisterShaderNoMip( "icons/iconf_neutral1" );
922 cgs.media.flagShader[1] = trap_R_RegisterShaderNoMip( "icons/iconf_red2" );
923 cgs.media.flagShader[2] = trap_R_RegisterShaderNoMip( "icons/iconf_blu2" );
924 cgs.media.flagShader[3] = trap_R_RegisterShaderNoMip( "icons/iconf_neutral3" );
925 }
926
927 if ( cgs.gametype == GT_OBELISK || cg_buildScript.integer ) {
928 cgs.media.overloadBaseModel = trap_R_RegisterModel( "models/powerups/overload_base.md3" );
929 cgs.media.overloadTargetModel = trap_R_RegisterModel( "models/powerups/overload_target.md3" );
930 cgs.media.overloadLightsModel = trap_R_RegisterModel( "models/powerups/overload_lights.md3" );
931 cgs.media.overloadEnergyModel = trap_R_RegisterModel( "models/powerups/overload_energy.md3" );
932 }
933
934 if ( cgs.gametype == GT_HARVESTER || cg_buildScript.integer ) {
935 cgs.media.harvesterModel = trap_R_RegisterModel( "models/powerups/harvester/harvester.md3" );
936 cgs.media.harvesterRedSkin = trap_R_RegisterSkin( "models/powerups/harvester/red.skin" );
937 cgs.media.harvesterBlueSkin = trap_R_RegisterSkin( "models/powerups/harvester/blue.skin" );
938 cgs.media.harvesterNeutralModel = trap_R_RegisterModel( "models/powerups/obelisk/obelisk.md3" );
939 }
940
941 cgs.media.redKamikazeShader = trap_R_RegisterShader( "models/weaphits/kamikred" );
942 cgs.media.dustPuffShader = trap_R_RegisterShader("hasteSmokePuff" );
943 #endif
944
945 if ( cgs.gametype >= GT_TEAM || cg_buildScript.integer ) {
946 cgs.media.friendShader = trap_R_RegisterShader( "sprites/foe" );
947 cgs.media.redQuadShader = trap_R_RegisterShader("powerups/blueflag" );
948 cgs.media.teamStatusBar = trap_R_RegisterShader( "gfx/2d/colorbar.tga" );
949 #ifdef MISSIONPACK
950 cgs.media.blueKamikazeShader = trap_R_RegisterShader( "models/weaphits/kamikblu" );
951 #endif
952 }
953
954 cgs.media.armorModel = trap_R_RegisterModel( "models/powerups/armor/armor_yel.md3" );
955 cgs.media.armorIcon = trap_R_RegisterShaderNoMip( "icons/iconr_yellow" );
956
957 cgs.media.machinegunBrassModel = trap_R_RegisterModel( "models/weapons2/shells/m_shell.md3" );
958 cgs.media.shotgunBrassModel = trap_R_RegisterModel( "models/weapons2/shells/s_shell.md3" );
959
960 cgs.media.gibAbdomen = trap_R_RegisterModel( "models/gibs/abdomen.md3" );
961 cgs.media.gibArm = trap_R_RegisterModel( "models/gibs/arm.md3" );
962 cgs.media.gibChest = trap_R_RegisterModel( "models/gibs/chest.md3" );
963 cgs.media.gibFist = trap_R_RegisterModel( "models/gibs/fist.md3" );
964 cgs.media.gibFoot = trap_R_RegisterModel( "models/gibs/foot.md3" );
965 cgs.media.gibForearm = trap_R_RegisterModel( "models/gibs/forearm.md3" );
966 cgs.media.gibIntestine = trap_R_RegisterModel( "models/gibs/intestine.md3" );
967 cgs.media.gibLeg = trap_R_RegisterModel( "models/gibs/leg.md3" );
968 cgs.media.gibSkull = trap_R_RegisterModel( "models/gibs/skull.md3" );
969 cgs.media.gibBrain = trap_R_RegisterModel( "models/gibs/brain.md3" );
970
971 cgs.media.smoke2 = trap_R_RegisterModel( "models/weapons2/shells/s_shell.md3" );
972
973 cgs.media.balloonShader = trap_R_RegisterShader( "sprites/balloon3" );
974
975 cgs.media.bloodExplosionShader = trap_R_RegisterShader( "bloodExplosion" );
976
977 cgs.media.bulletFlashModel = trap_R_RegisterModel("models/weaphits/bullet.md3");
978 cgs.media.ringFlashModel = trap_R_RegisterModel("models/weaphits/ring02.md3");
979 cgs.media.dishFlashModel = trap_R_RegisterModel("models/weaphits/boom01.md3");
980 #ifdef MISSIONPACK
981 cgs.media.teleportEffectModel = trap_R_RegisterModel( "models/powerups/pop.md3" );
982 #else
983 cgs.media.teleportEffectModel = trap_R_RegisterModel( "models/misc/telep.md3" );
984 cgs.media.teleportEffectShader = trap_R_RegisterShader( "teleportEffect" );
985 #endif
986 #ifdef MISSIONPACK
987 cgs.media.kamikazeEffectModel = trap_R_RegisterModel( "models/weaphits/kamboom2.md3" );
988 cgs.media.kamikazeShockWave = trap_R_RegisterModel( "models/weaphits/kamwave.md3" );
989 cgs.media.kamikazeHeadModel = trap_R_RegisterModel( "models/powerups/kamikazi.md3" );
990 cgs.media.kamikazeHeadTrail = trap_R_RegisterModel( "models/powerups/trailtest.md3" );
991 cgs.media.guardPowerupModel = trap_R_RegisterModel( "models/powerups/guard_player.md3" );
992 cgs.media.scoutPowerupModel = trap_R_RegisterModel( "models/powerups/scout_player.md3" );
993 cgs.media.doublerPowerupModel = trap_R_RegisterModel( "models/powerups/doubler_player.md3" );
994 cgs.media.ammoRegenPowerupModel = trap_R_RegisterModel( "models/powerups/ammo_player.md3" );
995 cgs.media.invulnerabilityImpactModel = trap_R_RegisterModel( "models/powerups/shield/impact.md3" );
996 cgs.media.invulnerabilityJuicedModel = trap_R_RegisterModel( "models/powerups/shield/juicer.md3" );
997 cgs.media.medkitUsageModel = trap_R_RegisterModel( "models/powerups/regen.md3" );
998 cgs.media.heartShader = trap_R_RegisterShaderNoMip( "ui/assets/statusbar/selectedhealth.tga" );
999
1000 #endif
1001
1002 cgs.media.invulnerabilityPowerupModel = trap_R_RegisterModel( "models/powerups/shield/shield.md3" );
1003 cgs.media.medalImpressive = trap_R_RegisterShaderNoMip( "medal_impressive" );
1004 cgs.media.medalExcellent = trap_R_RegisterShaderNoMip( "medal_excellent" );
1005 cgs.media.medalGauntlet = trap_R_RegisterShaderNoMip( "medal_gauntlet" );
1006 cgs.media.medalDefend = trap_R_RegisterShaderNoMip( "medal_defend" );
1007 cgs.media.medalAssist = trap_R_RegisterShaderNoMip( "medal_assist" );
1008 cgs.media.medalCapture = trap_R_RegisterShaderNoMip( "medal_capture" );
1009
1010
1011 memset( cg_items, 0, sizeof( cg_items ) );
1012 memset( cg_weapons, 0, sizeof( cg_weapons ) );
1013
1014 // only register the items that the server says we need
1015 Q_strncpyz(items, CG_ConfigString(CS_ITEMS), sizeof(items));
1016
1017 for ( i = 1 ; i < bg_numItems ; i++ ) {
1018 if ( items[ i ] == '1' || cg_buildScript.integer ) {
1019 CG_LoadingItem( i );
1020 CG_RegisterItemVisuals( i );
1021 }
1022 }
1023
1024 // wall marks
1025 cgs.media.bulletMarkShader = trap_R_RegisterShader( "gfx/damage/bullet_mrk" );
1026 cgs.media.burnMarkShader = trap_R_RegisterShader( "gfx/damage/burn_med_mrk" );
1027 cgs.media.holeMarkShader = trap_R_RegisterShader( "gfx/damage/hole_lg_mrk" );
1028 cgs.media.energyMarkShader = trap_R_RegisterShader( "gfx/damage/plasma_mrk" );
1029 cgs.media.shadowMarkShader = trap_R_RegisterShader( "markShadow" );
1030 cgs.media.wakeMarkShader = trap_R_RegisterShader( "wake" );
1031 cgs.media.bloodMarkShader = trap_R_RegisterShader( "bloodMark" );
1032
1033 // register the inline models
1034 cgs.numInlineModels = trap_CM_NumInlineModels();
1035 for ( i = 1 ; i < cgs.numInlineModels ; i++ ) {
1036 char name[10];
1037 vec3_t mins, maxs;
1038 int j;
1039
1040 Com_sprintf( name, sizeof(name), "*%i", i );
1041 cgs.inlineDrawModel[i] = trap_R_RegisterModel( name );
1042 trap_R_ModelBounds( cgs.inlineDrawModel[i], mins, maxs );
1043 for ( j = 0 ; j < 3 ; j++ ) {
1044 cgs.inlineModelMidpoints[i][j] = mins[j] + 0.5 * ( maxs[j] - mins[j] );
1045 }
1046 }
1047
1048 // register all the server specified models
1049 for (i=1 ; i<MAX_MODELS ; i++) {
1050 const char *modelName;
1051
1052 modelName = CG_ConfigString( CS_MODELS+i );
1053 if ( !modelName[0] ) {
1054 break;
1055 }
1056 cgs.gameModels[i] = trap_R_RegisterModel( modelName );
1057 }
1058
1059 #ifdef MISSIONPACK
1060 // new stuff
1061 cgs.media.patrolShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/patrol.tga");
1062 cgs.media.assaultShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/assault.tga");
1063 cgs.media.campShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/camp.tga");
1064 cgs.media.followShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/follow.tga");
1065 cgs.media.defendShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/defend.tga");
1066 cgs.media.teamLeaderShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/team_leader.tga");
1067 cgs.media.retrieveShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/retrieve.tga");
1068 cgs.media.escortShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/escort.tga");
1069 cgs.media.cursor = trap_R_RegisterShaderNoMip( "menu/art/3_cursor2" );
1070 cgs.media.sizeCursor = trap_R_RegisterShaderNoMip( "ui/assets/sizecursor.tga" );
1071 cgs.media.selectCursor = trap_R_RegisterShaderNoMip( "ui/assets/selectcursor.tga" );
1072 cgs.media.flagShaders[0] = trap_R_RegisterShaderNoMip("ui/assets/statusbar/flag_in_base.tga");
1073 cgs.media.flagShaders[1] = trap_R_RegisterShaderNoMip("ui/assets/statusbar/flag_capture.tga");
1074 cgs.media.flagShaders[2] = trap_R_RegisterShaderNoMip("ui/assets/statusbar/flag_missing.tga");
1075
1076 trap_R_RegisterModel( "models/players/james/lower.md3" );
1077 trap_R_RegisterModel( "models/players/james/upper.md3" );
1078 trap_R_RegisterModel( "models/players/heads/james/james.md3" );
1079
1080 trap_R_RegisterModel( "models/players/janet/lower.md3" );
1081 trap_R_RegisterModel( "models/players/janet/upper.md3" );
1082 trap_R_RegisterModel( "models/players/heads/janet/janet.md3" );
1083
1084 #endif
1085 CG_ClearParticles ();
1086 /*
1087 for (i=1; i<MAX_PARTICLES_AREAS; i++)
1088 {
1089 {
1090 int rval;
1091
1092 rval = CG_NewParticleArea ( CS_PARTICLES + i);
1093 if (!rval)
1094 break;
1095 }
1096 }
1097 */
1098 }
1099
1100
1101
1102 /*
1103 =======================
1104 CG_BuildSpectatorString
1105
1106 =======================
1107 */
1108 void CG_BuildSpectatorString(void) {
1109 int i;
1110 cg.spectatorList[0] = 0;
1111 for (i = 0; i < MAX_CLIENTS; i++) {
1112 if (cgs.clientinfo[i].infoValid && cgs.clientinfo[i].team == TEAM_SPECTATOR ) {
1113 Q_strcat(cg.spectatorList, sizeof(cg.spectatorList), va("%s ", cgs.clientinfo[i].name));
1114 }
1115 }
1116 i = strlen(cg.spectatorList);
1117 if (i != cg.spectatorLen) {
1118 cg.spectatorLen = i;
1119 cg.spectatorWidth = -1;
1120 }
1121 }
1122
1123
1124 /*
1125 ===================
1126 CG_RegisterClients
1127 ===================
1128 */
1129 static void CG_RegisterClients( void ) {
1130 int i;
1131
1132 CG_LoadingClient(cg.clientNum);
1133 CG_NewClientInfo(cg.clientNum);
1134
1135 for (i=0 ; i<MAX_CLIENTS ; i++) {
1136 const char *clientInfo;
1137
1138 if (cg.clientNum == i) {
1139 continue;
1140 }
1141
1142 clientInfo = CG_ConfigString( CS_PLAYERS+i );
1143 if ( !clientInfo[0]) {
1144 continue;
1145 }
1146 CG_LoadingClient( i );
1147 CG_NewClientInfo( i );
1148 }
1149 CG_BuildSpectatorString();
1150 }
1151
1152 //===========================================================================
1153
1154 /*
1155 =================
1156 CG_ConfigString
1157 =================
1158 */
1159 const char *CG_ConfigString( int index ) {
1160 if ( index < 0 || index >= MAX_CONFIGSTRINGS ) {
1161 CG_Error( "CG_ConfigString: bad index: %i", index );
1162 }
1163 return cgs.gameState.stringData + cgs.gameState.stringOffsets[ index ];
1164 }
1165
1166 //==================================================================
1167
1168 /*
1169 ======================
1170 CG_StartMusic
1171
1172 ======================
1173 */
1174 void CG_StartMusic( void ) {
1175 char *s;
1176 char parm1[MAX_QPATH], parm2[MAX_QPATH];
1177
1178 // start the background music
1179 s = (char *)CG_ConfigString( CS_MUSIC );
1180 Q_strncpyz( parm1, Com_Parse( &s ), sizeof( parm1 ) );
1181 Q_strncpyz( parm2, Com_Parse( &s ), sizeof( parm2 ) );
1182
1183 trap_S_StartBackgroundTrack( parm1, parm2 );
1184 }
1185 #ifdef MISSIONPACK
1186 char *CG_GetMenuBuffer(const char *filename) {
1187 int len;
1188 fileHandle_t f;
1189 static char buf[MAX_MENUFILE];
1190
1191 len = trap_FS_FOpenFile( filename, &f, FS_READ );
1192 if ( !f ) {
1193 trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) );
1194 return NULL;
1195 }
1196 if ( len >= MAX_MENUFILE ) {
1197 trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) );
1198 trap_FS_FCloseFile( f );
1199 return NULL;
1200 }
1201
1202 trap_FS_Read( buf, len, f );
1203 buf[len] = 0;
1204 trap_FS_FCloseFile( f );
1205
1206 return buf;
1207 }
1208
1209 //
1210 // ==============================
1211 // new hud stuff ( mission pack )
1212 // ==============================
1213 //
1214 qboolean CG_Asset_Parse(int handle) {
1215 pc_token_t token;
1216 const char *tempStr;
1217
1218 if (!trap_PC_ReadToken(handle, &token))
1219 return qfalse;
1220 if (Q_stricmp(token.string, "{") != 0) {
1221 return qfalse;
1222 }
1223
1224 while ( 1 ) {
1225 if (!trap_PC_ReadToken(handle, &token))
1226 return qfalse;
1227
1228 if (Q_stricmp(token.string, "}") == 0) {
1229 return qtrue;
1230 }
1231
1232 // font
1233 if (Q_stricmp(token.string, "font") == 0) {
1234 int pointSize;
1235 if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle, &pointSize)) {
1236 return qfalse;
1237 }
1238 cgDC.registerFont(tempStr, pointSize, &cgDC.Assets.textFont);
1239 continue;
1240 }
1241
1242 // smallFont
1243 if (Q_stricmp(token.string, "smallFont") == 0) {
1244 int pointSize;
1245 if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle, &pointSize)) {
1246 return qfalse;
1247 }
1248 cgDC.registerFont(tempStr, pointSize, &cgDC.Assets.smallFont);
1249 continue;
1250 }
1251
1252 // font
1253 if (Q_stricmp(token.string, "bigfont") == 0) {
1254 int pointSize;
1255 if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle, &pointSize)) {
1256 return qfalse;
1257 }
1258 cgDC.registerFont(tempStr, pointSize, &cgDC.Assets.bigFont);
1259 continue;
1260 }
1261
1262 // gradientbar
1263 if (Q_stricmp(token.string, "gradientbar") == 0) {
1264 if (!PC_String_Parse(handle, &tempStr)) {
1265 return qfalse;
1266 }
1267 cgDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(tempStr);
1268 continue;
1269 }
1270
1271 // enterMenuSound
1272 if (Q_stricmp(token.string, "menuEnterSound") == 0) {
1273 if (!PC_String_Parse(handle, &tempStr)) {
1274 return qfalse;
1275 }
1276 cgDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr, qfalse );
1277 continue;
1278 }
1279
1280 // exitMenuSound
1281 if (Q_stricmp(token.string, "menuExitSound") == 0) {
1282 if (!PC_String_Parse(handle, &tempStr)) {
1283 return qfalse;
1284 }
1285 cgDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr, qfalse );
1286 continue;
1287 }
1288
1289 // itemFocusSound
1290 if (Q_stricmp(token.string, "itemFocusSound") == 0) {
1291 if (!PC_String_Parse(handle, &tempStr)) {
1292 return qfalse;
1293 }
1294 cgDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr, qfalse );
1295 continue;
1296 }
1297
1298 // menuBuzzSound
1299 if (Q_stricmp(token.string, "menuBuzzSound") == 0) {
1300 if (!PC_String_Parse(handle, &tempStr)) {
1301 return qfalse;
1302 }
1303 cgDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr, qfalse );
1304 continue;
1305 }
1306
1307 if (Q_stricmp(token.string, "cursor") == 0) {
1308 if (!PC_String_Parse(handle, &cgDC.Assets.cursorStr)) {
1309 return qfalse;
1310 }
1311 cgDC.Assets.cursor = trap_R_RegisterShaderNoMip( cgDC.Assets.cursorStr);
1312 continue;
1313 }
1314
1315 if (Q_stricmp(token.string, "fadeClamp") == 0) {
1316 if (!PC_Float_Parse(handle, &cgDC.Assets.fadeClamp)) {
1317 return qfalse;
1318 }
1319 continue;
1320 }
1321
1322 if (Q_stricmp(token.string, "fadeCycle") == 0) {
1323 if (!PC_Int_Parse(handle, &cgDC.Assets.fadeCycle)) {
1324 return qfalse;
1325 }
1326 continue;
1327 }
1328
1329 if (Q_stricmp(token.string, "fadeAmount") == 0) {
1330 if (!PC_Float_Parse(handle, &cgDC.Assets.fadeAmount)) {
1331 return qfalse;
1332 }
1333 continue;
1334 }
1335
1336 if (Q_stricmp(token.string, "shadowX") == 0) {
1337 if (!PC_Float_Parse(handle, &cgDC.Assets.shadowX)) {
1338 return qfalse;
1339 }
1340 continue;
1341 }
1342
1343 if (Q_stricmp(token.string, "shadowY") == 0) {
1344 if (!PC_Float_Parse(handle, &cgDC.Assets.shadowY)) {
1345 return qfalse;
1346 }
1347 continue;
1348 }
1349
1350 if (Q_stricmp(token.string, "shadowColor") == 0) {
1351 if (!PC_Color_Parse(handle, &cgDC.Assets.shadowColor)) {
1352 return qfalse;
1353 }
1354 cgDC.Assets.shadowFadeClamp = cgDC.Assets.shadowColor[3];
1355 continue;
1356 }
1357 }
1358 return qfalse;
1359 }
1360
1361 void CG_ParseMenu(const char *menuFile) {
1362 pc_token_t token;
1363 int handle;
1364
1365 handle = trap_PC_LoadSource(menuFile);
1366 if (!handle)
1367 handle = trap_PC_LoadSource("ui/testhud.menu");
1368 if (!handle)
1369 return;
1370
1371 while ( 1 ) {
1372 if (!trap_PC_ReadToken( handle, &token )) {
1373 break;
1374 }
1375
1376 //if ( Q_stricmp( token, "{" ) ) {
1377 // Com_Printf( "Missing { in menu file\n" );
1378 // break;
1379 //}
1380
1381 //if ( menuCount == MAX_MENUS ) {
1382 // Com_Printf( "Too many menus!\n" );
1383 // break;
1384 //}
1385
1386 if ( token.string[0] == '}' ) {
1387 break;
1388 }
1389
1390 if (Q_stricmp(token.string, "assetGlobalDef") == 0) {
1391 if (CG_Asset_Parse(handle)) {
1392 continue;
1393 } else {
1394 break;
1395 }
1396 }
1397
1398
1399 if (Q_stricmp(token.string, "menudef") == 0) {
1400 // start a new menu
1401 Menu_New(handle);
1402 }
1403 }
1404 trap_PC_FreeSource(handle);
1405 }
1406
1407 qboolean CG_Load_Menu(char **p) {
1408 char *token;
1409
1410 token = Com_ParseExt(p, qtrue);
1411
1412 if (token[0] != '{') {
1413 return qfalse;
1414 }
1415
1416 while ( 1 ) {
1417
1418 token = Com_ParseExt(p, qtrue);
1419
1420 if (Q_stricmp(token, "}") == 0) {
1421 return qtrue;
1422 }
1423
1424 if ( !token || token[0] == 0 ) {
1425 return qfalse;
1426 }
1427
1428 CG_ParseMenu(token);
1429 }
1430 return qfalse;
1431 }
1432
1433
1434
1435 void CG_LoadMenus(const char *menuFile) {
1436 char *token;
1437 char *p;
1438 int len, start;
1439 fileHandle_t f;
1440 static char buf[MAX_MENUDEFFILE];
1441
1442 start = trap_Milliseconds();
1443
1444 len = trap_FS_FOpenFile( menuFile, &f, FS_READ );
1445 if ( !f ) {
1446 trap_Error( va( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile ) );
1447 len = trap_FS_FOpenFile( "ui/hud.txt", &f, FS_READ );
1448 if (!f) {
1449 trap_Error( va( S_COLOR_RED "default menu file not found: ui/hud.txt, unable to continue!\n") );
1450 }
1451 }
1452
1453 if ( len >= MAX_MENUDEFFILE ) {
1454 trap_Error( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", menuFile, len, MAX_MENUDEFFILE ) );
1455 trap_FS_FCloseFile( f );
1456 return;
1457 }
1458
1459 trap_FS_Read( buf, len, f );
1460 buf[len] = 0;
1461 trap_FS_FCloseFile( f );
1462
1463 COM_Compress(buf);
1464
1465 Menu_Reset();
1466
1467 p = buf;
1468
1469 while ( 1 ) {
1470 token = Com_ParseExt( &p, qtrue );
1471 if( !token || token[0] == 0 || token[0] == '}') {
1472 break;
1473 }
1474
1475 //if ( Q_stricmp( token, "{" ) ) {
1476 // Com_Printf( "Missing { in menu file\n" );
1477 // break;
1478 //}
1479
1480 //if ( menuCount == MAX_MENUS ) {
1481 // Com_Printf( "Too many menus!\n" );
1482 // break;
1483 //}
1484
1485 if ( Q_stricmp( token, "}" ) == 0 ) {
1486 break;
1487 }
1488
1489 if (Q_stricmp(token, "loadmenu") == 0) {
1490 if (CG_Load_Menu(&p)) {
1491 continue;
1492 } else {
1493 break;
1494 }
1495 }
1496 }
1497
1498 Com_Printf("UI menu load time = %d milli seconds\n", trap_Milliseconds() - start);
1499
1500 }
1501
1502
1503
1504 static qboolean CG_OwnerDrawHandleKey(int ownerDraw, int flags, float *special, int key) {
1505 return qfalse;
1506 }
1507
1508
1509 static int CG_FeederCount(float feederID) {
1510 int i, count;
1511 count = 0;
1512 if (feederID == FEEDER_REDTEAM_LIST) {
1513 for (i = 0; i < cg.numScores; i++) {
1514 if (cg.scores[i].team == TEAM_RED) {
1515 count++;
1516 }
1517 }
1518 } else if (feederID == FEEDER_BLUETEAM_LIST) {
1519 for (i = 0; i < cg.numScores; i++) {
1520 if (cg.scores[i].team == TEAM_BLUE) {
1521 count++;
1522 }
1523 }
1524 } else if (feederID == FEEDER_SCOREBOARD) {
1525 return cg.numScores;
1526 }
1527 return count;
1528 }
1529
1530
1531 void CG_SetScoreSelection(void *p) {
1532 menuDef_t *menu = (menuDef_t*)p;
1533 playerState_t *ps = &cg.snap->ps;
1534 int i, red, blue;
1535 red = blue = 0;
1536 for (i = 0; i < cg.numScores; i++) {
1537 if (cg.scores[i].team == TEAM_RED) {
1538 red++;
1539 } else if (cg.scores[i].team == TEAM_BLUE) {
1540 blue++;
1541 }
1542 if (ps->clientNum == cg.scores[i].client) {
1543 cg.selectedScore = i;
1544 }
1545 }
1546
1547 if (menu == NULL) {
1548 // just interested in setting the selected score
1549 return;
1550 }
1551
1552 if ( cgs.gametype >= GT_TEAM ) {
1553 int feeder = FEEDER_REDTEAM_LIST;
1554 i = red;
1555 if (cg.scores[cg.selectedScore].team == TEAM_BLUE) {
1556 feeder = FEEDER_BLUETEAM_LIST;
1557 i = blue;
1558 }
1559 Menu_SetFeederSelection(menu, feeder, i, NULL);
1560 } else {
1561 Menu_SetFeederSelection(menu, FEEDER_SCOREBOARD, cg.selectedScore, NULL);
1562 }
1563 }
1564
1565 // FIXME: might need to cache this info
1566 static clientInfo_t * CG_InfoFromScoreIndex(int index, int team, int *scoreIndex) {
1567 int i, count;
1568 if ( cgs.gametype >= GT_TEAM ) {
1569 count = 0;
1570 for (i = 0; i < cg.numScores; i++) {
1571 if (cg.scores[i].team == team) {
1572 if (count == index) {
1573 *scoreIndex = i;
1574 return &cgs.clientinfo[cg.scores[i].client];
1575 }
1576 count++;
1577 }
1578 }
1579 }
1580 *scoreIndex = index;
1581 return &cgs.clientinfo[ cg.scores[index].client ];
1582 }
1583
1584 static const char *CG_FeederItemText(float feederID, int index, int column, qhandle_t *handle) {
1585 gitem_t *item;
1586 int scoreIndex = 0;
1587 clientInfo_t *info = NULL;
1588 int team = -1;
1589 score_t *sp = NULL;
1590
1591 *handle = -1;
1592
1593 if (feederID == FEEDER_REDTEAM_LIST) {
1594 team = TEAM_RED;
1595 } else if (feederID == FEEDER_BLUETEAM_LIST) {
1596 team = TEAM_BLUE;
1597 }
1598
1599 info = CG_InfoFromScoreIndex(index, team, &scoreIndex);
1600 sp = &cg.scores[scoreIndex];
1601
1602 if (info && info->infoValid) {
1603 switch (column) {
1604 case 0:
1605 if ( info->powerups & ( 1 << PW_NEUTRALFLAG ) ) {
1606 item = BG_FindItemForPowerup( PW_NEUTRALFLAG );
1607 *handle = cg_items[ ITEM_INDEX(item) ].icon;
1608 } else if ( info->powerups & ( 1 << PW_REDFLAG ) ) {
1609 item = BG_FindItemForPowerup( PW_REDFLAG );
1610 *handle = cg_items[ ITEM_INDEX(item) ].icon;
1611 } else if ( info->powerups & ( 1 << PW_BLUEFLAG ) ) {
1612 item = BG_FindItemForPowerup( PW_BLUEFLAG );
1613 *handle = cg_items[ ITEM_INDEX(item) ].icon;
1614 } else {
1615 if ( info->botSkill > 0 && info->botSkill <= 5 ) {
1616 *handle = cgs.media.botSkillShaders[ info->botSkill - 1 ];
1617 } else if ( info->handicap < 100 ) {
1618 return va("%i", info->handicap );
1619 }
1620 }
1621 break;
1622 case 1:
1623 if (team == -1) {
1624 return "";
1625 } else {
1626 *handle = CG_StatusHandle(info->teamTask);
1627 }
1628 break;
1629 case 2:
1630 if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << sp->client ) ) {
1631 return "Ready";
1632 }
1633 if (team == -1) {
1634 if (cgs.gametype == GT_TOURNAMENT) {
1635 return va("%i/%i", info->wins, info->losses);
1636 } else if (info->infoValid && info->team == TEAM_SPECTATOR ) {
1637 return "Spectator";
1638 } else {
1639 return "";
1640 }
1641 } else {
1642 if (info->teamLeader) {
1643 return "Leader";
1644 }
1645 }
1646 break;
1647 case 3:
1648 return info->name;
1649 break;
1650 case 4:
1651 return va("%i", info->score);
1652 break;
1653 case 5:
1654 return va("%4i", sp->time);
1655 break;
1656 case 6:
1657 if ( sp->ping == -1 ) {
1658 return "connecting";
1659 }
1660 return va("%4i", sp->ping);
1661 break;
1662 }
1663 }
1664
1665 return "";
1666 }
1667
1668 static qhandle_t CG_FeederItemImage(float feederID, int index) {
1669 return 0;
1670 }
1671
1672 static void CG_FeederSelection(float feederID, int index) {
1673 if ( cgs.gametype >= GT_TEAM ) {
1674 int i, count;
1675 int team = (feederID == FEEDER_REDTEAM_LIST) ? TEAM_RED : TEAM_BLUE;
1676 count = 0;
1677 for (i = 0; i < cg.numScores; i++) {
1678 if (cg.scores[i].team == team) {
1679 if (index == count) {
1680 cg.selectedScore = i;
1681 }
1682 count++;
1683 }
1684 }
1685 } else {
1686 cg.selectedScore = index;
1687 }
1688 }
1689 #endif
1690
1691 #ifdef MISSIONPACK
1692 static float CG_Cvar_Get(const char *cvar) {
1693 char buff[128];
1694 memset(buff, 0, sizeof(buff));
1695 trap_Cvar_VariableStringBuffer(cvar, buff, sizeof(buff));
1696 return atof(buff);
1697 }
1698 #endif
1699
1700 #ifdef MISSIONPACK
1701 void CG_Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style) {
1702 CG_Text_Paint(x, y, scale, color, text, 0, limit, style);
1703 }
1704
1705 static int CG_OwnerDrawWidth(int ownerDraw, float scale) {
1706 switch (ownerDraw) {
1707 case CG_GAME_TYPE:
1708 return CG_Text_Width(CG_GameTypeString(), scale, 0);
1709 case CG_GAME_STATUS:
1710 return CG_Text_Width(CG_GetGameStatusText(), scale, 0);
1711 break;
1712 case CG_KILLER:
1713 return CG_Text_Width(CG_GetKillerText(), scale, 0);
1714 break;
1715 case CG_RED_NAME:
1716 return CG_Text_Width(cg_redTeamName.string, scale, 0);
1717 break;
1718 case CG_BLUE_NAME:
1719 return CG_Text_Width(cg_blueTeamName.string, scale, 0);
1720 break;
1721
1722
1723 }
1724 return 0;
1725 }
1726
1727 static int CG_PlayCinematic(const char *name, float x, float y, float w, float h) {
1728 return trap_CIN_PlayCinematic(name, x, y, w, h, CIN_loop);
1729 }
1730
1731 static void CG_StopCinematic(int handle) {
1732 trap_CIN_StopCinematic(handle);
1733 }
1734
1735 static void CG_DrawCinematic(int handle, float x, float y, float w, float h) {
1736 trap_CIN_SetExtents(handle, x, y, w, h);
1737 trap_CIN_DrawCinematic(handle);
1738 }
1739
1740 static void CG_RunCinematicFrame(int handle) {
1741 trap_CIN_RunCinematic(handle);
1742 }
1743
1744 /*
1745 =================
1746 CG_LoadHudMenu();
1747
1748 =================
1749 */
1750 void CG_LoadHudMenu( void ) {
1751 char buff[1024];
1752 const char *hudSet;
1753
1754 cgDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip;
1755 cgDC.setColor = &trap_R_SetColor;
1756 cgDC.drawHandlePic = &CG_DrawPic;
1757 cgDC.drawStretchPic = &trap_R_DrawStretchPic;
1758 cgDC.drawText = &CG_Text_Paint;
1759 cgDC.textWidth = &CG_Text_Width;
1760 cgDC.textHeight = &CG_Text_Height;
1761 cgDC.registerModel = &trap_R_RegisterModel;
1762 cgDC.modelBounds = &trap_R_ModelBounds;
1763 cgDC.fillRect = &CG_FillRect;
1764 cgDC.drawRect = &CG_DrawRect;
1765 cgDC.drawSides = &CG_DrawSides;
1766 cgDC.drawTopBottom = &CG_DrawTopBottom;
1767 cgDC.clearScene = &trap_R_ClearScene;
1768 cgDC.addRefEntityToScene = &trap_R_AddRefEntityToScene;
1769 cgDC.renderScene = &trap_R_RenderScene;
1770 cgDC.registerFont = &trap_R_RegisterFont;
1771 cgDC.ownerDrawItem = &CG_OwnerDraw;
1772 cgDC.getValue = &CG_GetValue;
1773 cgDC.ownerDrawVisible = &CG_OwnerDrawVisible;
1774 cgDC.runScript = &CG_RunMenuScript;
1775 cgDC.getTeamColor = &CG_GetTeamColor;
1776 cgDC.setCVar = trap_Cvar_Set;
1777 cgDC.getCVarString = trap_Cvar_VariableStringBuffer;
1778 cgDC.getCVarValue = CG_Cvar_Get;
1779 cgDC.drawTextWithCursor = &CG_Text_PaintWithCursor;
1780 //cgDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode;
1781 //cgDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode;
1782 cgDC.startLocalSound = &trap_S_StartLocalSound;
1783 cgDC.ownerDrawHandleKey = &CG_OwnerDrawHandleKey;
1784 cgDC.feederCount = &CG_FeederCount;
1785 cgDC.feederItemImage = &CG_FeederItemImage;
1786 cgDC.feederItemText = &CG_FeederItemText;
1787 cgDC.feederSelection = &CG_FeederSelection;
1788 //cgDC.setBinding = &trap_Key_SetBinding;
1789 //cgDC.getBindingBuf = &trap_Key_GetBindingBuf;
1790 //cgDC.keynumToStringBuf = &trap_Key_KeynumToStringBuf;
1791 //cgDC.executeText = &trap_Cmd_ExecuteText;
1792 cgDC.Error = &Com_Error;
1793 cgDC.Print = &Com_Printf;
1794 cgDC.ownerDrawWidth = &CG_OwnerDrawWidth;
1795 //cgDC.Pause = &CG_Pause;
1796 cgDC.registerSound = &trap_S_RegisterSound;
1797 cgDC.startBackgroundTrack = &trap_S_StartBackgroundTrack;
1798 cgDC.stopBackgroundTrack = &trap_S_StopBackgroundTrack;
1799 cgDC.playCinematic = &CG_PlayCinematic;
1800 cgDC.stopCinematic = &CG_StopCinematic;
1801 cgDC.drawCinematic = &CG_DrawCinematic;
1802 cgDC.runCinematicFrame = &CG_RunCinematicFrame;
1803
1804 Init_Display(&cgDC);
1805
1806 Menu_Reset();
1807
1808 trap_Cvar_VariableStringBuffer("cg_hudFiles", buff, sizeof(buff));
1809 hudSet = buff;
1810 if (hudSet[0] == '\0') {
1811 hudSet = "ui/hud.txt";
1812 }
1813
1814 CG_LoadMenus(hudSet);
1815 }
1816
1817 void CG_AssetCache( void ) {
1818 //if (Assets.textFont == NULL) {
1819 // trap_R_RegisterFont("fonts/arial.ttf", 72, &Assets.textFont);
1820 //}
1821 //Assets.background = trap_R_RegisterShaderNoMip( ASSET_BACKGROUND );
1822 //Com_Printf("Menu Size: %i bytes\n", sizeof(Menus));
1823 cgDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR );
1824 cgDC.Assets.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE );
1825 cgDC.Assets.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED );
1826 cgDC.Assets.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW );
1827 cgDC.Assets.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_GREEN );
1828 cgDC.Assets.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_TEAL );
1829 cgDC.Assets.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_BLUE );
1830 cgDC.Assets.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_CYAN );
1831 cgDC.Assets.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE );
1832 cgDC.Assets.scrollBar = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR );
1833 cgDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN );
1834 cgDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP );
1835 cgDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT );
1836 cgDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT );
1837 cgDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip( ASSET_SCROLL_THUMB );
1838 cgDC.Assets.sliderBar = trap_R_RegisterShaderNoMip( ASSET_SLIDER_BAR );
1839 cgDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip( ASSET_SLIDER_THUMB );
1840 }
1841 #endif
1842 /*
1843 =================
1844 CG_Init
1845
1846 Called after every level change or subsystem restart
1847 Will perform callbacks to make the loading info screen update.
1848 =================
1849 */
1850 void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum ) {
1851 const char *s;
1852
1853 // clear everything
1854 memset( &cgs, 0, sizeof( cgs ) );
1855 memset( &cg, 0, sizeof( cg ) );
1856 memset( cg_entities, 0, sizeof(cg_entities) );
1857 memset( cg_weapons, 0, sizeof(cg_weapons) );
1858 memset( cg_items, 0, sizeof(cg_items) );
1859
1860 cg.clientNum = clientNum;
1861
1862 cgs.processedSnapshotNum = serverMessageNum;
1863 cgs.serverCommandSequence = serverCommandSequence;
1864
1865 // load a few needed things before we do any screen updates
1866 cgs.media.charsetShader = trap_R_RegisterShader( "gfx/2d/bigchars" );
1867 cgs.media.whiteShader = trap_R_RegisterShader( "white" );
1868 cgs.media.charsetProp = trap_R_RegisterShaderNoMip( "menu/art/font1_prop.tga" );
1869 cgs.media.charsetPropGlow = trap_R_RegisterShaderNoMip( "menu/art/font1_prop_glo.tga" );
1870 cgs.media.charsetPropB = trap_R_RegisterShaderNoMip( "menu/art/font2_prop.tga" );
1871
1872 CG_RegisterCvars();
1873
1874 CG_InitConsoleCommands();
1875
1876 cg.weaponSelect = WP_MACHINEGUN;
1877
1878 cgs.redflag = cgs.blueflag = -1; // For compatibily, default to unset for
1879 cgs.flagStatus = -1;
1880 // old servers
1881
1882 // get the rendering configuration from the client system
1883 trap_GetGlconfig( &cgs.glconfig );
1884 cgs.screenXScale = cgs.glconfig.vidWidth / 640.0;
1885 cgs.screenYScale = cgs.glconfig.vidHeight / 480.0;
1886
1887 // get the gamestate from the client system
1888 trap_GetGameState( &cgs.gameState );
1889
1890 // check version
1891 s = CG_ConfigString( CS_GAME_VERSION );
1892 if ( strcmp( s, GAME_VERSION ) ) {
1893 CG_Error( "Client/Server game mismatch: %s/%s", GAME_VERSION, s );
1894 }
1895
1896 s = CG_ConfigString( CS_LEVEL_START_TIME );
1897 cgs.levelStartTime = atoi( s );
1898
1899 CG_ParseServerinfo();
1900
1901 // load the new map
1902 CG_LoadingString( "collision map" );
1903
1904 trap_CM_LoadMap( cgs.mapname );
1905
1906 #ifdef MISSIONPACK
1907 String_Init();
1908 #endif
1909
1910 cg.loading = qtrue; // force players to load instead of defer
1911
1912 CG_LoadingString( "sounds" );
1913
1914 CG_RegisterSounds();
1915
1916 CG_LoadingString( "graphics" );
1917
1918 CG_RegisterGraphics();
1919
1920 CG_LoadingString( "clients" );
1921
1922 CG_RegisterClients(); // if low on memory, some clients will be deferred
1923
1924 #ifdef MISSIONPACK
1925 CG_AssetCache();
1926 CG_LoadHudMenu(); // load new hud stuff
1927 #endif
1928
1929 cg.loading = qfalse; // future players will be deferred
1930
1931 CG_InitLocalEntities();
1932
1933 CG_InitMarkPolys();
1934
1935 // remove the last loading update
1936 cg.infoScreenText[0] = 0;
1937
1938 // Make sure we have update values (scores)
1939 CG_SetConfigValues();
1940
1941 CG_StartMusic();
1942
1943 CG_LoadingString( "" );
1944
1945 #ifdef MISSIONPACK
1946 CG_InitTeamChat();
1947 #endif
1948
1949 CG_ShaderStateChanged();
1950
1951 trap_S_ClearLoopingSounds( qtrue );
1952 }
1953
1954 /*
1955 =================
1956 CG_Shutdown
1957
1958 Called before every level change or subsystem restart
1959 =================
1960 */
1961 void CG_Shutdown( void ) {
1962 // some mods may need to do cleanup work here,
1963 // like closing files or archiving session data
1964 }
1965
1966
1967 /*
1968 ==================
1969 CG_EventHandling
1970 ==================
1971 type 0 - no event handling
1972 1 - team menu
1973 2 - hud editor
1974
1975 */
1976 #ifndef MISSIONPACK
1977 void CG_EventHandling(int type) {
1978 }
1979
1980
1981
1982 void CG_KeyEvent(int key, qboolean down) {
1983 }
1984
1985 void CG_MouseEvent(int x, int y) {
1986 }
1987 #endif
1988
1989