1 /*
2 ===========================================================================
3 
4 Return to Castle Wolfenstein single player GPL Source Code
5 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”).
8 
9 RTCW SP Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 RTCW SP Source Code 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 RTCW SP Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the RTCW SP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW SP Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 /*
30  * name:		cg_main.c
31  *
32  * desc:		initialization and primary entry point for cgame
33  *
34 */
35 
36 
37 #include "cg_local.h"
38 #include "../ui/ui_shared.h"
39 
40 displayContextDef_t cgDC;
41 
42 int forceModelModificationCount = -1;
43 
44 void CG_Init( int serverMessageNum, int serverCommandSequence );
45 void CG_Shutdown( void );
46 
47 
48 /*
49 ================
50 vmMain
51 
52 This is the only way control passes into the module.
53 This must be the very first function compiled into the .q3vm file
54 ================
55 */
vmMain(intptr_t command,intptr_t arg0,intptr_t arg1,intptr_t arg2,intptr_t arg3,intptr_t arg4,intptr_t arg5,intptr_t arg6,intptr_t arg7,intptr_t arg8,intptr_t arg9,intptr_t arg10,intptr_t arg11)56 Q_EXPORT intptr_t vmMain( intptr_t command, intptr_t arg0, intptr_t arg1, intptr_t arg2, intptr_t arg3, intptr_t arg4, intptr_t arg5, intptr_t arg6, intptr_t arg7, intptr_t arg8, intptr_t arg9, intptr_t arg10, intptr_t arg11  ) {
57 	switch ( command ) {
58 	case CG_GET_TAG:
59 		return CG_GetTag( arg0, (char *)arg1, (orientation_t *)arg2 );
60 	case CG_DRAW_ACTIVE_FRAME:
61 		CG_DrawActiveFrame( arg0, arg1, arg2 );
62 		return 0;
63 	case CG_EVENT_HANDLING:
64 		CG_EventHandling( arg0 );
65 		return 0;
66 	case CG_INIT:
67 		CG_Init( arg0, arg1 );
68 		return 0;
69 	case CG_SHUTDOWN:
70 		CG_Shutdown();
71 		return 0;
72 	case CG_CONSOLE_COMMAND:
73 		return CG_ConsoleCommand();
74 	case CG_CROSSHAIR_PLAYER:
75 		return CG_CrosshairPlayer();
76 	case CG_LAST_ATTACKER:
77 		return CG_LastAttacker();
78 	case CG_KEY_EVENT:
79 		CG_KeyEvent( arg0, arg1 );
80 		return 0;
81 	case CG_MOUSE_EVENT:
82 		cgDC.cursorx = cgs.cursorX;
83 		cgDC.cursory = cgs.cursorY;
84 		CG_MouseEvent( arg0, arg1 );
85 		return 0;
86 	default:
87 		CG_Error( "vmMain: unknown command %li", (long)command );
88 		break;
89 	}
90 	return -1;
91 }
92 
93 
94 cg_t cg;
95 cgs_t cgs;
96 centity_t cg_entities[MAX_GENTITIES];
97 weaponInfo_t cg_weapons[MAX_WEAPONS];
98 itemInfo_t cg_items[MAX_ITEMS];
99 
100 
101 vmCvar_t cg_railTrailTime;
102 vmCvar_t cg_centertime;
103 vmCvar_t cg_runpitch;
104 vmCvar_t cg_runroll;
105 vmCvar_t cg_bobup;
106 vmCvar_t cg_bobpitch;
107 vmCvar_t cg_bobroll;
108 vmCvar_t cg_swingSpeed;
109 vmCvar_t cg_shadows;
110 vmCvar_t cg_gibs;
111 vmCvar_t cg_drawTimer;
112 vmCvar_t cg_drawFPS;
113 vmCvar_t cg_drawSnapshot;
114 vmCvar_t cg_draw3dIcons;
115 vmCvar_t cg_drawIcons;
116 vmCvar_t cg_youGotMail;         //----(SA)	added
117 vmCvar_t cg_drawAmmoWarning;
118 vmCvar_t cg_drawCrosshair;
119 vmCvar_t cg_drawCrosshairBinoc;
120 vmCvar_t cg_drawCrosshairNames;
121 vmCvar_t cg_drawCrosshairPickups;
122 vmCvar_t cg_drawCrosshairReticle;
123 vmCvar_t cg_hudAlpha;
124 vmCvar_t cg_weaponCycleDelay;       //----(SA)	added
125 vmCvar_t cg_cycleAllWeaps;
126 vmCvar_t cg_useWeapsForZoom;
127 vmCvar_t cg_drawAllWeaps;
128 vmCvar_t cg_drawRewards;
129 vmCvar_t cg_crosshairSize;
130 vmCvar_t cg_crosshairAlpha;     //----(SA)	added
131 vmCvar_t cg_crosshairX;
132 vmCvar_t cg_crosshairY;
133 vmCvar_t cg_crosshairHealth;
134 vmCvar_t cg_draw2D;
135 vmCvar_t cg_drawFrags;
136 vmCvar_t cg_teamChatsOnly;
137 vmCvar_t cg_drawStatus;
138 vmCvar_t cg_animSpeed;
139 vmCvar_t cg_drawSpreadScale;
140 vmCvar_t cg_debugAnim;
141 vmCvar_t cg_debugPosition;
142 vmCvar_t cg_debugEvents;
143 vmCvar_t cg_errorDecay;
144 vmCvar_t cg_nopredict;
145 vmCvar_t cg_noPlayerAnims;
146 vmCvar_t cg_showmiss;
147 vmCvar_t cg_footsteps;
148 vmCvar_t cg_markTime;
149 vmCvar_t cg_brassTime;
150 vmCvar_t cg_viewsize;
151 vmCvar_t cg_letterbox;
152 vmCvar_t cg_drawGun;
153 vmCvar_t cg_drawFPGun;
154 vmCvar_t cg_drawGamemodels;
155 vmCvar_t cg_cursorHints;
156 vmCvar_t cg_hintFadeTime;       //----(SA)	added
157 vmCvar_t cg_gun_frame;
158 vmCvar_t cg_gun_x;
159 vmCvar_t cg_gun_y;
160 vmCvar_t cg_gun_z;
161 vmCvar_t cg_tracerChance;
162 vmCvar_t cg_tracerWidth;
163 vmCvar_t cg_tracerLength;
164 vmCvar_t cg_tracerSpeed;
165 vmCvar_t cg_autoswitch;
166 vmCvar_t cg_ignore;
167 vmCvar_t cg_simpleItems;
168 vmCvar_t cg_fov;
169 vmCvar_t cg_fixedAspect;
170 vmCvar_t cg_fixedAspectFOV;
171 vmCvar_t cg_oldWolfUI;
172 vmCvar_t cg_drawStatusHead;
173 vmCvar_t cg_zoomFov;
174 vmCvar_t cg_zoomStepBinoc;
175 vmCvar_t cg_zoomStepSniper;
176 vmCvar_t cg_zoomStepSnooper;
177 vmCvar_t cg_zoomStepFG;         //----(SA)	added
178 vmCvar_t cg_zoomDefaultBinoc;
179 vmCvar_t cg_zoomDefaultSniper;
180 vmCvar_t cg_zoomDefaultSnooper;
181 vmCvar_t cg_zoomDefaultFG;      //----(SA)	added
182 vmCvar_t cg_reticles;
183 vmCvar_t cg_reticleBrightness;      //----(SA)	added
184 vmCvar_t cg_thirdPerson;
185 vmCvar_t cg_thirdPersonRange;
186 vmCvar_t cg_thirdPersonAngle;
187 vmCvar_t cg_lagometer;
188 vmCvar_t cg_drawAttacker;
189 vmCvar_t cg_synchronousClients;
190 vmCvar_t cg_teamChatTime;
191 vmCvar_t cg_teamChatHeight;
192 vmCvar_t cg_stats;
193 vmCvar_t cg_buildScript;
194 vmCvar_t cg_forceModel;
195 vmCvar_t cg_coronafardist;
196 vmCvar_t cg_coronas;
197 vmCvar_t cg_paused;
198 vmCvar_t cg_blood;
199 vmCvar_t cg_predictItems;
200 vmCvar_t cg_deferPlayers;
201 vmCvar_t cg_drawTeamOverlay;
202 vmCvar_t cg_enableBreath;
203 vmCvar_t cg_autoactivate;
204 vmCvar_t cg_useSuggestedWeapons;    //----(SA)	added
205 vmCvar_t cg_emptyswitch;
206 vmCvar_t cg_particleDist;
207 vmCvar_t cg_particleLOD;
208 vmCvar_t cg_blinktime;      //----(SA)	added
209 
210 vmCvar_t cg_smoothClients;
211 vmCvar_t pmove_fixed;
212 vmCvar_t pmove_msec;
213 
214 // Rafael - particle switch
215 vmCvar_t cg_wolfparticles;
216 // done
217 
218 // Ridah
219 vmCvar_t cg_gameType;
220 vmCvar_t cg_bloodTime;
221 vmCvar_t cg_norender;
222 vmCvar_t cg_skybox;
223 
224 // Rafael
225 vmCvar_t cg_gameSkill;
226 // done
227 
228 vmCvar_t cg_reloading;      //----(SA)	added
229 
230 // JPW NERVE
231 vmCvar_t cg_medicChargeTime;
232 vmCvar_t cg_engineerChargeTime;
233 vmCvar_t cg_LTChargeTime;
234 vmCvar_t cg_soldierChargeTime;
235 vmCvar_t cg_redlimbotime;
236 vmCvar_t cg_bluelimbotime;
237 // jpw
238 
239 vmCvar_t cg_hunkUsed;
240 vmCvar_t cg_soundAdjust;
241 vmCvar_t cg_expectedhunkusage;
242 
243 vmCvar_t cg_showAIState;
244 
245 vmCvar_t cg_notebook;
246 vmCvar_t cg_notebookpages;          // bitflags for the currently accessable pages.  if they wanna cheat, let 'em.  Most won't, or will wait 'til they actually play it.
247 
248 vmCvar_t cg_currentSelectedPlayer;
249 vmCvar_t cg_currentSelectedPlayerName;
250 vmCvar_t cg_cameraMode;
251 vmCvar_t cg_cameraOrbit;
252 vmCvar_t cg_cameraOrbitDelay;
253 vmCvar_t cg_timescaleFadeEnd;
254 vmCvar_t cg_timescaleFadeSpeed;
255 vmCvar_t cg_timescale;
256 vmCvar_t cg_smallFont;
257 vmCvar_t cg_bigFont;
258 vmCvar_t cg_hudFiles;
259 
260 vmCvar_t cg_animState;
261 vmCvar_t cg_missionStats;
262 vmCvar_t cg_waitForFire;
263 
264 vmCvar_t cg_loadWeaponSelect;
265 
266 // NERVE - SMF - Wolf multiplayer configuration cvars
267 vmCvar_t mp_playerType;
268 vmCvar_t mp_team;
269 vmCvar_t mp_weapon;
270 vmCvar_t mp_pistol;
271 vmCvar_t mp_item1;
272 
273 vmCvar_t mp_item2;
274 vmCvar_t mp_mapDesc;
275 vmCvar_t mp_mapTitle;
276 vmCvar_t mp_itemDesc;
277 // -NERVE - SMF
278 
279 typedef struct {
280 	vmCvar_t    *vmCvar;
281 	char        *cvarName;
282 	char        *defaultString;
283 	int cvarFlags;
284 } cvarTable_t;
285 
286 cvarTable_t cvarTable[] = {
287 	{ &cg_ignore, "cg_ignore", "0", 0 },  // used for debugging
288 	{ &cg_autoswitch, "cg_autoswitch", "2", CVAR_ARCHIVE },
289 	{ &cg_drawGun, "cg_drawGun", "1", CVAR_ARCHIVE },
290 	{ &cg_drawGamemodels, "cg_drawGamemodels", "1", CVAR_CHEAT },
291 	{ &cg_drawFPGun, "cg_drawFPGun", "1", CVAR_ARCHIVE },
292 	{ &cg_gun_frame, "cg_gun_frame", "0", CVAR_TEMP },
293 	{ &cg_cursorHints, "cg_cursorHints", "1", CVAR_ARCHIVE },
294 	{ &cg_hintFadeTime, "cg_hintFadeTime", "500", CVAR_ARCHIVE }, //----(SA)	added
295 	{ &cg_zoomFov, "cg_zoomfov", "22.5", CVAR_ARCHIVE },
296 	{ &cg_zoomDefaultBinoc, "cg_zoomDefaultBinoc", "22.5", CVAR_ARCHIVE },
297 	{ &cg_zoomDefaultSniper, "cg_zoomDefaultSniper", "15", CVAR_ARCHIVE },
298 	{ &cg_zoomDefaultSnooper, "cg_zoomDefaultSnooper", "40", CVAR_ARCHIVE },
299 	{ &cg_zoomDefaultFG, "cg_zoomDefaultFG", "55", CVAR_ARCHIVE },                //----(SA)	added
300 	{ &cg_zoomStepBinoc, "cg_zoomStepBinoc", "3", CVAR_ARCHIVE },
301 	{ &cg_zoomStepSniper, "cg_zoomStepSniper", "2", CVAR_ARCHIVE },
302 	{ &cg_zoomStepSnooper, "cg_zoomStepSnooper", "5", CVAR_ARCHIVE },
303 	{ &cg_zoomStepFG, "cg_zoomStepFG", "10", CVAR_ARCHIVE },          //----(SA)	added
304 	{ &cg_fov, "cg_fov", "90", CVAR_ARCHIVE },	// NOTE: there is already a dmflag (DF_FIXED_FOV) to allow server control of this cheat
305 	{ &cg_fixedAspect, "cg_fixedAspect", "0", CVAR_ARCHIVE | CVAR_LATCH }, // Essentially the same as setting DF_FIXED_FOV for widescreen aspects
306 	{ &cg_fixedAspectFOV, "cg_fixedAspectFOV", "1", CVAR_ARCHIVE },
307 	{ &cg_oldWolfUI, "cg_oldWolfUI", "0", CVAR_ARCHIVE },
308 	{ &cg_drawStatusHead, "cg_drawStatusHead", "0", CVAR_ARCHIVE },
309 	{ &cg_viewsize, "cg_viewsize", "100", CVAR_ARCHIVE },
310 	{ &cg_letterbox, "cg_letterbox", "0", CVAR_TEMP },    //----(SA)	added
311 	{ &cg_shadows, "cg_shadows", "1", CVAR_ARCHIVE  },
312 	{ &cg_gibs, "cg_gibs", "1", CVAR_ARCHIVE  },
313 	{ &cg_draw2D, "cg_draw2D", "1", CVAR_ARCHIVE  },
314 	{ &cg_drawSpreadScale, "cg_drawSpreadScale", "1", CVAR_ARCHIVE },
315 	{ &cg_drawFrags, "cg_drawFrags", "1", CVAR_ARCHIVE },
316 	{ &cg_drawStatus, "cg_drawStatus", "1", CVAR_ARCHIVE  },
317 	{ &cg_drawTimer, "cg_drawTimer", "0", CVAR_ARCHIVE  },
318 	{ &cg_drawFPS, "cg_drawFPS", "0", CVAR_ARCHIVE  },
319 	{ &cg_drawSnapshot, "cg_drawSnapshot", "0", CVAR_ARCHIVE  },
320 	{ &cg_draw3dIcons, "cg_draw3dIcons", "1", CVAR_ARCHIVE  },
321 	{ &cg_drawIcons, "cg_drawIcons", "1", CVAR_ARCHIVE  },
322 	{ &cg_drawAmmoWarning, "cg_drawAmmoWarning", "1", CVAR_ARCHIVE  },
323 	{ &cg_drawAttacker, "cg_drawAttacker", "1", CVAR_ARCHIVE  },
324 	{ &cg_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE },
325 	{ &cg_drawCrosshairBinoc, "cg_drawCrosshairBinoc", "0", CVAR_ARCHIVE },
326 	{ &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE },
327 	{ &cg_drawCrosshairPickups, "cg_drawCrosshairPickups", "1", CVAR_ARCHIVE },
328 	{ &cg_drawCrosshairReticle, "cg_drawCrosshairReticle", "1", CVAR_ARCHIVE },
329 	{ &cg_drawRewards, "cg_drawRewards", "1", CVAR_ARCHIVE },
330 	{ &cg_hudAlpha, "cg_hudAlpha", "0.8", CVAR_ARCHIVE },
331 	{ &cg_useWeapsForZoom,  "cg_useWeapsForZoom", "1", CVAR_ARCHIVE },
332 	{ &cg_weaponCycleDelay, "cg_weaponCycleDelay", "150", CVAR_ARCHIVE }, //----(SA)	added
333 	{ &cg_cycleAllWeaps,    "cg_cycleAllWeaps", "1", CVAR_ARCHIVE },
334 	{ &cg_drawAllWeaps,     "cg_drawAllWeaps",   "1", CVAR_ARCHIVE },
335 	{ &cg_crosshairSize, "cg_crosshairSize", "24", CVAR_ARCHIVE },
336 	{ &cg_crosshairAlpha, "cg_crosshairAlpha", "0.5", CVAR_ARCHIVE }, //----(SA)	added
337 	{ &cg_crosshairHealth, "cg_crosshairHealth", "1", CVAR_ARCHIVE },
338 	{ &cg_crosshairX, "cg_crosshairX", "0", CVAR_ARCHIVE },
339 	{ &cg_crosshairY, "cg_crosshairY", "0", CVAR_ARCHIVE },
340 	{ &cg_brassTime, "cg_brassTime", "1250", CVAR_ARCHIVE },
341 	{ &cg_simpleItems, "cg_simpleItems", "0", CVAR_ARCHIVE },
342 	{ &cg_reticles, "cg_reticles", "1", CVAR_CHEAT },
343 	{ &cg_reticleBrightness, "cg_reticleBrightness", "0.7", CVAR_ARCHIVE },
344 	{ &cg_markTime, "cg_marktime", "20000", CVAR_ARCHIVE },
345 	{ &cg_lagometer, "cg_lagometer", "0", CVAR_ARCHIVE },
346 	{ &cg_railTrailTime, "cg_railTrailTime", "400", CVAR_ARCHIVE  },
347 	{ &cg_gun_x, "cg_gunX", "0", CVAR_CHEAT },
348 	{ &cg_gun_y, "cg_gunY", "0", CVAR_CHEAT },
349 	{ &cg_gun_z, "cg_gunZ", "0", CVAR_CHEAT },
350 	{ &cg_centertime, "cg_centertime", "3", CVAR_CHEAT },
351 	{ &cg_runpitch, "cg_runpitch", "0.002", CVAR_ARCHIVE},
352 	{ &cg_runroll, "cg_runroll", "0.005", CVAR_ARCHIVE },
353 	{ &cg_bobup, "cg_bobup", "0.005", CVAR_ARCHIVE },
354 	{ &cg_bobpitch, "cg_bobpitch", "0.002", CVAR_ARCHIVE },
355 	{ &cg_bobroll, "cg_bobroll", "0.002", CVAR_ARCHIVE },
356 
357 	// JOSEPH 10-27-99
358 	{ &cg_autoactivate, "cg_autoactivate", "1", CVAR_ARCHIVE },
359 	{ &cg_emptyswitch, "cg_emptyswitch", "0", CVAR_ARCHIVE },
360 	// END JOSEPH
361 
362 //----(SA)	added
363 	{ &cg_particleDist, "cg_particleDist", "1024", CVAR_ARCHIVE },
364 	{ &cg_particleLOD, "cg_particleLOD", "0", CVAR_ARCHIVE },
365 	{ &cg_useSuggestedWeapons, "cg_useSuggestedWeapons", "1", CVAR_ARCHIVE }, //----(SA)	added
366 //----(SA)	end
367 
368 	// Ridah, more fluid rotations
369 	{ &cg_swingSpeed, "cg_swingSpeed", "0.1", CVAR_CHEAT },   // was 0.3 for Q3
370 	{ &cg_bloodTime, "cg_bloodTime", "120", CVAR_ARCHIVE },
371 	{ &cg_hunkUsed, "com_hunkUsed", "0", 0 },
372 	{ &cg_soundAdjust, "hunk_soundadjust", "0", 0 },
373 
374 	{ &cg_skybox, "cg_skybox", "1", CVAR_CHEAT },
375 	// done.
376 
377 	{ &cg_animSpeed, "cg_animspeed", "1", CVAR_CHEAT },
378 	{ &cg_debugAnim, "cg_debuganim", "0", CVAR_CHEAT },
379 	{ &cg_debugPosition, "cg_debugposition", "0", CVAR_CHEAT },
380 	{ &cg_debugEvents, "cg_debugevents", "0", CVAR_CHEAT },
381 	{ &cg_errorDecay, "cg_errordecay", "100", 0 },
382 	{ &cg_nopredict, "cg_nopredict", "0", 0 },
383 	{ &cg_noPlayerAnims, "cg_noplayeranims", "0", CVAR_CHEAT },
384 	{ &cg_showmiss, "cg_showmiss", "0", 0 },
385 	{ &cg_footsteps, "cg_footsteps", "1", CVAR_CHEAT },
386 	{ &cg_tracerChance, "cg_tracerchance", "0.4", CVAR_CHEAT },
387 	{ &cg_tracerWidth, "cg_tracerwidth", "0.8", CVAR_CHEAT },
388 	{ &cg_tracerSpeed, "cg_tracerSpeed", "4500", CVAR_CHEAT },
389 	{ &cg_tracerLength, "cg_tracerlength", "160", CVAR_CHEAT },
390 	{ &cg_thirdPersonRange, "cg_thirdPersonRange", "40", 0 },
391 	{ &cg_thirdPersonAngle, "cg_thirdPersonAngle", "0", CVAR_CHEAT },
392 	{ &cg_thirdPerson, "cg_thirdPerson", "0", 0 },
393 	{ &cg_teamChatTime, "cg_teamChatTime", "3000", CVAR_ARCHIVE  },
394 	{ &cg_teamChatHeight, "cg_teamChatHeight", "8", CVAR_ARCHIVE  },
395 	{ &cg_forceModel, "cg_forceModel", "0", CVAR_ARCHIVE  },
396 	{ &cg_coronafardist, "cg_coronafardist", "1536", CVAR_ARCHIVE },
397 	{ &cg_coronas, "cg_coronas", "1", CVAR_ARCHIVE },
398 	{ &cg_predictItems, "cg_predictItems", "1", CVAR_ARCHIVE },
399 	{ &cg_deferPlayers, "cg_deferPlayers", "1", CVAR_ARCHIVE },
400 	{ &cg_drawTeamOverlay, "cg_drawTeamOverlay", "0", CVAR_ARCHIVE },
401 	{ &cg_stats, "cg_stats", "0", 0 },
402 	{ &cg_blinktime, "cg_blinktime", "100", CVAR_ARCHIVE},         //----(SA)	added
403 
404 	{ &cg_enableBreath, "g_enableBreath", "1", CVAR_SERVERINFO},
405 	{ &cg_cameraOrbit, "cg_cameraOrbit", "0", CVAR_CHEAT},
406 	{ &cg_cameraOrbitDelay, "cg_cameraOrbitDelay", "50", CVAR_ARCHIVE},
407 	{ &cg_timescaleFadeEnd, "cg_timescaleFadeEnd", "1", 0},
408 	{ &cg_timescaleFadeSpeed, "cg_timescaleFadeSpeed", "0", 0},
409 	{ &cg_timescale, "timescale", "1", 0},
410 //	{ &cg_smoothClients, "cg_smoothClients", "0", CVAR_USERINFO | CVAR_ARCHIVE},
411 	{ &cg_cameraMode, "com_cameraMode", "0", CVAR_CHEAT},
412 
413 	{ &pmove_fixed, "pmove_fixed", "0", CVAR_SYSTEMINFO},
414 	{ &pmove_msec, "pmove_msec", "8", CVAR_SYSTEMINFO},
415 	{ &cg_smallFont, "ui_smallFont", "0.25", CVAR_ARCHIVE},
416 	{ &cg_bigFont, "ui_bigFont", "0.4", CVAR_ARCHIVE},
417 	{ &cg_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE},
418 
419 	{ &cg_teamChatsOnly, "cg_teamChatsOnly", "0", CVAR_ARCHIVE },
420 	// the following variables are created in other parts of the system,
421 	// but we also reference them here
422 
423 	{ &cg_buildScript, "com_buildScript", "0", 0 },   // force loading of all possible data amd error on failures
424 	{ &cg_paused, "cl_paused", "0", CVAR_ROM },
425 
426 	{ &cg_blood, "com_blood", "1", CVAR_ARCHIVE },
427 	{ &cg_synchronousClients, "g_synchronousClients", "0", CVAR_SYSTEMINFO },
428 	{ &cg_currentSelectedPlayer, "cg_currentSelectedPlayer", "0", CVAR_ARCHIVE},
429 	{ &cg_currentSelectedPlayerName, "cg_currentSelectedPlayerName", "", CVAR_ARCHIVE},
430 
431 	// Rafael - particle switch
432 	{ &cg_wolfparticles, "cg_wolfparticles", "1", CVAR_ARCHIVE },
433 	// done
434 
435 	// Ridah
436 	{ &cg_gameType, "g_gametype", "0", 0 }, // communicated by systeminfo
437 	{ &cg_norender, "cg_norender", "0", 0 },  // only used during single player, to suppress rendering until the server is ready
438 
439 	{ &cg_gameSkill, "g_gameskill", "2", 0 }, // communicated by systeminfo	// (SA) new default '2' (was '1')
440 
441 	{ &cg_reloading, "g_reloading", "0", 0 }, //----(SA)	added
442 
443 	// JPW NERVE
444 	{ &cg_medicChargeTime,  "g_medicChargeTime", "10000", 0 }, // communicated by systeminfo
445 	{ &cg_LTChargeTime, "g_LTChargeTime", "30000", 0 }, // communicated by systeminfo
446 	{ &cg_engineerChargeTime,   "g_engineerChargeTime", "30000", 0 }, // communicated by systeminfo
447 	{ &cg_soldierChargeTime,    "g_soldierChargeTime", "20000", 0 }, // communicated by systeminfo
448 	{ &cg_bluelimbotime,        "g_bluelimbotime", "30000", 0 }, // communicated by systeminfo
449 	{ &cg_redlimbotime,         "g_redlimbotime", "30000", 0 }, // communicated by systeminfo
450 	// jpw
451 
452 	{ &cg_notebook, "cl_notebook", "0", CVAR_ROM },
453 	{ &cg_notebookpages, "cg_notebookpages", "0", CVAR_ROM},
454 //	{ &cg_youGotMail, "cg_youGotMail", "0", CVAR_ROM},	// used to display notebook new-info icon
455 	{ &cg_youGotMail, "cg_youGotMail", "0", 0},   // used to display notebook new-info icon
456 
457 	{ &cg_animState, "cg_animState", "0", CVAR_CHEAT},
458 	{ &cg_missionStats, "g_missionStats", "0", CVAR_ROM},
459 	{ &cg_waitForFire, "cl_waitForFire", "0", CVAR_ROM},
460 
461 	{ &cg_loadWeaponSelect, "cg_loadWeaponSelect", "0", CVAR_ROM},
462 
463 	{ &cg_expectedhunkusage, "com_expectedhunkusage", "0", CVAR_ROM},
464 
465 	// NERVE - SMF
466 	{ &mp_playerType, "mp_playerType", "0", 0 },
467 	{ &mp_team, "mp_team", "0", 0 },
468 	{ &mp_weapon, "mp_weapon", "0", 0 },
469 	{ &mp_pistol, "mp_pistol", "0", 0 },
470 	{ &mp_item1, "mp_item1", "0", 0 },
471 
472 	{ &mp_item2, "mp_item2", "0", 0 },
473 	{ &mp_mapDesc, "mp_mapDesc", "", 0 },
474 	{ &mp_mapTitle, "mp_mapTitle", "", 0 },
475 	{ &mp_itemDesc, "mp_itemDesc", "", 0 },
476 	// -NERVE - SMF
477 
478 	{ &cg_showAIState, "cg_showAIState", "0", CVAR_CHEAT},
479 };
480 int cvarTableSize = ARRAY_LEN( cvarTable );
481 
482 /*
483 =================
484 CG_RegisterCvars
485 =================
486 */
CG_RegisterCvars(void)487 void CG_RegisterCvars( void ) {
488 	int i;
489 	cvarTable_t *cv;
490 	char var[MAX_TOKEN_CHARS];
491 
492 	trap_Cvar_Set( "cg_letterbox", "0" ); // force this for people who might have it in their
493 
494 	for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
495 		trap_Cvar_Register( cv->vmCvar, cv->cvarName,
496 							cv->defaultString, cv->cvarFlags );
497 	}
498 
499 	// see if we are also running the server on this machine
500 	trap_Cvar_VariableStringBuffer( "sv_running", var, sizeof( var ) );
501 	cgs.localServer = atoi( var );
502 
503 	forceModelModificationCount = cg_forceModel.modificationCount;
504 
505 	trap_Cvar_Register( NULL, "model", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
506 	trap_Cvar_Register( NULL, "head", DEFAULT_HEAD, CVAR_USERINFO | CVAR_ARCHIVE );
507 
508 
509 }
510 
511 /*
512 ===================
513 CG_ForceModelChange
514 ===================
515 */
516 /*
517 static void CG_ForceModelChange( void ) {
518 	int	i;
519 
520 	for ( i = 0 ; i < MAX_CLIENTS ; i++ ) {
521 		const char      *clientInfo;
522 
523 		clientInfo = CG_ConfigString( CS_PLAYERS + i );
524 		if ( !clientInfo[0] ) {
525 			continue;
526 		}
527 		CG_NewClientInfo( i );
528 	}
529 }
530 */
531 
532 /*
533 =================
534 CG_UpdateCvars
535 =================
536 */
CG_UpdateCvars(void)537 void CG_UpdateCvars( void ) {
538 	int i;
539 	cvarTable_t *cv;
540 
541 	for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
542 		trap_Cvar_Update( cv->vmCvar );
543 	}
544 
545 /* RF, disabled this, not needed anymore
546 	// if force model changed
547 	if ( forceModelModificationCount != cg_forceModel.modificationCount ) {
548 		forceModelModificationCount = cg_forceModel.modificationCount;
549 		CG_ForceModelChange();
550 	}
551 */
552 
553 }
554 
555 
CG_CrosshairPlayer(void)556 int CG_CrosshairPlayer( void ) {
557 	if ( cg.time > ( cg.crosshairClientTime + 1000 ) ) {
558 		return -1;
559 	}
560 	return cg.crosshairClientNum;
561 }
562 
CG_LastAttacker(void)563 int CG_LastAttacker( void ) {
564 	if ( !cg.attackerTime ) {
565 		return -1;
566 	}
567 	return cg.snap->ps.persistant[PERS_ATTACKER];
568 }
569 
CG_Printf(const char * msg,...)570 void QDECL CG_Printf( const char *msg, ... ) {
571 	va_list argptr;
572 	char text[1024];
573 
574 	va_start( argptr, msg );
575 	Q_vsnprintf( text, sizeof( text ), msg, argptr );
576 	va_end( argptr );
577 
578 	trap_Print( text );
579 }
580 
CG_Error(const char * msg,...)581 void QDECL CG_Error( const char *msg, ... ) {
582 	va_list argptr;
583 	char text[1024];
584 
585 	va_start( argptr, msg );
586 	Q_vsnprintf( text, sizeof( text ), msg, argptr );
587 	va_end( argptr );
588 
589 	trap_Error( text );
590 }
591 
Com_Error(int level,const char * error,...)592 void QDECL Com_Error( int level, const char *error, ... ) {
593 	va_list argptr;
594 	char text[1024];
595 
596 	va_start( argptr, error );
597 	Q_vsnprintf( text, sizeof( text ), error, argptr );
598 	va_end( argptr );
599 
600 	trap_Error( text );
601 }
602 
Com_Printf(const char * msg,...)603 void QDECL Com_Printf( const char *msg, ... ) {
604 	va_list argptr;
605 	char text[1024];
606 
607 	va_start( argptr, msg );
608 	Q_vsnprintf( text, sizeof( text ), msg, argptr );
609 	va_end( argptr );
610 
611 	trap_Print( text );
612 }
613 
614 /*
615 ================
616 CG_Argv
617 ================
618 */
CG_Argv(int arg)619 const char *CG_Argv( int arg ) {
620 	static char buffer[MAX_STRING_CHARS];
621 
622 	trap_Argv( arg, buffer, sizeof( buffer ) );
623 
624 	return buffer;
625 }
626 
627 
628 //========================================================================
CG_SetupDlightstyles(void)629 void CG_SetupDlightstyles( void ) {
630 	int i, j;
631 	char        *str;
632 	char        *token;
633 	int entnum;
634 	centity_t   *cent;
635 
636 	cg.lightstylesInited = qtrue;
637 
638 	for ( i = 1; i < MAX_DLIGHT_CONFIGSTRINGS; i++ )
639 	{
640 		str = (char *) CG_ConfigString( CS_DLIGHTS + i );
641 		if ( !strlen( str ) ) {
642 			break;
643 		}
644 
645 		token = COM_Parse( &str );   // ent num
646 		entnum = atoi( token );
647 		cent = &cg_entities[entnum];
648 
649 		token = COM_Parse( &str );   // stylestring
650 		Q_strncpyz( cent->dl_stylestring, token, strlen( token ) );
651 
652 		token = COM_Parse( &str );   // offset
653 		cent->dl_frame      = atoi( token );
654 		cent->dl_oldframe   = cent->dl_frame - 1;
655 		if ( cent->dl_oldframe < 0 ) {
656 			cent->dl_oldframe = strlen( cent->dl_stylestring );
657 		}
658 
659 		token = COM_Parse( &str );   // sound id
660 		cent->dl_sound = atoi( token );
661 
662 		token = COM_Parse( &str );   // attenuation
663 		cent->dl_atten = atoi( token );
664 
665 		for ( j = 0; j < strlen( cent->dl_stylestring ); j++ ) {
666 
667 			cent->dl_stylestring[j] += cent->dl_atten;  // adjust character for attenuation/amplification
668 
669 			// clamp result
670 			if ( cent->dl_stylestring[j] < 'a' ) {
671 				cent->dl_stylestring[j] = 'a';
672 			}
673 			if ( cent->dl_stylestring[j] > 'z' ) {
674 				cent->dl_stylestring[j] = 'z';
675 			}
676 		}
677 
678 		cent->dl_backlerp   = 0.0;
679 		cent->dl_time       = cg.time;
680 	}
681 
682 }
683 
684 //========================================================================
685 
686 /*
687 =================
688 CG_RegisterItemSounds
689 
690 The server says this item is used on this level
691 =================
692 */
CG_RegisterItemSounds(int itemNum)693 static void CG_RegisterItemSounds( int itemNum ) {
694 	gitem_t         *item;
695 	char data[MAX_QPATH];
696 	char            *s, *start;
697 	int len;
698 
699 	item = &bg_itemlist[ itemNum ];
700 
701 	if ( item->pickup_sound ) {
702 		trap_S_RegisterSound( item->pickup_sound );
703 	}
704 
705 	// parse the space seperated precache string for other media
706 	s = item->sounds;
707 	if ( !s || !s[0] ) {
708 		return;
709 	}
710 
711 	while ( *s ) {
712 		start = s;
713 		while ( *s && *s != ' ' ) {
714 			s++;
715 		}
716 
717 		len = s - start;
718 		if ( len >= MAX_QPATH || len < 5 ) {
719 			CG_Error( "PrecacheItem: %s has bad precache string",
720 					  item->classname );
721 			return;
722 		}
723 		memcpy( data, start, len );
724 		data[len] = 0;
725 		if ( *s ) {
726 			s++;
727 		}
728 
729 		if ( !strcmp( data + len - 3, "wav" ) ) {
730 			trap_S_RegisterSound( data );
731 		}
732 	}
733 }
734 
735 
736 //----(SA)	added
737 
738 // this is the only thing that sets a cap on # items.  would like it to be adaptable.
739 // (rather than 256 max items with pickup name fixed at 32 chars)
740 
741 /*
742 ==============
743 CG_LoadPickupNames
744 ==============
745 */
746 #define MAX_BUFFER          20000
CG_LoadPickupNames(void)747 static void CG_LoadPickupNames( void ) {
748 	char buffer[MAX_BUFFER];
749 	char *text;
750 	char filename[MAX_QPATH];
751 	fileHandle_t f;
752 	int len, i;
753 	char *token;
754 
755 	Com_sprintf( filename, MAX_QPATH, "text/pickupnames.txt" );
756 	len = trap_FS_FOpenFile( filename, &f, FS_READ );
757 	if ( len <= 0 ) {
758 		CG_Printf( S_COLOR_RED "WARNING: pickup name file (pickupnames.txt not found in main/text)\n" );
759 		return;
760 	}
761 	if ( len > MAX_BUFFER ) {
762 		CG_Error( "%s is too big, make it smaller (max = %i bytes)\n", filename, MAX_BUFFER );
763 	}
764 
765 	// load the file into memory
766 	trap_FS_Read( buffer, len, f );
767 	buffer[len] = 0;
768 	trap_FS_FCloseFile( f );
769 	// parse the list
770 	text = buffer;
771 
772 	for ( i = 0; i < bg_numItems; i++ ) {
773 		token = COM_ParseExt( &text, qtrue );
774 		if ( !token[0] ) {
775 			break;
776 		}
777 		if ( !Q_stricmp( token, "---" ) ) {   // no name.  use hardcoded value
778 			if ( bg_itemlist[i].pickup_name && strlen( bg_itemlist[i].pickup_name ) ) {
779 				Com_sprintf( cgs.itemPrintNames[i], MAX_QPATH, "%s", bg_itemlist[ i ].pickup_name );
780 			} else {
781 				cgs.itemPrintNames[i][0] = 0;
782 			}
783 		} else {
784 			Com_sprintf( cgs.itemPrintNames[i], MAX_QPATH, "%s", token );
785 		}
786 	}
787 }
788 
789 // a straight dupe right now so I don't mess anything up while adding this
CG_LoadTranslationStrings(void)790 static void CG_LoadTranslationStrings( void ) {
791 	char buffer[MAX_BUFFER];
792 	char *text;
793 	char filename[MAX_QPATH];
794 	fileHandle_t f;
795 	int len, i, numStrings;
796 	char *token;
797 
798 	Com_sprintf( filename, MAX_QPATH, "text/strings.txt" );
799 	len = trap_FS_FOpenFile( filename, &f, FS_READ );
800 	if ( len <= 0 ) {
801 		CG_Printf( S_COLOR_RED "WARNING: string translation file (strings.txt not found in main/text)\n" );
802 		return;
803 	}
804 	if ( len > MAX_BUFFER ) {
805 		CG_Error( "%s is too big, make it smaller (max = %i bytes)\n", filename, MAX_BUFFER );
806 	}
807 
808 	// load the file into memory
809 	trap_FS_Read( buffer, len, f );
810 	buffer[len] = 0;
811 	trap_FS_FCloseFile( f );
812 	// parse the list
813 	text = buffer;
814 
815 	numStrings = sizeof( translateStrings ) / sizeof( translateStrings[0] ) - 1;
816 
817 	for ( i = 0; i < numStrings; i++ ) {
818 		token = COM_ParseExt( &text, qtrue );
819 		if ( !token[0] ) {
820 			break;
821 		}
822 #ifdef Q3_VM // new IORTCW syscall (works for qvms and dlls), but have dlls use vanilla rtcw compatible code
823 		translateStrings[i].localname = (char *)trap_Alloc( strlen( token ) + 1 );
824 #else
825 		translateStrings[i].localname = (char *)malloc( strlen( token ) + 1 );
826 #endif
827 		strcpy( translateStrings[i].localname, token );
828 	}
829 }
830 
831 
CG_LoadTranslateStrings(void)832 static void CG_LoadTranslateStrings( void ) {
833 	CG_LoadPickupNames();
834 	CG_LoadTranslationStrings();    // right now just centerprint
835 }
836 
837 //----(SA)	end
838 
839 
840 /*
841 =================
842 CG_RegisterSounds
843 
844 called during a precache command
845 =================
846 */
CG_RegisterSounds(void)847 static void CG_RegisterSounds( void ) {
848 	int i;
849 	char items[MAX_ITEMS + 1];
850 	char name[MAX_QPATH];
851 	const char  *soundName;
852 
853 	// Ridah, init sound scripts
854 	CG_SoundInit();
855 	// done.
856 
857 	cgs.media.n_health = trap_S_RegisterSound( "sound/items/n_health.wav" );
858 	cgs.media.noFireUnderwater = trap_S_RegisterSound( "sound/weapons/underwaterfire.wav" ); //----(SA)	added
859 
860 	cgs.media.snipersound = trap_S_RegisterSound( "sound/weapons/mauser/mauserf1.wav" );
861 	cgs.media.tracerSound = trap_S_RegisterSound( "sound/weapons/machinegun/buletby1.wav" );
862 	cgs.media.selectSound = trap_S_RegisterSound( "sound/weapons/change.wav" );
863 	cgs.media.wearOffSound = trap_S_RegisterSound( "sound/items/wearoff.wav" );
864 	cgs.media.useNothingSound = trap_S_RegisterSound( "sound/items/use_nothing.wav" );
865 	cgs.media.gibSound = trap_S_RegisterSound( "sound/player/gibsplt1.wav" );
866 	cgs.media.gibBounce1Sound = trap_S_RegisterSound( "sound/player/gibimp1.wav" );
867 	cgs.media.gibBounce2Sound = trap_S_RegisterSound( "sound/player/gibimp2.wav" );
868 	cgs.media.gibBounce3Sound = trap_S_RegisterSound( "sound/player/gibimp3.wav" );
869 
870 //	cgs.media.teleInSound = trap_S_RegisterSound( "sound/world/telein.wav" );
871 //	cgs.media.teleOutSound = trap_S_RegisterSound( "sound/world/teleout.wav" );
872 //	cgs.media.respawnSound = trap_S_RegisterSound( "sound/items/respawn1.wav" );
873 
874 
875 	cgs.media.grenadebounce[GRENBOUNCE_DEFAULT][0]  = trap_S_RegisterSound( "sound/weapons/grenade/hgrenb1a.wav" );
876 	cgs.media.grenadebounce[GRENBOUNCE_DEFAULT][1]  = trap_S_RegisterSound( "sound/weapons/grenade/hgrenb2a.wav" );
877 	cgs.media.grenadebounce[GRENBOUNCE_DIRT][0]     = trap_S_RegisterSound( "sound/weapons/grenade/hg_dirt1a.wav" );
878 	cgs.media.grenadebounce[GRENBOUNCE_DIRT][1]     = trap_S_RegisterSound( "sound/weapons/grenade/hg_dirt2a.wav" );
879 	cgs.media.grenadebounce[GRENBOUNCE_WOOD][0]     = trap_S_RegisterSound( "sound/weapons/grenade/hg_wood1a.wav" );
880 	cgs.media.grenadebounce[GRENBOUNCE_WOOD][1]     = trap_S_RegisterSound( "sound/weapons/grenade/hg_wood2a.wav" );
881 	cgs.media.grenadebounce[GRENBOUNCE_METAL][0]    = trap_S_RegisterSound( "sound/weapons/grenade/hg_metal1a.wav" );
882 	cgs.media.grenadebounce[GRENBOUNCE_METAL][1]    = trap_S_RegisterSound( "sound/weapons/grenade/hg_metal2a.wav" );
883 
884 	cgs.media.dynamitebounce1 = trap_S_RegisterSound( "sound/weapons/dynamite/dynamite_bounce.wav" );
885 
886 	cgs.media.fbarrelexp1 = trap_S_RegisterSound( "sound/weapons/flamebarrel/fbarrela.wav" );
887 	cgs.media.fbarrelexp2 = trap_S_RegisterSound( "sound/weapons/flamebarrel/fbarrelb.wav" );
888 
889 	cgs.media.fkickwall = trap_S_RegisterSound( "sound/weapons/melee/fstatck.wav" );
890 	cgs.media.fkickflesh = trap_S_RegisterSound( "sound/weapons/melee/fstatck.wav" );
891 	cgs.media.fkickmiss = trap_S_RegisterSound( "sound/weapons/melee/fstmiss.wav" );
892 
893 	cgs.media.noAmmoSound = trap_S_RegisterSound( "sound/weapons/noammo.wav" );
894 
895 	cgs.media.talkSound = trap_S_RegisterSound( "sound/player/talk.wav" );
896 	cgs.media.landSound = trap_S_RegisterSound( "sound/player/land1.wav" );
897 
898 	cgs.media.watrInSound = trap_S_RegisterSound( "sound/player/watr_in.wav" );
899 	cgs.media.watrOutSound = trap_S_RegisterSound( "sound/player/watr_out.wav" );
900 	cgs.media.watrUnSound = trap_S_RegisterSound( "sound/player/watr_un.wav" );
901 
902 	cgs.media.underWaterSound = trap_S_RegisterSound( "sound/world/underwater03.wav" );
903 
904 	for ( i = 0 ; i < 4 ; i++ ) {
905 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/step%i.wav", i + 1 );
906 		cgs.media.footsteps[FOOTSTEP_NORMAL][i] = trap_S_RegisterSound( name );
907 
908 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/boot%i.wav", i + 1 );
909 		cgs.media.footsteps[FOOTSTEP_BOOT][i] = trap_S_RegisterSound( name );
910 
911 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/flesh%i.wav", i + 1 );
912 		cgs.media.footsteps[FOOTSTEP_FLESH][i] = trap_S_RegisterSound( name );
913 
914 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/mech%i.wav", i + 1 );
915 		cgs.media.footsteps[FOOTSTEP_MECH][i] = trap_S_RegisterSound( name );
916 
917 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/energy%i.wav", i + 1 );
918 		cgs.media.footsteps[FOOTSTEP_ENERGY][i] = trap_S_RegisterSound( name );
919 
920 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/splash%i.wav", i + 1 );
921 		cgs.media.footsteps[FOOTSTEP_SPLASH][i] = trap_S_RegisterSound( name );
922 
923 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/clank%i.wav", i + 1 );
924 		cgs.media.footsteps[FOOTSTEP_METAL][i] = trap_S_RegisterSound( name );
925 
926 
927 		// (SA) Wolf footstep sound registration
928 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/wood%i.wav", i + 1 );
929 		cgs.media.footsteps[FOOTSTEP_WOOD][i] = trap_S_RegisterSound( name );
930 
931 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/grass%i.wav", i + 1 );
932 		cgs.media.footsteps[FOOTSTEP_GRASS][i] = trap_S_RegisterSound( name );
933 
934 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/gravel%i.wav", i + 1 );
935 		cgs.media.footsteps[FOOTSTEP_GRAVEL][i] = trap_S_RegisterSound( name );
936 
937 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/roof%i.wav", i + 1 );
938 		cgs.media.footsteps[FOOTSTEP_ROOF][i] = trap_S_RegisterSound( name );
939 
940 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/snow%i.wav", i + 1 );
941 		cgs.media.footsteps[FOOTSTEP_SNOW][i] = trap_S_RegisterSound( name );
942 
943 		Com_sprintf( name, sizeof( name ), "sound/player/footsteps/carpet%i.wav", i + 1 );    //----(SA)
944 		cgs.media.footsteps[FOOTSTEP_CARPET][i] = trap_S_RegisterSound( name );
945 	}
946 
947 	// only register the items that the server says we need
948 	Q_strncpyz(items, CG_ConfigString(CS_ITEMS), sizeof(items));
949 
950 	for ( i = 1 ; i < bg_numItems ; i++ ) {
951 		if ( items[ i ] == '1' || cg_buildScript.integer ) {
952 			CG_RegisterItemSounds( i );
953 		}
954 	}
955 
956 	for ( i = 1 ; i < MAX_SOUNDS ; i++ ) {
957 		soundName = CG_ConfigString( CS_SOUNDS + i );
958 		if ( !soundName[0] ) {
959 			break;
960 		}
961 		if ( soundName[0] == '*' ) {
962 			continue;   // custom sound
963 		}
964 
965 		// Ridah, register sound scripts seperately
966 		if ( !strstr( soundName, ".wav" ) ) {
967 			cgs.gameSounds[i] = CG_SoundScriptPrecache( soundName );    //----(SA)	shouldn't this be okay?  The cs index is reserved anyway, so it can't hurt, right?
968 			cgs.gameSoundTypes[i] = 2;
969 		} else {
970 			cgs.gameSounds[i] = trap_S_RegisterSound( soundName );
971 			cgs.gameSoundTypes[i] = 1;
972 		}
973 	}
974 
975 	//----(SA)	added
976 	cgs.media.grenadePulseSound4 = trap_S_RegisterSound( "sound/weapons/grenade/grenpulse4.wav" );
977 	cgs.media.grenadePulseSound3 = trap_S_RegisterSound( "sound/weapons/grenade/grenpulse3.wav" );
978 	cgs.media.grenadePulseSound2 = trap_S_RegisterSound( "sound/weapons/grenade/grenpulse2.wav" );
979 	cgs.media.grenadePulseSound1 = trap_S_RegisterSound( "sound/weapons/grenade/grenpulse1.wav" );
980 	//----(SA)	end
981 
982 	//----(SA) added
983 	cgs.media.debBounce1Sound = trap_S_RegisterSound( "sound/world/block.wav" );
984 	cgs.media.debBounce2Sound = trap_S_RegisterSound( "sound/world/brick.wav" );
985 	cgs.media.debBounce3Sound = trap_S_RegisterSound( "sound/world/brick2.wav" );
986 
987 	// Ridah
988 	cgs.media.flameSound = trap_S_RegisterSound( "sound/weapons/flamethrower/fl_fire.wav" );
989 	cgs.media.flameBlowSound = trap_S_RegisterSound( "sound/weapons/flamethrower/fl_blow.wav" );
990 	cgs.media.flameStartSound = trap_S_RegisterSound( "sound/weapons/flamethrower/fl_start.wav" );
991 	cgs.media.flameStreamSound = trap_S_RegisterSound( "sound/weapons/flamethrower/fl_stream.wav" );
992 	cgs.media.flameCrackSound = trap_S_RegisterSound( "sound/world/firecrack1.wav" );
993 	cgs.media.boneBounceSound = trap_S_RegisterSound( "sound/world/boardbreak.wav" );    // TODO: need a real sound for this
994 
995 	cgs.media.lightningSounds[0] = trap_S_RegisterSound( "sound/world/electzap1.wav" );
996 	cgs.media.lightningSounds[1] = trap_S_RegisterSound( "sound/world/electzap2.wav" );
997 	cgs.media.lightningSounds[2] = trap_S_RegisterSound( "sound/world/electzap3.wav" );
998 	cgs.media.lightningZap = trap_S_RegisterSound( "sound/world/electrocute.wav" );
999 
1000 	// precache sound scripts that get called from the cgame
1001 	cgs.media.bulletHitFleshScript = CG_SoundScriptPrecache( "bulletHitFlesh" );
1002 	cgs.media.bulletHitFleshMetalScript = CG_SoundScriptPrecache( "bulletHitFleshMetal" );
1003 
1004 	cgs.media.teslaZapScript = CG_SoundScriptPrecache( "teslaZap" );
1005 	cgs.media.teslaLoopSound = trap_S_RegisterSound( "sound/weapons/tesla/loop.wav" );
1006 
1007 	cgs.media.batsFlyingLoopSound = trap_S_RegisterSound( "sound/world/bats_flying.wav" );
1008 
1009 	// FIXME: only needed with item
1010 //	cgs.media.flightSound = trap_S_RegisterSound( "sound/items/flight.wav" );
1011 //	cgs.media.medkitSound = trap_S_RegisterSound ("sound/items/use_medkit.wav");
1012 	cgs.media.elecSound = trap_S_RegisterSound( "sound/items/use_elec.wav" );
1013 	cgs.media.fireSound = trap_S_RegisterSound( "sound/items/use_fire.wav" );
1014 	cgs.media.waterSound = trap_S_RegisterSound( "sound/items/use_water.wav" );
1015 	cgs.media.wineSound = trap_S_RegisterSound( "sound/pickup/holdable/use_wine.wav" );       //----(SA)	modified
1016 	cgs.media.bookSound = trap_S_RegisterSound( "sound/pickup/holdable/use_book.wav" );       //----(SA)	added
1017 	cgs.media.staminaSound = trap_S_RegisterSound( "sound/pickup/holdable/use_stamina.wav" ); //----(SA)	added
1018 	cgs.media.quadSound = trap_S_RegisterSound( "sound/items/damage3.wav" );
1019 	cgs.media.sfx_ric1 = trap_S_RegisterSound( "sound/weapons/machinegun/ric1.wav" );
1020 	cgs.media.sfx_ric2 = trap_S_RegisterSound( "sound/weapons/machinegun/ric2.wav" );
1021 	cgs.media.sfx_ric3 = trap_S_RegisterSound( "sound/weapons/machinegun/ric3.wav" );
1022 //	cgs.media.sfx_railg = trap_S_RegisterSound( "sound/weapons/railgun/railgf1a.wav" );
1023 	cgs.media.sfx_rockexp = trap_S_RegisterSound( "sound/weapons/rocket/rocklx1a.wav" );
1024 	cgs.media.sfx_dynamiteexp = trap_S_RegisterSound( "sound/weapons/dynamite/dynamite_exp.wav" );
1025 	cgs.media.sfx_dynamiteexpDist = trap_S_RegisterSound( "sound/weapons/dynamite/dynamite_exp_dist.wav" );   //----(SA)	added
1026 
1027 
1028 	cgs.media.sfx_spearhit = trap_S_RegisterSound( "sound/weapons/speargun/spearhit.wav" );
1029 
1030 	cgs.media.sfx_knifehit[0] = trap_S_RegisterSound( "sound/weapons/knife/knife_hit1.wav" ); // hitting player
1031 	cgs.media.sfx_knifehit[1] = trap_S_RegisterSound( "sound/weapons/knife/knife_hit2.wav" );
1032 	cgs.media.sfx_knifehit[2] = trap_S_RegisterSound( "sound/weapons/knife/knife_hit3.wav" );
1033 	cgs.media.sfx_knifehit[3] = trap_S_RegisterSound( "sound/weapons/knife/knife_hit4.wav" );
1034 
1035 	cgs.media.sfx_knifehit[4] = trap_S_RegisterSound( "sound/weapons/knife/knife_hitwall1.wav" ); // hitting wall
1036 
1037 	cgs.media.sfx_bullet_metalhit[0] = trap_S_RegisterSound( "sound/weapons/bullethit_metal1.wav" );
1038 	cgs.media.sfx_bullet_metalhit[1] = trap_S_RegisterSound( "sound/weapons/bullethit_metal2.wav" );
1039 	cgs.media.sfx_bullet_metalhit[2] = trap_S_RegisterSound( "sound/weapons/bullethit_metal3.wav" );
1040 
1041 	cgs.media.sfx_bullet_woodhit[0] = trap_S_RegisterSound( "sound/weapons/bullethit_wood1.wav" );
1042 	cgs.media.sfx_bullet_woodhit[1] = trap_S_RegisterSound( "sound/weapons/bullethit_wood2.wav" );
1043 	cgs.media.sfx_bullet_woodhit[2] = trap_S_RegisterSound( "sound/weapons/bullethit_wood3.wav" );
1044 
1045 	cgs.media.sfx_bullet_roofhit[0] = trap_S_RegisterSound( "sound/weapons/bullethit_roof1.wav" );
1046 	cgs.media.sfx_bullet_roofhit[1] = trap_S_RegisterSound( "sound/weapons/bullethit_roof2.wav" );
1047 	cgs.media.sfx_bullet_roofhit[2] = trap_S_RegisterSound( "sound/weapons/bullethit_roof3.wav" );
1048 
1049 	cgs.media.sfx_bullet_ceramichit[0] = trap_S_RegisterSound( "sound/weapons/bullethit_ceramic1.wav" );
1050 	cgs.media.sfx_bullet_ceramichit[1] = trap_S_RegisterSound( "sound/weapons/bullethit_ceramic2.wav" );
1051 	cgs.media.sfx_bullet_ceramichit[2] = trap_S_RegisterSound( "sound/weapons/bullethit_ceramic3.wav" );
1052 
1053 	cgs.media.sfx_bullet_glasshit[0] = trap_S_RegisterSound( "sound/weapons/bullethit_glass1.wav" );
1054 	cgs.media.sfx_bullet_glasshit[1] = trap_S_RegisterSound( "sound/weapons/bullethit_glass2.wav" );
1055 	cgs.media.sfx_bullet_glasshit[2] = trap_S_RegisterSound( "sound/weapons/bullethit_glass3.wav" );
1056 
1057 
1058 	cgs.media.sparkSounds[0] = trap_S_RegisterSound( "sound/world/saarc2.wav" );
1059 	cgs.media.sparkSounds[1] = trap_S_RegisterSound( "sound/world/arc2.wav" );
1060 
1061 
1062 //----(SA)	doors and kick
1063 
1064 	//----(SA)	removed some unnecessary stuff
1065 
1066 	trap_S_RegisterSound( "sound/weapons/melee/fstatck.wav" );
1067 	trap_S_RegisterSound( "sound/weapons/melee/fstmiss.wav" );
1068 
1069 	trap_S_RegisterSound( "sound/Loogie/spit.wav" );
1070 	trap_S_RegisterSound( "sound/Loogie/sizzle.wav" );
1071 }
1072 
1073 
1074 //===================================================================================
1075 
1076 
1077 
1078 /*
1079 =================
1080 CG_RegisterGraphics
1081 
1082 This function may execute for a couple of minutes with a slow disk.
1083 =================
1084 */
CG_RegisterGraphics(void)1085 static void CG_RegisterGraphics( void ) {
1086 	char name[1024];
1087 
1088 	int i;
1089 	char items[MAX_ITEMS + 1];
1090 	static char     *sb_nums[11] = {
1091 		"gfx/2d/numbers/zero_32b",
1092 		"gfx/2d/numbers/one_32b",
1093 		"gfx/2d/numbers/two_32b",
1094 		"gfx/2d/numbers/three_32b",
1095 		"gfx/2d/numbers/four_32b",
1096 		"gfx/2d/numbers/five_32b",
1097 		"gfx/2d/numbers/six_32b",
1098 		"gfx/2d/numbers/seven_32b",
1099 		"gfx/2d/numbers/eight_32b",
1100 		"gfx/2d/numbers/nine_32b",
1101 		"gfx/2d/numbers/minus_32b",
1102 	};
1103 
1104 	// clear any references to old media
1105 	memset( &cg.refdef, 0, sizeof( cg.refdef ) );
1106 	trap_R_ClearScene();
1107 
1108 	CG_LoadingString( cgs.mapname );
1109 
1110 	trap_R_LoadWorldMap( cgs.mapname );
1111 
1112 	// precache status bar pics
1113 	CG_LoadingString( "game media" );
1114 
1115 	CG_LoadingString( " - textures" );
1116 
1117 	for ( i = 0 ; i < 11 ; i++ ) {
1118 		cgs.media.numberShaders[i] = trap_R_RegisterShader( sb_nums[i] );
1119 	}
1120 
1121 	cgs.media.smokePuffShader = trap_R_RegisterShader( "smokePuff" );
1122 
1123 	// Rafael - blood pool
1124 	//cgs.media.bloodPool = trap_R_RegisterShader ("bloodPool");
1125 
1126 	// RF, blood cloud
1127 	cgs.media.bloodCloudShader = trap_R_RegisterShader( "bloodCloud" );
1128 
1129 	// Rafael - cannon
1130 	cgs.media.smokePuffShaderdirty = trap_R_RegisterShader( "smokePuffdirty" );
1131 	cgs.media.smokePuffShaderb1 = trap_R_RegisterShader( "smokePuffblack1" );
1132 	cgs.media.smokePuffShaderb2 = trap_R_RegisterShader( "smokePuffblack2" );
1133 	cgs.media.smokePuffShaderb3 = trap_R_RegisterShader( "smokePuffblack3" );
1134 	cgs.media.smokePuffShaderb4 = trap_R_RegisterShader( "smokePuffblack4" );
1135 	cgs.media.smokePuffShaderb5 = trap_R_RegisterShader( "smokePuffblack5" );
1136 	// done
1137 
1138 	// Rafael - bleedanim
1139 	for ( i = 0; i < 5; i++ ) {
1140 		cgs.media.viewBloodAni[i] = trap_R_RegisterShader( va( "viewBloodBlend%i", i + 1 ) );
1141 	}
1142 	cgs.media.viewFlashBlood = trap_R_RegisterShader( "viewFlashBlood" );
1143 	for ( i = 0; i < 16; i++ ) {
1144 		cgs.media.viewFlashFire[i] = trap_R_RegisterShader( va( "viewFlashFire%i", i + 1 ) );
1145 	}
1146 	// done
1147 
1148 	// Rafael bats
1149 	for ( i = 0; i < 10; i++ ) {
1150 		cgs.media.bats[i] = trap_R_RegisterShader( va( "bats%i",i + 1 ) );
1151 	}
1152 	// done
1153 
1154 	cgs.media.smokePuffRageProShader = trap_R_RegisterShader( "smokePuffRagePro" );
1155 	cgs.media.shotgunSmokePuffShader = trap_R_RegisterShader( "shotgunSmokePuff" );
1156 
1157 	cgs.media.bloodTrailShader = trap_R_RegisterShader( "bloodTrail" );
1158 	cgs.media.lagometerShader = trap_R_RegisterShader( "lagometer" );
1159 	cgs.media.connectionShader = trap_R_RegisterShader( "disconnected" );
1160 
1161 	cgs.media.nailPuffShader = trap_R_RegisterShader( "nailtrail" );
1162 
1163 //	cgs.media.reticleShaderSimple = trap_R_RegisterShader( "gfx/misc/reticlesimple" );		// TODO: remove
1164 	cgs.media.reticleShaderSimpleQ = trap_R_RegisterShader( "gfx/misc/reticlesimple_quarter" );
1165 	cgs.media.snooperShaderSimple = trap_R_RegisterShader( "gfx/misc/snoopersimple" );
1166 
1167 //	cgs.media.binocShaderSimple = trap_R_RegisterShader( "gfx/misc/binocsimple" );			// TODO: remove
1168 	cgs.media.binocShaderSimpleQ = trap_R_RegisterShader( "gfx/misc/binocsimple_quarter" );  //----(SA)	added
1169 
1170 	// Rafael
1171 	// cgs.media.snowShader = trap_R_RegisterShader ( "snowPuff" );
1172 	cgs.media.snowShader = trap_R_RegisterShader( "snow_tri" );
1173 
1174 	cgs.media.oilParticle = trap_R_RegisterShader( "oilParticle" );
1175 	cgs.media.oilSlick = trap_R_RegisterShader( "oilSlick" );
1176 
1177 	cgs.media.waterBubbleShader = trap_R_RegisterShader( "waterBubble" );
1178 
1179 	cgs.media.tracerShader = trap_R_RegisterShader( "gfx/misc/tracer" );
1180 	cgs.media.selectShader = trap_R_RegisterShader( "gfx/2d/select" );
1181 
1182 
1183 	cgs.media.hintShaders[HINT_ACTIVATE]            = trap_R_RegisterShader( "gfx/2d/usableHint" );
1184 	cgs.media.hintShaders[HINT_NOACTIVATE]          = trap_R_RegisterShader( "gfx/2d/notUsableHint" );
1185 	cgs.media.hintShaders[HINT_DOOR]                = trap_R_RegisterShader( "gfx/2d/doorHint" );
1186 	cgs.media.hintShaders[HINT_DOOR_ROTATING]       = trap_R_RegisterShader( "gfx/2d/doorRotateHint" );
1187 	cgs.media.hintShaders[HINT_DOOR_LOCKED]         = trap_R_RegisterShader( "gfx/2d/doorLockHint" );
1188 	cgs.media.hintShaders[HINT_DOOR_ROTATING_LOCKED] = trap_R_RegisterShader( "gfx/2d/doorRotateLockHint" );
1189 	cgs.media.hintShaders[HINT_MG42]                = trap_R_RegisterShader( "gfx/2d/mg42Hint" );
1190 	cgs.media.hintShaders[HINT_BREAKABLE]           = trap_R_RegisterShader( "gfx/2d/breakableHint" );
1191 	cgs.media.hintShaders[HINT_CHAIR]               = trap_R_RegisterShader( "gfx/2d/chairHint" );
1192 	cgs.media.hintShaders[HINT_ALARM]               = trap_R_RegisterShader( "gfx/2d/alarmHint" );
1193 	cgs.media.hintShaders[HINT_HEALTH]              = trap_R_RegisterShader( "gfx/2d/healthHint" );
1194 	cgs.media.hintShaders[HINT_TREASURE]            = trap_R_RegisterShader( "gfx/2d/treasureHint" );
1195 	cgs.media.hintShaders[HINT_KNIFE]               = trap_R_RegisterShader( "gfx/2d/knifeHint" );
1196 	cgs.media.hintShaders[HINT_LADDER]              = trap_R_RegisterShader( "gfx/2d/ladderHint" );
1197 	cgs.media.hintShaders[HINT_BUTTON]              = trap_R_RegisterShader( "gfx/2d/buttonHint" );
1198 	cgs.media.hintShaders[HINT_WATER]               = trap_R_RegisterShader( "gfx/2d/waterHint" );
1199 	cgs.media.hintShaders[HINT_CAUTION]             = trap_R_RegisterShader( "gfx/2d/cautionHint" );
1200 	cgs.media.hintShaders[HINT_DANGER]              = trap_R_RegisterShader( "gfx/2d/dangerHint" );
1201 	cgs.media.hintShaders[HINT_SECRET]              = trap_R_RegisterShader( "gfx/2d/secretHint" );
1202 	cgs.media.hintShaders[HINT_QUESTION]            = trap_R_RegisterShader( "gfx/2d/questionHint" );
1203 	cgs.media.hintShaders[HINT_EXCLAMATION]         = trap_R_RegisterShader( "gfx/2d/exclamationHint" );
1204 	cgs.media.hintShaders[HINT_CLIPBOARD]           = trap_R_RegisterShader( "gfx/2d/clipboardHint" );
1205 	cgs.media.hintShaders[HINT_WEAPON]              = trap_R_RegisterShader( "gfx/2d/weaponHint" );
1206 	cgs.media.hintShaders[HINT_AMMO]                = trap_R_RegisterShader( "gfx/2d/ammoHint" );
1207 	cgs.media.hintShaders[HINT_ARMOR]               = trap_R_RegisterShader( "gfx/2d/armorHint" );
1208 	cgs.media.hintShaders[HINT_POWERUP]             = trap_R_RegisterShader( "gfx/2d/powerupHint" );
1209 	cgs.media.hintShaders[HINT_HOLDABLE]            = trap_R_RegisterShader( "gfx/2d/holdableHint" );
1210 	cgs.media.hintShaders[HINT_INVENTORY]           = trap_R_RegisterShader( "gfx/2d/inventoryHint" );
1211 	cgs.media.hintShaders[HINT_EXIT]                = trap_R_RegisterShader( "gfx/2d/exitHint" );
1212 	cgs.media.hintShaders[HINT_NOEXIT]              = cgs.media.hintShaders[HINT_EXIT];
1213 	cgs.media.hintShaders[HINT_EXIT_FAR]            = cgs.media.hintShaders[HINT_EXIT];
1214 	cgs.media.hintShaders[HINT_NOEXIT_FAR]          = cgs.media.hintShaders[HINT_EXIT];
1215 
1216 //	cgs.media.hintShaders[HINT_PLYR_FRIEND]			= trap_R_RegisterShader( "gfx/2d/hintPlrFriend" );
1217 //	cgs.media.hintShaders[HINT_PLYR_NEUTRAL]		= trap_R_RegisterShader( "gfx/2d/hintPlrNeutral" );
1218 //	cgs.media.hintShaders[HINT_PLYR_ENEMY]			= trap_R_RegisterShader( "gfx/2d/hintPlrEnemy" );
1219 //	cgs.media.hintShaders[HINT_PLYR_UNKNOWN]		= trap_R_RegisterShader( "gfx/2d/hintPlrUnknown" );
1220 
1221 //	cgs.media.hintShaders[HINT_BUILD]				= trap_R_RegisterShader( "gfx/2d/buildHint" );		// DHM - Nerve
1222 
1223 	cgs.media.youGotMailShader      = trap_R_RegisterShader( "gfx/2d/yougotmail" );    //----(SA)	added
1224 	cgs.media.youGotObjectiveShader = trap_R_RegisterShader( "gfx/2d/yougotobjective" );   //----(SA)	added
1225 
1226 //----(SA)	end
1227 
1228 	for ( i = 0 ; i < NUM_CROSSHAIRS ; i++ ) {
1229 		cgs.media.crosshairShader[i] = trap_R_RegisterShaderNoMip( va( "gfx/2d/crosshair%c", 'a' + i ) );
1230 	}
1231 
1232 	cgs.media.crosshairFriendly =  trap_R_RegisterShader( "gfx/2d/friendlycross" );  //----(SA)	added
1233 
1234 	cgs.media.backTileShader = trap_R_RegisterShader( "gfx/2d/backtile" );
1235 	cgs.media.noammoShader = trap_R_RegisterShader( "icons/noammo" );
1236 
1237 	// powerup shaders
1238 //	cgs.media.quadShader = trap_R_RegisterShader("powerups/quad" );
1239 //	cgs.media.quadWeaponShader = trap_R_RegisterShader("powerups/quadWeapon" );
1240 //	cgs.media.battleSuitShader = trap_R_RegisterShader("powerups/battleSuit" );
1241 //	cgs.media.battleWeaponShader = trap_R_RegisterShader("powerups/battleWeapon" );
1242 //	cgs.media.invisShader = trap_R_RegisterShader("powerups/invisibility" );
1243 //	cgs.media.regenShader = trap_R_RegisterShader("powerups/regen" );
1244 //	cgs.media.hastePuffShader = trap_R_RegisterShader("hasteSmokePuff" );
1245 
1246 	// DHM - Nerve :: Allow flags again, will change later to more appropriate models
1247 	if ( cgs.gametype == GT_CTF || cgs.gametype == GT_WOLF || cg_buildScript.integer ) {
1248 		cgs.media.redFlagModel = trap_R_RegisterModel( "models/flags/r_flag.md3" );
1249 		cgs.media.blueFlagModel = trap_R_RegisterModel( "models/flags/b_flag.md3" );
1250 	}
1251 
1252 //	if ( cgs.gametype >= GT_TEAM || cg_buildScript.integer ) {
1253 //		cgs.media.friendShader = trap_R_RegisterShader( "sprites/foe" );
1254 //		cgs.media.redQuadShader = trap_R_RegisterShader("powerups/blueflag" );
1255 //		cgs.media.teamStatusBar = trap_R_RegisterShader( "gfx/2d/colorbar.tga" );
1256 //	}
1257 
1258 	CG_LoadingString( " - models" );
1259 
1260 	cgs.media.machinegunBrassModel = trap_R_RegisterModel( "models/weapons2/shells/m_shell.md3" );
1261 	cgs.media.panzerfaustBrassModel = trap_R_RegisterModel( "models/weapons2/shells/pf_shell.md3" );
1262 	cgs.media.smallgunBrassModel = trap_R_RegisterModel( "models/weapons2/shells/sm_shell.md3" );
1263 
1264 	//----(SA) wolf debris
1265 	cgs.media.debBlock[0] = trap_R_RegisterModel( "models/mapobjects/debris/brick1.md3" );
1266 	cgs.media.debBlock[1] = trap_R_RegisterModel( "models/mapobjects/debris/brick2.md3" );
1267 	cgs.media.debBlock[2] = trap_R_RegisterModel( "models/mapobjects/debris/brick3.md3" );
1268 	cgs.media.debBlock[3] = trap_R_RegisterModel( "models/mapobjects/debris/brick4.md3" );
1269 	cgs.media.debBlock[4] = trap_R_RegisterModel( "models/mapobjects/debris/brick5.md3" );
1270 	cgs.media.debBlock[5] = trap_R_RegisterModel( "models/mapobjects/debris/brick6.md3" );
1271 
1272 	cgs.media.debRock[0] = trap_R_RegisterModel( "models/mapobjects/debris/rubble1.md3" );
1273 	cgs.media.debRock[1] = trap_R_RegisterModel( "models/mapobjects/debris/rubble2.md3" );
1274 	cgs.media.debRock[2] = trap_R_RegisterModel( "models/mapobjects/debris/rubble3.md3" );
1275 
1276 
1277 	cgs.media.debWood[0] = trap_R_RegisterModel( "models/gibs/wood/wood1.md3" );
1278 	cgs.media.debWood[1] = trap_R_RegisterModel( "models/gibs/wood/wood2.md3" );
1279 	cgs.media.debWood[2] = trap_R_RegisterModel( "models/gibs/wood/wood3.md3" );
1280 	cgs.media.debWood[3] = trap_R_RegisterModel( "models/gibs/wood/wood4.md3" );
1281 	cgs.media.debWood[4] = trap_R_RegisterModel( "models/gibs/wood/wood5.md3" );
1282 	cgs.media.debWood[5] = trap_R_RegisterModel( "models/gibs/wood/wood6.md3" );
1283 //	cgs.media.debWoodl = trap_R_RegisterModel( "models/mapobjects/debris/woodxl.md3" );
1284 //	cgs.media.debWoodm = trap_R_RegisterModel( "models/mapobjects/debris/woodm.md3" );
1285 //	cgs.media.debWoods = trap_R_RegisterModel( "models/mapobjects/debris/woodsm.md3" );
1286 
1287 	cgs.media.debFabric[0] = trap_R_RegisterModel( "models/shards/fabric1.md3" );
1288 	cgs.media.debFabric[1] = trap_R_RegisterModel( "models/shards/fabric2.md3" );
1289 	cgs.media.debFabric[2] = trap_R_RegisterModel( "models/shards/fabric3.md3" );
1290 
1291 	//----(SA) end
1292 
1293 //	cgs.media.medicReviveShader = trap_R_RegisterShader( "sprites/medic_revive" );	//----(SA)	commented out from MP
1294 	cgs.media.balloonShader = trap_R_RegisterShader( "sprites/balloon3" );
1295 
1296 	for ( i = 0; i < MAX_AISTATES; i++ ) {
1297 		cgs.media.aiStateShaders[i] = trap_R_RegisterShader( va( "sprites/aistate%i", i + 1 ) );
1298 	}
1299 
1300 	cgs.media.bloodExplosionShader = trap_R_RegisterShader( "bloodExplosion" );
1301 
1302 	//cgs.media.bleedExplosionShader = trap_R_RegisterShader( "bleedExplosion" );
1303 
1304 	//----(SA)	water splash
1305 //	cgs.media.waterSplashModel = trap_R_RegisterModel( "models/weaphits/bullet.md3" );
1306 //	cgs.media.waterSplashShader = trap_R_RegisterShader( "waterSplash" );
1307 	//----(SA)	end
1308 
1309 //	cgs.media.spearModel = trap_R_RegisterModel( "models/weaphits/spear.md3" );	//----(SA)
1310 
1311 //	cgs.media.bulletFlashModel = trap_R_RegisterModel( "models/weaphits/bullet.md3" );
1312 //	cgs.media.ringFlashModel = trap_R_RegisterModel( "models/weaphits/ring02.md3" );
1313 //	cgs.media.dishFlashModel = trap_R_RegisterModel( "models/weaphits/boom01.md3" );
1314 //	cgs.media.teleportEffectModel = trap_R_RegisterModel( "models/misc/telep.md3" );
1315 //	cgs.media.teleportEffectShader = trap_R_RegisterShader( "teleportEffect" );
1316 
1317 //	cgs.media.batModel = trap_R_RegisterModel( "models/mapobjects/bat/bat.md3" );
1318 
1319 //	cgs.media.medalImpressive = trap_R_RegisterShaderNoMip( "medal_impressive" );
1320 //	cgs.media.medalExcellent = trap_R_RegisterShaderNoMip( "medal_excellent" );
1321 //	cgs.media.medalGauntlet = trap_R_RegisterShaderNoMip( "medal_gauntlet" );
1322 
1323 	// Ridah, spark particles
1324 	cgs.media.sparkParticleShader = trap_R_RegisterShader( "sparkParticle" );
1325 	cgs.media.smokeTrailShader = trap_R_RegisterShader( "smokeTrail" );
1326 //	cgs.media.fireTrailShader = trap_R_RegisterShader( "fireTrail" );
1327 	cgs.media.lightningBoltShader = trap_R_RegisterShader( "lightningBolt" );
1328 //	cgs.media.lightningBoltShaderGreen = trap_R_RegisterShader( "lightningBoltGreen" );	//----(SA)	alternate lightning color
1329 	cgs.media.flamethrowerFireStream = trap_R_RegisterShader( "flamethrowerFireStream" );
1330 	cgs.media.flamethrowerBlueStream = trap_R_RegisterShader( "flamethrowerBlueStream" );
1331 	//cgs.media.flamethrowerFuelStream = trap_R_RegisterShader( "flamethrowerFuelStream" );
1332 	//cgs.media.flamethrowerFuelShader = trap_R_RegisterShader( "flamethrowerFuel" );
1333 	cgs.media.onFireShader2 = trap_R_RegisterShader( "entityOnFire1" );
1334 	cgs.media.onFireShader = trap_R_RegisterShader( "entityOnFire2" );
1335 	//cgs.media.dripWetShader2 = trap_R_RegisterShader( "dripWet2" );
1336 	//cgs.media.dripWetShader = trap_R_RegisterShader( "dripWet1" );
1337 	cgs.media.viewFadeBlack = trap_R_RegisterShader( "viewFadeBlack" );
1338 	cgs.media.sparkFlareShader = trap_R_RegisterShader( "sparkFlareParticle" );
1339 
1340 	// spotlight
1341 	// shaders
1342 	cgs.media.spotLightShader = trap_R_RegisterShader( "spotLight" );
1343 	cgs.media.spotLightBeamShader = trap_R_RegisterShader( "lightBeam" );
1344 
1345 	// models
1346 	cgs.media.spotLightBaseModel = trap_R_RegisterModel( "models/mapobjects/light/searchlight1_b.md3" );
1347 	cgs.media.spotLightLightModel = trap_R_RegisterModel( "models/mapobjects/light/searchlight1_l.md3" );
1348 	cgs.media.spotLightLightModelBroke = trap_R_RegisterModel( "models/mapobjects/light/searchlight_l_broke.md3" );
1349 	// end spotlight
1350 
1351 	cgs.media.lightningHitWallShader = trap_R_RegisterShader( "lightningHitWall" );
1352 	cgs.media.lightningWaveShader = trap_R_RegisterShader( "lightningWave" );
1353 	cgs.media.bulletParticleTrailShader = trap_R_RegisterShader( "bulletParticleTrail" );
1354 	cgs.media.smokeParticleShader = trap_R_RegisterShader( "smokeParticle" );
1355 
1356 	// DHM - Nerve :: bullet hitting dirt
1357 	cgs.media.dirtParticle1Shader = trap_R_RegisterShader( "dirt_splash" );
1358 	cgs.media.dirtParticle2Shader = trap_R_RegisterShader( "water_splash" );
1359 	//cgs.media.dirtParticle3Shader = trap_R_RegisterShader( "dirtParticle3" );
1360 
1361 	cgs.media.teslaDamageEffectShader = trap_R_RegisterShader( "teslaDamageEffect" );
1362 	cgs.media.teslaAltDamageEffectShader = trap_R_RegisterShader( "teslaAltDamageEffect" );
1363 	cgs.media.viewTeslaDamageEffectShader = trap_R_RegisterShader( "viewTeslaDamageEffect" );
1364 	cgs.media.viewTeslaAltDamageEffectShader = trap_R_RegisterShader( "viewTeslaAltDamageEffect" );
1365 	// done.
1366 
1367 	cgs.media.railCoreShader = trap_R_RegisterShader( "railCore" );  // (SA) for debugging server traces
1368 
1369 	cgs.media.thirdPersonBinocModel = trap_R_RegisterModel( "models/powerups/holdable/binocs_thirdperson.md3" ); //----(SA)	added
1370 	cgs.media.cigModel = trap_R_RegisterModel( "models/players/infantryss/acc/cig.md3" );    //----(SA)	added
1371 
1372 	// RF, not used anymore
1373 	//cgs.media.targetEffectExplosionShader	= trap_R_RegisterShader( "targetEffectExplode" );
1374 	//cgs.media.rocketExplosionShader			= trap_R_RegisterShader( "rocketExplosion" );
1375 	//cgs.media.grenadeExplosionShader		= trap_R_RegisterShader( "grenadeExplosion" );
1376 
1377 	// zombie shot
1378 	//cgs.media.zombieLoogie = trap_R_RegisterModel( "models/mapobjects/bodyparts/zom_loog.md3" );
1379 	cgs.media.flamebarrel = trap_R_RegisterModel( "models/furniture/barrel/barrel_a.md3" );
1380 	//----(SA) end
1381 
1382 	cgs.media.mg42muzzleflash = trap_R_RegisterModel( "models/weapons2/machinegun/mg42_flash.md3" );
1383 	// cgs.media.mg42muzzleflashgg = trap_R_RegisterModel ("models/weapons2/machinegun/mg42_flash_gg.md3" );
1384 
1385 	cgs.media.planemuzzleflash = trap_R_RegisterModel( "models/mapobjects/vehicles/gunflare.md3" );
1386 	cgs.media.crowbar = trap_R_RegisterModel( "models/weapons2/wrench/wrench.md3" );
1387 
1388 	// Rafael shards
1389 	cgs.media.shardGlass1 = trap_R_RegisterModel( "models/shards/glass1.md3" );
1390 	cgs.media.shardGlass2 = trap_R_RegisterModel( "models/shards/glass2.md3" );
1391 	cgs.media.shardWood1 = trap_R_RegisterModel( "models/shards/wood1.md3" );
1392 	cgs.media.shardWood2 = trap_R_RegisterModel( "models/shards/wood2.md3" );
1393 	cgs.media.shardMetal1 = trap_R_RegisterModel( "models/shards/metal1.md3" );
1394 	cgs.media.shardMetal2 = trap_R_RegisterModel( "models/shards/metal2.md3" );
1395 	cgs.media.shardCeramic1 = trap_R_RegisterModel( "models/shards/ceramic1.md3" );
1396 	cgs.media.shardCeramic2 = trap_R_RegisterModel( "models/shards/ceramic2.md3" );
1397 	// done
1398 
1399 	cgs.media.shardRubble1 = trap_R_RegisterModel( "models/mapobjects/debris/brick000.md3" );
1400 	cgs.media.shardRubble2 = trap_R_RegisterModel( "models/mapobjects/debris/brick001.md3" );
1401 	cgs.media.shardRubble3 = trap_R_RegisterModel( "models/mapobjects/debris/brick002.md3" );
1402 
1403 	for ( i = 0; i < MAX_LOCKER_DEBRIS; i++ )
1404 	{
1405 		Com_sprintf( name, sizeof( name ), "models/mapobjects/debris/personal%i.md3", i + 1 );
1406 		cgs.media.shardJunk[i] = trap_R_RegisterModel( name );
1407 	}
1408 
1409 	memset( cg_items, 0, sizeof( cg_items ) );
1410 	memset( cg_weapons, 0, sizeof( cg_weapons ) );
1411 
1412 	CG_LoadTranslateStrings();  //----(SA)	added.  for localization, read on-screen print names from text file
1413 
1414 	// TODO: FIXME:  REMOVE REGISTRATION OF EACH MODEL FOR EVERY LEVEL LOAD
1415 
1416 
1417 	//----(SA)	okay, new stuff to intialize rather than doing it at level load time (or "give all" time)
1418 	//			(I'm certainly not against being efficient here, but I'm tired of the rocket launcher effect only registering
1419 	//			sometimes and want it to work for sure for this demo)
1420 
1421 
1422 // code is almost complete for doing this correctly.  will remove when that is complete.
1423 	CG_LoadingString( " - weapons" );
1424 	for ( i = WP_KNIFE; i < WP_GAUNTLET; i++ ) {
1425 //		CG_LoadingString( va("   - %d", i) );
1426 		CG_RegisterWeapon( i );
1427 	}
1428 
1429 // END
1430 
1431 
1432 	// only register the items that the server says we need
1433 	Q_strncpyz(items, CG_ConfigString(CS_ITEMS), sizeof(items));
1434 
1435 	CG_LoadingString( " - items" );
1436 	for ( i = 1 ; i < bg_numItems ; i++ ) {
1437 		if ( items[ i ] == '1' || cg_buildScript.integer ) {
1438 			// TODO: get weapons added to the list that are 'set' from a script
1439 			CG_LoadingItem( i );
1440 			CG_RegisterItemVisuals( i );
1441 		}
1442 	}
1443 
1444 	// wall marks
1445 	cgs.media.bulletMarkShader = trap_R_RegisterShader( "gfx/damage/bullet_mrk" );
1446 	cgs.media.burnMarkShader = trap_R_RegisterShader( "gfx/damage/burn_med_mrk" );
1447 	cgs.media.holeMarkShader = trap_R_RegisterShader( "gfx/damage/hole_lg_mrk" );
1448 	cgs.media.shadowMarkShader = trap_R_RegisterShader( "markShadow" );
1449 	cgs.media.shadowFootShader = trap_R_RegisterShader( "markShadowFoot" );
1450 	cgs.media.shadowTorsoShader = trap_R_RegisterShader( "markShadowTorso" );
1451 	cgs.media.wakeMarkShader = trap_R_RegisterShader( "wake" );
1452 	cgs.media.wakeMarkShaderAnim = trap_R_RegisterShader( "wakeAnim" ); // (SA)
1453 
1454 	//----(SA)	added
1455 	cgs.media.bulletMarkShaderMetal = trap_R_RegisterShader( "gfx/damage/metal_mrk" );
1456 	cgs.media.bulletMarkShaderWood = trap_R_RegisterShader( "gfx/damage/wood_mrk" );
1457 	cgs.media.bulletMarkShaderCeramic = trap_R_RegisterShader( "gfx/damage/ceramic_mrk" );
1458 	cgs.media.bulletMarkShaderGlass = trap_R_RegisterShader( "gfx/damage/glass_mrk" );
1459 
1460 	for ( i = 0 ; i < 5 ; i++ ) {
1461 		char name[32];
1462 		//Com_sprintf( name, sizeof(name), "textures/decals/blood%i", i+1 );
1463 		//cgs.media.bloodMarkShaders[i] = trap_R_RegisterShader( name );
1464 		Com_sprintf( name, sizeof( name ), "blood_dot%i", i + 1 );
1465 		cgs.media.bloodDotShaders[i] = trap_R_RegisterShader( name );
1466 	}
1467 
1468 	CG_LoadingString( " - inline models" );
1469 
1470 	// register the inline models
1471 	cgs.numInlineModels = trap_CM_NumInlineModels();
1472 	for ( i = 1 ; i < cgs.numInlineModels ; i++ ) {
1473 		char name[10];
1474 		vec3_t mins, maxs;
1475 		int j;
1476 
1477 		Com_sprintf( name, sizeof( name ), "*%i", i );
1478 		cgs.inlineDrawModel[i] = trap_R_RegisterModel( name );
1479 		trap_R_ModelBounds( cgs.inlineDrawModel[i], mins, maxs );
1480 		for ( j = 0 ; j < 3 ; j++ ) {
1481 			cgs.inlineModelMidpoints[i][j] = mins[j] + 0.5 * ( maxs[j] - mins[j] );
1482 		}
1483 	}
1484 
1485 	CG_LoadingString( " - server models" );
1486 
1487 	// register all the server specified models
1488 	for ( i = 1 ; i < MAX_MODELS ; i++ ) {
1489 		const char      *modelName;
1490 
1491 		modelName = CG_ConfigString( CS_MODELS + i );
1492 		if ( !modelName[0] ) {
1493 			break;
1494 		}
1495 		cgs.gameModels[i] = trap_R_RegisterModel( modelName );
1496 	}
1497 
1498 	CG_LoadingString( " - particles" );
1499 	CG_ClearParticles();
1500 
1501 	for ( i = 1; i < MAX_PARTICLES_AREAS; i++ )
1502 	{
1503 		{
1504 			int rval;
1505 
1506 			rval = CG_NewParticleArea( CS_PARTICLES + i );
1507 			if ( !rval ) {
1508 				break;
1509 			}
1510 		}
1511 	}
1512 
1513 //	cgs.media.cursor = trap_R_RegisterShaderNoMip( "menu/art/3_cursor2" );
1514 	cgs.media.sizeCursor = trap_R_RegisterShaderNoMip( "ui/assets/sizecursor.tga" );
1515 	cgs.media.selectCursor = trap_R_RegisterShaderNoMip( "ui/assets/selectcursor.tga" );
1516 	CG_LoadingString( " - game media done" );
1517 
1518 }
1519 
1520 /*
1521 ===================
1522 CG_RegisterClients
1523 
1524 ===================
1525 */
CG_RegisterClients(void)1526 static void CG_RegisterClients( void ) {
1527 	int i;
1528 
1529 	for ( i = 0 ; i < MAX_CLIENTS ; i++ ) {
1530 		const char      *clientInfo;
1531 
1532 		clientInfo = CG_ConfigString( CS_PLAYERS + i );
1533 		if ( !clientInfo[0] ) {
1534 			continue;
1535 		}
1536 		CG_LoadingClient( i );
1537 		CG_NewClientInfo( i );
1538 	}
1539 }
1540 
1541 //===========================================================================
1542 
1543 /*
1544 =================
1545 CG_ConfigString
1546 =================
1547 */
CG_ConfigString(int index)1548 const char *CG_ConfigString( int index ) {
1549 	if ( index < 0 || index >= MAX_CONFIGSTRINGS ) {
1550 		CG_Error( "CG_ConfigString: bad index: %i", index );
1551 	}
1552 	return cgs.gameState.stringData + cgs.gameState.stringOffsets[ index ];
1553 }
1554 
1555 //==================================================================
1556 
1557 /*
1558 ======================
1559 CG_StartMusic
1560 
1561 ======================
1562 */
CG_StartMusic(void)1563 void CG_StartMusic( void ) {
1564 	char    *s;
1565 	char parm1[MAX_QPATH], parm2[MAX_QPATH];
1566 
1567 	// start the background music
1568 	s = (char *)CG_ConfigString( CS_MUSIC );
1569 	Q_strncpyz( parm1, COM_Parse( &s ), sizeof( parm1 ) );
1570 	Q_strncpyz( parm2, COM_Parse( &s ), sizeof( parm2 ) );
1571 
1572 	if ( strlen( parm1 ) ) {
1573 		trap_S_StartBackgroundTrack( parm1, parm2, 0 );
1574 	}
1575 }
1576 
1577 //----(SA)	added
1578 /*
1579 ==============
1580 CG_QueueMusic
1581 ==============
1582 */
CG_QueueMusic(void)1583 void CG_QueueMusic( void ) {
1584 	char    *s;
1585 	char parm[MAX_QPATH];
1586 
1587 	// prepare the next background track
1588 	s = (char *)CG_ConfigString( CS_MUSIC_QUEUE );
1589 	Q_strncpyz( parm, COM_Parse( &s ), sizeof( parm ) );
1590 
1591 	// even if no strlen(parm).  we want to be able to clear the queue
1592 
1593 	// TODO: \/		the values stored in here will be made accessable so
1594 	//				it doesn't have to go through startbackgroundtrack() (which is stupid)
1595 	trap_S_StartBackgroundTrack( parm, "", -2 );  // '-2' for 'queue looping track' (QUEUED_PLAY_LOOPED)
1596 }
1597 //----(SA)	end
1598 
CG_GetMenuBuffer(const char * filename)1599 char *CG_GetMenuBuffer( const char *filename ) {
1600 	int len;
1601 	fileHandle_t f;
1602 	static char buf[MAX_MENUFILE];
1603 
1604 	len = trap_FS_FOpenFile( filename, &f, FS_READ );
1605 	if ( !f ) {
1606 		trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) );
1607 		return NULL;
1608 	}
1609 	if ( len >= MAX_MENUFILE ) {
1610 		trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i\n", filename, len, MAX_MENUFILE ) );
1611 		trap_FS_FCloseFile( f );
1612 		return NULL;
1613 	}
1614 
1615 	trap_FS_Read( buf, len, f );
1616 	buf[len] = 0;
1617 	trap_FS_FCloseFile( f );
1618 
1619 	return buf;
1620 }
1621 
1622 //
1623 // ==============================
1624 // new hud stuff ( mission pack )
1625 // ==============================
1626 //
CG_Asset_Parse(int handle)1627 qboolean CG_Asset_Parse( int handle ) {
1628 	pc_token_t token;
1629 	const char *tempStr;
1630 
1631 	if ( !trap_PC_ReadToken( handle, &token ) ) {
1632 		return qfalse;
1633 	}
1634 	if ( Q_stricmp( token.string, "{" ) != 0 ) {
1635 		return qfalse;
1636 	}
1637 
1638 	while ( 1 ) {
1639 		if ( !trap_PC_ReadToken( handle, &token ) ) {
1640 			return qfalse;
1641 		}
1642 
1643 		if ( Q_stricmp( token.string, "}" ) == 0 ) {
1644 			return qtrue;
1645 		}
1646 
1647 		// font
1648 		if ( Q_stricmp( token.string, "font" ) == 0 ) {
1649 			int pointSize;
1650 			if ( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) {
1651 				return qfalse;
1652 			}
1653 			cgDC.registerFont( tempStr, pointSize, &cgDC.Assets.textFont );
1654 			continue;
1655 		}
1656 
1657 		// smallFont
1658 		if ( Q_stricmp( token.string, "smallFont" ) == 0 ) {
1659 			int pointSize;
1660 			if ( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) {
1661 				return qfalse;
1662 			}
1663 			cgDC.registerFont( tempStr, pointSize, &cgDC.Assets.smallFont );
1664 			continue;
1665 		}
1666 
1667 		// font
1668 		if ( Q_stricmp( token.string, "bigfont" ) == 0 ) {
1669 			int pointSize;
1670 			if ( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) {
1671 				return qfalse;
1672 			}
1673 			cgDC.registerFont( tempStr, pointSize, &cgDC.Assets.bigFont );
1674 			continue;
1675 		}
1676 
1677 		// handwriting
1678 		if ( Q_stricmp( token.string, "handwritingFont" ) == 0 ) {
1679 			int pointSize;
1680 			if ( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) {
1681 				return qfalse;
1682 			}
1683 			cgDC.registerFont( tempStr, pointSize, &cgDC.Assets.handwritingFont );
1684 			continue;
1685 		}
1686 
1687 		// gradientbar
1688 		if ( Q_stricmp( token.string, "gradientbar" ) == 0 ) {
1689 			if ( !PC_String_Parse( handle, &tempStr ) ) {
1690 				return qfalse;
1691 			}
1692 			cgDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( tempStr );
1693 			continue;
1694 		}
1695 
1696 		// enterMenuSound
1697 		if ( Q_stricmp( token.string, "menuEnterSound" ) == 0 ) {
1698 			if ( !PC_String_Parse( handle, &tempStr ) ) {
1699 				return qfalse;
1700 			}
1701 			cgDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr );
1702 			continue;
1703 		}
1704 
1705 		// exitMenuSound
1706 		if ( Q_stricmp( token.string, "menuExitSound" ) == 0 ) {
1707 			if ( !PC_String_Parse( handle, &tempStr ) ) {
1708 				return qfalse;
1709 			}
1710 			cgDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr );
1711 			continue;
1712 		}
1713 
1714 		// itemFocusSound
1715 		if ( Q_stricmp( token.string, "itemFocusSound" ) == 0 ) {
1716 			if ( !PC_String_Parse( handle, &tempStr ) ) {
1717 				return qfalse;
1718 			}
1719 			cgDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr );
1720 			continue;
1721 		}
1722 
1723 		// menuBuzzSound
1724 		if ( Q_stricmp( token.string, "menuBuzzSound" ) == 0 ) {
1725 			if ( !PC_String_Parse( handle, &tempStr ) ) {
1726 				return qfalse;
1727 			}
1728 			cgDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr );
1729 			continue;
1730 		}
1731 
1732 		if ( Q_stricmp( token.string, "cursor" ) == 0 ) {
1733 			if ( !PC_String_Parse( handle, &cgDC.Assets.cursorStr ) ) {
1734 				return qfalse;
1735 			}
1736 			cgDC.Assets.cursor = trap_R_RegisterShaderNoMip( cgDC.Assets.cursorStr );
1737 			continue;
1738 		}
1739 
1740 		if ( Q_stricmp( token.string, "fadeClamp" ) == 0 ) {
1741 			if ( !PC_Float_Parse( handle, &cgDC.Assets.fadeClamp ) ) {
1742 				return qfalse;
1743 			}
1744 			continue;
1745 		}
1746 
1747 		if ( Q_stricmp( token.string, "fadeCycle" ) == 0 ) {
1748 			if ( !PC_Int_Parse( handle, &cgDC.Assets.fadeCycle ) ) {
1749 				return qfalse;
1750 			}
1751 			continue;
1752 		}
1753 
1754 		if ( Q_stricmp( token.string, "fadeAmount" ) == 0 ) {
1755 			if ( !PC_Float_Parse( handle, &cgDC.Assets.fadeAmount ) ) {
1756 				return qfalse;
1757 			}
1758 			continue;
1759 		}
1760 
1761 		if ( Q_stricmp( token.string, "shadowX" ) == 0 ) {
1762 			if ( !PC_Float_Parse( handle, &cgDC.Assets.shadowX ) ) {
1763 				return qfalse;
1764 			}
1765 			continue;
1766 		}
1767 
1768 		if ( Q_stricmp( token.string, "shadowY" ) == 0 ) {
1769 			if ( !PC_Float_Parse( handle, &cgDC.Assets.shadowY ) ) {
1770 				return qfalse;
1771 			}
1772 			continue;
1773 		}
1774 
1775 		if ( Q_stricmp( token.string, "shadowColor" ) == 0 ) {
1776 			if ( !PC_Color_Parse( handle, &cgDC.Assets.shadowColor ) ) {
1777 				return qfalse;
1778 			}
1779 			cgDC.Assets.shadowFadeClamp = cgDC.Assets.shadowColor[3];
1780 			continue;
1781 		}
1782 	}
1783 	return qfalse;
1784 }
1785 
CG_ParseMenu(const char * menuFile)1786 void CG_ParseMenu( const char *menuFile ) {
1787 	pc_token_t token;
1788 	int handle;
1789 
1790 	handle = trap_PC_LoadSource( menuFile );
1791 	if ( !handle ) {
1792 		handle = trap_PC_LoadSource( "ui/testhud.menu" );
1793 	}
1794 	if ( !handle ) {
1795 		return;
1796 	}
1797 
1798 	while ( 1 ) {
1799 		if ( !trap_PC_ReadToken( handle, &token ) ) {
1800 			break;
1801 		}
1802 
1803 		//if ( Q_stricmp( token, "{" ) ) {
1804 		//	Com_Printf( "Missing { in menu file\n" );
1805 		//	break;
1806 		//}
1807 
1808 		//if ( menuCount == MAX_MENUS ) {
1809 		//	Com_Printf( "Too many menus!\n" );
1810 		//	break;
1811 		//}
1812 
1813 		if ( token.string[0] == '}' ) {
1814 			break;
1815 		}
1816 
1817 		if ( Q_stricmp( token.string, "assetGlobalDef" ) == 0 ) {
1818 			if ( CG_Asset_Parse( handle ) ) {
1819 				continue;
1820 			} else {
1821 				break;
1822 			}
1823 		}
1824 
1825 
1826 		if ( Q_stricmp( token.string, "menudef" ) == 0 ) {
1827 			// start a new menu
1828 			Menu_New( handle );
1829 		}
1830 	}
1831 	trap_PC_FreeSource( handle );
1832 }
1833 
CG_Load_Menu(char ** p)1834 qboolean CG_Load_Menu( char **p ) {
1835 	char *token;
1836 
1837 	token = COM_ParseExt( p, qtrue );
1838 
1839 	if ( token[0] != '{' ) {
1840 		return qfalse;
1841 	}
1842 
1843 	while ( 1 ) {
1844 
1845 		token = COM_ParseExt( p, qtrue );
1846 
1847 		if ( Q_stricmp( token, "}" ) == 0 ) {
1848 			return qtrue;
1849 		}
1850 
1851 		if ( !token[0] ) {
1852 			return qfalse;
1853 		}
1854 
1855 		CG_ParseMenu( token );
1856 	}
1857 	return qfalse;
1858 }
1859 
1860 
1861 
CG_LoadMenus(const char * menuFile)1862 void CG_LoadMenus( const char *menuFile ) {
1863 	char    *token;
1864 	char *p;
1865 	int len, start;
1866 	fileHandle_t f;
1867 	static char buf[MAX_MENUDEFFILE];
1868 
1869 	start = trap_Milliseconds();
1870 
1871 	len = trap_FS_FOpenFile( menuFile, &f, FS_READ );
1872 	if ( !f ) {
1873 		Com_Printf( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile );
1874 		len = trap_FS_FOpenFile( "ui/hud.txt", &f, FS_READ );
1875 		if ( !f ) {
1876 			CG_Error( S_COLOR_RED "default menu file not found: ui/hud.txt, unable to continue!" );
1877 		}
1878 	}
1879 
1880 	if ( len >= MAX_MENUDEFFILE ) {
1881 		trap_FS_FCloseFile( f );
1882 		CG_Error( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", menuFile, len, MAX_MENUDEFFILE );
1883 		return;
1884 	}
1885 
1886 	trap_FS_Read( buf, len, f );
1887 	buf[len] = 0;
1888 	trap_FS_FCloseFile( f );
1889 
1890 	COM_Compress( buf );
1891 
1892 	Menu_Reset();
1893 
1894 	p = buf;
1895 
1896 	while ( 1 ) {
1897 		token = COM_ParseExt( &p, qtrue );
1898 		if ( !token[0] || token[0] == '}' ) {
1899 			break;
1900 		}
1901 
1902 		//if ( Q_stricmp( token, "{" ) ) {
1903 		//	Com_Printf( "Missing { in menu file\n" );
1904 		//	break;
1905 		//}
1906 
1907 		//if ( menuCount == MAX_MENUS ) {
1908 		//	Com_Printf( "Too many menus!\n" );
1909 		//	break;
1910 		//}
1911 
1912 		if ( Q_stricmp( token, "}" ) == 0 ) {
1913 			break;
1914 		}
1915 
1916 		if ( Q_stricmp( token, "loadmenu" ) == 0 ) {
1917 			if ( CG_Load_Menu( &p ) ) {
1918 				continue;
1919 			} else {
1920 				break;
1921 			}
1922 		}
1923 	}
1924 
1925 	Com_Printf( "UI menu load time = %d milli seconds\n", trap_Milliseconds() - start );
1926 
1927 }
1928 
1929 
1930 
CG_OwnerDrawHandleKey(int ownerDraw,int flags,float * special,int key)1931 static qboolean CG_OwnerDrawHandleKey( int ownerDraw, int flags, float *special, int key ) {
1932 	return qfalse;
1933 }
1934 
1935 
CG_FeederCount(float feederID)1936 static int CG_FeederCount( float feederID ) {
1937 	int i, count;
1938 	count = 0;
1939 	if ( feederID == FEEDER_REDTEAM_LIST ) {
1940 		for ( i = 0; i < cg.numScores; i++ ) {
1941 			if ( cg.scores[i].team == TEAM_RED ) {
1942 				count++;
1943 			}
1944 		}
1945 	} else if ( feederID == FEEDER_BLUETEAM_LIST ) {
1946 		for ( i = 0; i < cg.numScores; i++ ) {
1947 			if ( cg.scores[i].team == TEAM_BLUE ) {
1948 				count++;
1949 			}
1950 		}
1951 	} else if ( feederID == FEEDER_SCOREBOARD ) {
1952 		return cg.numScores;
1953 	}
1954 	return count;
1955 }
1956 
1957 
1958 
1959 
1960 ///////////////////////////
1961 ///////////////////////////
1962 
CG_InfoFromScoreIndex(int index,int team,int * scoreIndex)1963 static clientInfo_t * CG_InfoFromScoreIndex( int index, int team, int *scoreIndex ) {
1964 	int i, count;
1965 	if ( cgs.gametype >= GT_TEAM ) {
1966 		count = 0;
1967 		for ( i = 0; i < cg.numScores; i++ ) {
1968 			if ( cg.scores[i].team == team ) {
1969 				if ( count == index ) {
1970 					*scoreIndex = i;
1971 					return &cgs.clientinfo[cg.scores[i].client];
1972 				}
1973 				count++;
1974 			}
1975 		}
1976 	}
1977 	*scoreIndex = index;
1978 	return &cgs.clientinfo[ cg.scores[index].client ];
1979 }
1980 
CG_FeederItemText(float feederID,int index,int column,qhandle_t * handle)1981 static const char *CG_FeederItemText( float feederID, int index, int column, qhandle_t *handle ) {
1982 #ifdef MISSIONPACK
1983 	gitem_t *item;
1984 #endif  // #ifdef MISSIONPACK
1985 	int scoreIndex = 0;
1986 	clientInfo_t *info = NULL;
1987 	int team = -1;
1988 	score_t *sp = NULL;
1989 
1990 	*handle = -1;
1991 
1992 	if ( feederID == FEEDER_REDTEAM_LIST ) {
1993 		team = TEAM_RED;
1994 	} else if ( feederID == FEEDER_BLUETEAM_LIST ) {
1995 		team = TEAM_BLUE;
1996 	}
1997 
1998 	info = CG_InfoFromScoreIndex( index, team, &scoreIndex );
1999 	sp = &cg.scores[scoreIndex];
2000 
2001 	if ( info && info->infoValid ) {
2002 		switch ( column ) {
2003 		case 0:
2004 #ifdef MISSIONPACK
2005 			if ( info->powerups & ( 1 << PW_NEUTRALFLAG ) ) {
2006 				item = BG_FindItemForPowerup( PW_NEUTRALFLAG );
2007 				*handle = cg_items[ ITEM_INDEX( item ) ].icon;
2008 			} else if ( info->powerups & ( 1 << PW_REDFLAG ) ) {
2009 				item = BG_FindItemForPowerup( PW_REDFLAG );
2010 				*handle = cg_items[ ITEM_INDEX( item ) ].icon;
2011 			} else if ( info->powerups & ( 1 << PW_BLUEFLAG ) ) {
2012 				item = BG_FindItemForPowerup( PW_BLUEFLAG );
2013 				*handle = cg_items[ ITEM_INDEX( item ) ].icon;
2014 			} else {
2015 				if ( info->botSkill > 0 && info->botSkill <= 5 ) {
2016 					*handle = cgs.media.botSkillShaders[ info->botSkill - 1 ];
2017 				} else if ( info->handicap < 100 ) {
2018 					return va( "%i", info->handicap );
2019 				}
2020 			}
2021 			break;
2022 		case 1:
2023 			if ( team == -1 ) {
2024 				return "";
2025 			} else {
2026 				*handle = CG_StatusHandle( info->teamTask );
2027 			}
2028 			break;
2029 		case 2:
2030 			if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << sp->client ) ) {
2031 				return "Ready";
2032 			}
2033 			if ( team == -1 ) {
2034 				if ( cgs.gametype == GT_TOURNAMENT ) {
2035 					return va( "%i/%i", info->wins, info->losses );
2036 				} else if ( info->infoValid && info->team == TEAM_SPECTATOR ) {
2037 					return "Spectator";
2038 				} else {
2039 					return "";
2040 				}
2041 			} else {
2042 				if ( info->teamLeader ) {
2043 					return "Leader";
2044 				}
2045 			}
2046 #endif  // #ifdef MISSIONPACK
2047 			break;
2048 		case 3:
2049 			return info->name;
2050 			break;
2051 		case 4:
2052 			return va( "%i", info->score );
2053 			break;
2054 		case 5:
2055 			return va( "%4i", sp->time );
2056 			break;
2057 		case 6:
2058 			if ( sp->ping == -1 ) {
2059 				return "connecting";
2060 			}
2061 			return va( "%4i", sp->ping );
2062 			break;
2063 		}
2064 	}
2065 
2066 	return "";
2067 }
2068 
CG_FeederItemImage(float feederID,int index)2069 static qhandle_t CG_FeederItemImage( float feederID, int index ) {
2070 	return 0;
2071 }
2072 
CG_FeederSelection(float feederID,int index)2073 static void CG_FeederSelection( float feederID, int index ) {
2074 	if ( cgs.gametype >= GT_TEAM ) {
2075 		int i, count;
2076 		int team = ( feederID == FEEDER_REDTEAM_LIST ) ? TEAM_RED : TEAM_BLUE;
2077 		count = 0;
2078 		for ( i = 0; i < cg.numScores; i++ ) {
2079 			if ( cg.scores[i].team == team ) {
2080 				if ( index == count ) {
2081 					cg.selectedScore = i;
2082 				}
2083 				count++;
2084 			}
2085 		}
2086 	} else {
2087 		cg.selectedScore = index;
2088 	}
2089 }
2090 
CG_Cvar_Get(const char * cvar)2091 static float CG_Cvar_Get( const char *cvar ) {
2092 	char buff[128];
2093 	memset( buff, 0, sizeof( buff ) );
2094 	trap_Cvar_VariableStringBuffer( cvar, buff, sizeof( buff ) );
2095 	return atof( buff );
2096 }
2097 
CG_Text_PaintWithCursor(float x,float y,int font,float scale,vec4_t color,const char * text,int cursorPos,char cursor,int limit,int style)2098 void CG_Text_PaintWithCursor( float x, float y, int font, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style ) {
2099 	CG_Text_Paint( x, y, font, scale, color, text, 0, limit, style );
2100 }
2101 
CG_OwnerDrawWidth(int ownerDraw,int font,float scale)2102 static int CG_OwnerDrawWidth( int ownerDraw, int font, float scale ) {
2103 	switch ( ownerDraw ) {
2104 	case CG_GAME_TYPE:
2105 		return CG_Text_Width( CG_GameTypeString(), font, scale, 0 );
2106 	case CG_GAME_STATUS:
2107 		return CG_Text_Width( CG_GetGameStatusText(), font, scale, 0 );
2108 		break;
2109 	case CG_KILLER:
2110 		return CG_Text_Width( CG_GetKillerText(), font, scale, 0 );
2111 		break;
2112 #ifdef MISSIONPACK
2113 	case CG_RED_NAME:
2114 		return CG_Text_Width( cg_redTeamName.string, font, scale, 0 );
2115 		break;
2116 	case CG_BLUE_NAME:
2117 		return CG_Text_Width( cg_blueTeamName.string, font, scale, 0 );
2118 		break;
2119 #endif
2120 
2121 	}
2122 	return 0;
2123 }
2124 
CG_PlayCinematic(const char * name,float x,float y,float w,float h)2125 static int CG_PlayCinematic( const char *name, float x, float y, float w, float h ) {
2126 	return trap_CIN_PlayCinematic( name, x, y, w, h, CIN_loop );
2127 }
2128 
CG_StopCinematic(int handle)2129 static void CG_StopCinematic( int handle ) {
2130 	trap_CIN_StopCinematic( handle );
2131 }
2132 
CG_DrawCinematic(int handle,float x,float y,float w,float h)2133 static void CG_DrawCinematic( int handle, float x, float y, float w, float h ) {
2134 	trap_CIN_SetExtents( handle, x, y, w, h );
2135 	trap_CIN_DrawCinematic( handle );
2136 }
2137 
CG_RunCinematicFrame(int handle)2138 static void CG_RunCinematicFrame( int handle ) {
2139 	trap_CIN_RunCinematic( handle );
2140 }
2141 
2142 
2143 
2144 /*
2145 ==============
2146 CG_translateString
2147 	presumably if this gets used more extensively, it'll be modified to a hash table
2148 ==============
2149 */
CG_translateString(const char * str)2150 const char *CG_translateString( const char *str ) {
2151 	int i, numStrings;
2152 
2153 	numStrings = sizeof( translateStrings ) / sizeof( translateStrings[0] ) - 1;
2154 
2155 	for ( i = 0; i < numStrings; i++ ) {
2156 		if ( !translateStrings[i].name || !strlen( translateStrings[i].name ) ) {
2157 			return str;
2158 		}
2159 
2160 		if ( !strcmp( str, translateStrings[i].name ) ) {
2161 			if ( translateStrings[i].localname && strlen( translateStrings[i].localname ) ) {
2162 				return translateStrings[i].localname;
2163 			}
2164 			break;
2165 		}
2166 	}
2167 
2168 	return str;
2169 }
2170 
2171 /*
2172 =================
2173 CG_LoadHudMenu
2174 
2175 =================
2176 */
CG_LoadHudMenu(void)2177 void CG_LoadHudMenu( void ) {
2178 	char buff[1024];
2179 	const char *hudSet;
2180 
2181 	cgDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip;
2182 	cgDC.setColor = &trap_R_SetColor;
2183 	cgDC.drawHandlePic = &CG_DrawPic;
2184 	cgDC.drawStretchPic = &trap_R_DrawStretchPic;
2185 	cgDC.drawText = &CG_Text_Paint;
2186 	cgDC.textWidth = &CG_Text_Width;
2187 	cgDC.textHeight = &CG_Text_Height;
2188 	cgDC.registerModel = &trap_R_RegisterModel;
2189 	cgDC.modelBounds = &trap_R_ModelBounds;
2190 	cgDC.fillRect = &CG_FillRect;
2191 	cgDC.drawRect = &CG_DrawRect;
2192 	cgDC.drawSides = &CG_DrawSides;
2193 	cgDC.drawTopBottom = &CG_DrawTopBottom;
2194 	cgDC.clearScene = &trap_R_ClearScene;
2195 	cgDC.addRefEntityToScene = &trap_R_AddRefEntityToScene;
2196 	cgDC.renderScene = &trap_R_RenderScene;
2197 	cgDC.registerFont = &trap_R_RegisterFont;
2198 	cgDC.ownerDrawItem = &CG_OwnerDraw;
2199 	cgDC.getValue = &CG_GetValue;
2200 	cgDC.ownerDrawVisible = &CG_OwnerDrawVisible;
2201 	cgDC.runScript = &CG_RunMenuScript;
2202 	cgDC.getTeamColor = &CG_GetTeamColor;
2203 	cgDC.setCVar = trap_Cvar_Set;
2204 	cgDC.getCVarString = trap_Cvar_VariableStringBuffer;
2205 	cgDC.getCVarValue = CG_Cvar_Get;
2206 	cgDC.drawTextWithCursor = &CG_Text_PaintWithCursor;
2207 	//cgDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode;
2208 	//cgDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode;
2209 	cgDC.startLocalSound = &trap_S_StartLocalSound;
2210 	cgDC.ownerDrawHandleKey = &CG_OwnerDrawHandleKey;
2211 	cgDC.feederCount = &CG_FeederCount;
2212 	cgDC.feederItemImage = &CG_FeederItemImage;
2213 	cgDC.feederItemText = &CG_FeederItemText;
2214 	cgDC.feederSelection = &CG_FeederSelection;
2215 	//cgDC.setBinding = &trap_Key_SetBinding;
2216 	//cgDC.getBindingBuf = &trap_Key_GetBindingBuf;
2217 	//cgDC.keynumToStringBuf = &trap_Key_KeynumToStringBuf;
2218 	cgDC.getTranslatedString = &CG_translateString;     //----(SA)	added
2219 	//cgDC.executeText = &trap_Cmd_ExecuteText;
2220 	cgDC.Error = &Com_Error;
2221 	cgDC.Print = &Com_Printf;
2222 	cgDC.ownerDrawWidth = &CG_OwnerDrawWidth;
2223 	//cgDC.Pause = &CG_Pause;
2224 	cgDC.registerSound = &trap_S_RegisterSound;
2225 	cgDC.startBackgroundTrack = &trap_S_StartBackgroundTrack;
2226 	cgDC.stopBackgroundTrack = &trap_S_StopBackgroundTrack;
2227 	cgDC.playCinematic = &CG_PlayCinematic;
2228 	cgDC.stopCinematic = &CG_StopCinematic;
2229 	cgDC.drawCinematic = &CG_DrawCinematic;
2230 	cgDC.runCinematicFrame = &CG_RunCinematicFrame;
2231 
2232 	Init_Display( &cgDC );
2233 
2234 	Menu_Reset();
2235 
2236 	trap_Cvar_VariableStringBuffer( "cg_hudFiles", buff, sizeof( buff ) );
2237 	hudSet = buff;
2238 	if ( hudSet[0] == '\0' ) {
2239 		hudSet = "ui/hud.txt";
2240 	}
2241 
2242 	CG_LoadMenus( hudSet );
2243 }
2244 
CG_AssetCache(void)2245 void CG_AssetCache( void ) {
2246 	//if (Assets.textFont == NULL) {
2247 	//  trap_R_RegisterFont("fonts/arial.ttf", 72, &Assets.textFont);
2248 	//}
2249 	//Assets.background = trap_R_RegisterShaderNoMip( ASSET_BACKGROUND );
2250 	//Com_Printf("Menu Size: %i bytes\n", sizeof(Menus));
2251 	cgDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR );
2252 	cgDC.Assets.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE );
2253 	cgDC.Assets.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED );
2254 	cgDC.Assets.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW );
2255 	cgDC.Assets.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_GREEN );
2256 	cgDC.Assets.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_TEAL );
2257 	cgDC.Assets.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_BLUE );
2258 	cgDC.Assets.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_CYAN );
2259 	cgDC.Assets.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE );
2260 	cgDC.Assets.scrollBar = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR );
2261 	cgDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN );
2262 	cgDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP );
2263 	cgDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT );
2264 	cgDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT );
2265 	cgDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip( ASSET_SCROLL_THUMB );
2266 	cgDC.Assets.sliderBar = trap_R_RegisterShaderNoMip( ASSET_SLIDER_BAR );
2267 	cgDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip( ASSET_SLIDER_THUMB );
2268 }
2269 
2270 
2271 /*
2272 =================
2273 CG_Init
2274 
2275 Called after every level change or subsystem restart
2276 Will perform callbacks to make the loading info screen update.
2277 =================
2278 */
CG_Init(int serverMessageNum,int serverCommandSequence)2279 void CG_Init( int serverMessageNum, int serverCommandSequence ) {
2280 	const char  *s;
2281 
2282 	// clear everything
2283 	memset( &cgs, 0, sizeof( cgs ) );
2284 	memset( &cg, 0, sizeof( cg ) );
2285 	memset( cg_entities, 0, sizeof( cg_entities ) );
2286 	memset( cg_weapons, 0, sizeof( cg_weapons ) );
2287 	memset( cg_items, 0, sizeof( cg_items ) );
2288 
2289 	// RF, init the anim scripting
2290 	cgs.animScriptData.soundIndex = CG_SoundScriptPrecache;
2291 	cgs.animScriptData.playSound = CG_SoundPlayIndexedScript;
2292 
2293 	cgs.processedSnapshotNum = serverMessageNum;
2294 	cgs.serverCommandSequence = serverCommandSequence;
2295 
2296 	// load a few needed things before we do any screen updates
2297 	// (SA) using Nerve's text since they have foreign characters
2298 	cgs.media.charsetShader     = trap_R_RegisterShader( "gfx/2d/hudchars" ); //trap_R_RegisterShader( "gfx/2d/bigchars" );
2299 	// JOSEPH 4-17-00
2300 	cgs.media.menucharsetShader = trap_R_RegisterShader( "gfx/2d/hudchars" );
2301 	// END JOSEPH
2302 	cgs.media.whiteShader       = trap_R_RegisterShader( "white" );
2303 	cgs.media.charsetProp       = trap_R_RegisterShaderNoMip( "menu/art/font1_prop.tga" );
2304 	cgs.media.charsetPropGlow   = trap_R_RegisterShaderNoMip( "menu/art/font1_prop_glo.tga" );
2305 	cgs.media.charsetPropB      = trap_R_RegisterShaderNoMip( "menu/art/font2_prop.tga" );
2306 
2307 	CG_RegisterCvars();
2308 
2309 	CG_InitConsoleCommands();
2310 
2311 //	cg.weaponSelect = WP_MP40;
2312 
2313 	// get the rendering configuration from the client system
2314 	trap_GetGlconfig( &cgs.glconfig );
2315 	if ( cg_fixedAspect.integer ) {
2316 		cgs.screenXScaleStretch = cgs.glconfig.vidWidth * (1.0/640.0);
2317 		cgs.screenYScaleStretch = cgs.glconfig.vidHeight * (1.0/480.0);
2318 		if ( cgs.glconfig.vidWidth * 480 > cgs.glconfig.vidHeight * 640 ) {
2319 			cgs.screenXScale = cgs.glconfig.vidWidth * (1.0/640.0);
2320 			cgs.screenYScale = cgs.glconfig.vidHeight * (1.0/480.0);
2321 			// wide screen
2322 			cgs.screenXBias = 0.5 * ( cgs.glconfig.vidWidth - ( cgs.glconfig.vidHeight * (640.0/480.0) ) );
2323 			cgs.screenXScale = cgs.screenYScale;
2324 			// no narrow screen
2325 			cgs.screenYBias = 0;
2326 		} else {
2327 			cgs.screenXScale = cgs.glconfig.vidWidth * (1.0/640.0);
2328 			cgs.screenYScale = cgs.glconfig.vidHeight * (1.0/480.0);
2329 			// narrow screen
2330 			cgs.screenYBias = 0.5 * ( cgs.glconfig.vidHeight - ( cgs.glconfig.vidWidth * (480.0/640.0) ) );
2331 			cgs.screenYScale = cgs.screenXScale;
2332 			// no wide screen
2333 			cgs.screenXBias = 0;
2334 		}
2335 	} else {
2336 		cgs.screenXScale = cgs.glconfig.vidWidth / 640.0;
2337 		cgs.screenYScale = cgs.glconfig.vidHeight / 480.0;
2338 	}
2339 
2340 	// get the gamestate from the client system
2341 	trap_GetGameState( &cgs.gameState );
2342 
2343 	// check version
2344 	s = CG_ConfigString( CS_GAME_VERSION );
2345 	if ( strcmp( s, GAME_VERSION ) ) {
2346 		CG_Error( "Client/Server game mismatch: %s/%s", GAME_VERSION, s );
2347 	}
2348 
2349 	s = CG_ConfigString( CS_LEVEL_START_TIME );
2350 	cgs.levelStartTime = atoi( s );
2351 
2352 	CG_ParseServerinfo();
2353 
2354 	// load the new map
2355 	CG_LoadingString( "collision map" );
2356 
2357 	trap_CM_LoadMap( cgs.mapname );
2358 
2359 	String_Init();
2360 
2361 	cg.loading = qtrue;     // force players to load instead of defer
2362 
2363 	CG_LoadingString( "sounds" );
2364 
2365 	CG_RegisterSounds();
2366 
2367 	CG_LoadingString( "graphics" );
2368 
2369 	CG_RegisterGraphics();
2370 
2371 	CG_LoadingString( "flamechunks" );
2372 
2373 	CG_InitFlameChunks();       // RF, register and clear all flamethrower resources
2374 
2375 	CG_LoadingString( "clients" );
2376 
2377 	CG_RegisterClients();       // if low on memory, some clients will be deferred
2378 
2379 	CG_AssetCache();
2380 	CG_LoadHudMenu();      // load new hud stuff
2381 
2382 	cg.loading = qfalse;    // future players will be deferred
2383 
2384 	CG_InitLocalEntities();
2385 
2386 	CG_InitMarkPolys();
2387 
2388 	// RF, init ZombieFX
2389 	trap_RB_ZombieFXAddNewHit( -1, NULL, NULL );
2390 
2391 	// remove the last loading update
2392 	cg.infoScreenText[0] = 0;
2393 
2394 	// Make sure we have update values (scores)
2395 	CG_SetConfigValues();
2396 
2397 	CG_StartMusic();
2398 
2399 	cg.lightstylesInited = qfalse;
2400 
2401 	CG_LoadingString( "" );
2402 
2403 	CG_ShaderStateChanged();
2404 
2405 	// RF, clear all sounds, so we dont hear anything after level load
2406 	trap_S_ClearLoopingSounds( 2 );
2407 
2408 	// start level load music
2409 	// too late...
2410 //	trap_S_StartBackgroundTrack( "sound/music/fla_mp03.wav", "sound/music/fla_mp03.wav", 1 );
2411 
2412 
2413 	// NERVE - SMF
2414 // JPW NERVE -- commented out 'cause this moved
2415 
2416 	if ( cgs.gametype == GT_WOLF ) {
2417 		trap_Cvar_Set( "cg_drawTimer", "0" ); // jpw
2418 	}
2419 	// jpw
2420 	// -NERVE - SMF
2421 }
2422 
2423 /*
2424 =================
2425 CG_Shutdown
2426 
2427 Called before every level change or subsystem restart
2428 =================
2429 */
CG_Shutdown(void)2430 void CG_Shutdown( void ) {
2431 	// some mods may need to do cleanup work here,
2432 	// like closing files or archiving session data
2433 }
2434 
CG_S_AddLoopingSound(int entityNum,const vec3_t origin,const vec3_t velocity,sfxHandle_t sfx,int volume)2435 void CG_S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx, int volume ) {
2436 	trap_S_AddLoopingSound( entityNum, origin, velocity, 1250, sfx, volume );	// volume was previously removed from CG_S_ADDLOOPINGSOUND. I added 'range'
2437 }
2438 
CG_S_AddRangedLoopingSound(int entityNum,const vec3_t origin,const vec3_t velocity,sfxHandle_t sfx,int range)2439 void CG_S_AddRangedLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx, int range ) {
2440 	trap_S_AddLoopingSound( entityNum, origin, velocity, range, sfx, 255 );		// RF, assume full volume, since thats how it worked before
2441 }
2442 
CG_S_AddRealLoopingSound(int entityNum,const vec3_t origin,const vec3_t velocity,sfxHandle_t sfx)2443 void CG_S_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ) {
2444 	//trap_S_AddRealLoopingSound( entityNum, origin, velocity, 1250, sfx, 255 );	//----(SA) modified
2445 }
2446