codemp/cgame/cg_main.c

Go to the documentation of this file.
00001 // Copyright (C) 1999-2000 Id Software, Inc.
00002 //
00003 // cg_main.c -- initialization and primary entry point for cgame
00004 #include "cg_local.h"
00005 
00006 #include "../ui/ui_shared.h"
00007 // display context for new ui stuff
00008 displayContextDef_t cgDC;
00009 
00010 #if !defined(CL_LIGHT_H_INC)
00011         #include "cg_lights.h"
00012 #endif
00013 
00014 extern int cgSiegeRoundState;
00015 extern int cgSiegeRoundTime;
00016 /*
00017 Ghoul2 Insert Start
00018 */
00019 void CG_InitItems(void);
00020 /*
00021 Ghoul2 Insert End
00022 */
00023 
00024 void CG_InitJetpackGhoul2(void);
00025 void CG_CleanJetpackGhoul2(void);
00026 
00027 vec4_t colorTable[CT_MAX] = 
00028 {
00029 {0, 0, 0, 0},                   // CT_NONE
00030 {0, 0, 0, 1},                   // CT_BLACK
00031 {1, 0, 0, 1},                   // CT_RED
00032 {0, 1, 0, 1},                   // CT_GREEN
00033 {0, 0, 1, 1},                   // CT_BLUE
00034 {1, 1, 0, 1},                   // CT_YELLOW
00035 {1, 0, 1, 1},                   // CT_MAGENTA
00036 {0, 1, 1, 1},                   // CT_CYAN
00037 {1, 1, 1, 1},                   // CT_WHITE
00038 {0.75f, 0.75f, 0.75f, 1},       // CT_LTGREY
00039 {0.50f, 0.50f, 0.50f, 1},       // CT_MDGREY
00040 {0.25f, 0.25f, 0.25f, 1},       // CT_DKGREY
00041 {0.15f, 0.15f, 0.15f, 1},       // CT_DKGREY2
00042 
00043 {0.810f, 0.530f, 0.0f,  1},     // CT_VLTORANGE -- needs values
00044 {0.810f, 0.530f, 0.0f,  1},     // CT_LTORANGE
00045 {0.610f, 0.330f, 0.0f,  1},     // CT_DKORANGE
00046 {0.402f, 0.265f, 0.0f,  1},     // CT_VDKORANGE
00047 
00048 {0.503f, 0.375f, 0.996f, 1},    // CT_VLTBLUE1
00049 {0.367f, 0.261f, 0.722f, 1},    // CT_LTBLUE1
00050 {0.199f, 0.0f,   0.398f, 1},    // CT_DKBLUE1
00051 {0.160f, 0.117f, 0.324f, 1},    // CT_VDKBLUE1
00052 
00053 {0.300f, 0.628f, 0.816f, 1},    // CT_VLTBLUE2 -- needs values
00054 {0.300f, 0.628f, 0.816f, 1},    // CT_LTBLUE2
00055 {0.191f, 0.289f, 0.457f, 1},    // CT_DKBLUE2
00056 {0.125f, 0.250f, 0.324f, 1},    // CT_VDKBLUE2
00057 
00058 {0.796f, 0.398f, 0.199f, 1},    // CT_VLTBROWN1 -- needs values
00059 {0.796f, 0.398f, 0.199f, 1},    // CT_LTBROWN1
00060 {0.558f, 0.207f, 0.027f, 1},    // CT_DKBROWN1
00061 {0.328f, 0.125f, 0.035f, 1},    // CT_VDKBROWN1
00062 
00063 {0.996f, 0.796f, 0.398f, 1},    // CT_VLTGOLD1 -- needs values
00064 {0.996f, 0.796f, 0.398f, 1},    // CT_LTGOLD1
00065 {0.605f, 0.441f, 0.113f, 1},    // CT_DKGOLD1
00066 {0.386f, 0.308f, 0.148f, 1},    // CT_VDKGOLD1
00067 
00068 {0.648f, 0.562f, 0.784f, 1},    // CT_VLTPURPLE1 -- needs values
00069 {0.648f, 0.562f, 0.784f, 1},    // CT_LTPURPLE1
00070 {0.437f, 0.335f, 0.597f, 1},    // CT_DKPURPLE1
00071 {0.308f, 0.269f, 0.375f, 1},    // CT_VDKPURPLE1
00072 
00073 {0.816f, 0.531f, 0.710f, 1},    // CT_VLTPURPLE2 -- needs values
00074 {0.816f, 0.531f, 0.710f, 1},    // CT_LTPURPLE2
00075 {0.566f, 0.269f, 0.457f, 1},    // CT_DKPURPLE2
00076 {0.343f, 0.226f, 0.316f, 1},    // CT_VDKPURPLE2
00077 
00078 {0.929f, 0.597f, 0.929f, 1},    // CT_VLTPURPLE3
00079 {0.570f, 0.371f, 0.570f, 1},    // CT_LTPURPLE3
00080 {0.355f, 0.199f, 0.355f, 1},    // CT_DKPURPLE3
00081 {0.285f, 0.136f, 0.230f, 1},    // CT_VDKPURPLE3
00082 
00083 {0.953f, 0.378f, 0.250f, 1},    // CT_VLTRED1
00084 {0.953f, 0.378f, 0.250f, 1},    // CT_LTRED1
00085 {0.593f, 0.121f, 0.109f, 1},    // CT_DKRED1
00086 {0.429f, 0.171f, 0.113f, 1},    // CT_VDKRED1
00087 {.25f, 0, 0, 1},                                        // CT_VDKRED
00088 {.70f, 0, 0, 1},                                        // CT_DKRED
00089         
00090 {0.717f, 0.902f, 1.0f,   1},            // CT_VLTAQUA
00091 {0.574f, 0.722f, 0.804f, 1},            // CT_LTAQUA
00092 {0.287f, 0.361f, 0.402f, 1},            // CT_DKAQUA
00093 {0.143f, 0.180f, 0.201f, 1},            // CT_VDKAQUA
00094 
00095 {0.871f, 0.386f, 0.375f, 1},            // CT_LTPINK
00096 {0.435f, 0.193f, 0.187f, 1},            // CT_DKPINK
00097 {         0,    .5f,    .5f, 1},                // CT_LTCYAN
00098 {         0,   .25f,   .25f, 1},                // CT_DKCYAN
00099 {   .179f, .51f,   .92f, 1},            // CT_LTBLUE3
00100 {   .199f, .71f,   .92f, 1},            // CT_LTBLUE3
00101 {   .5f,   .05f,    .4f, 1},            // CT_DKBLUE3
00102 
00103 {   0.0f,   .613f,  .097f, 1},          // CT_HUD_GREEN
00104 {   0.835f, .015f,  .015f, 1},          // CT_HUD_RED
00105 {       .567f,  .685f,  1.0f,   .75f},  // CT_ICON_BLUE
00106 {       .515f,  .406f,  .507f,  1},             // CT_NO_AMMO_RED
00107 {   1.0f,   .658f,  .062f, 1},          // CT_HUD_ORANGE
00108 
00109 };
00110 
00111 #include "holocronicons.h"
00112 
00113 int cgWeatherOverride = 0;
00114 
00115 int forceModelModificationCount = -1;
00116 
00117 void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum );
00118 void CG_Shutdown( void );
00119 
00120 void CG_CalcEntityLerpPositions( centity_t *cent );
00121 void CG_ROFF_NotetrackCallback( centity_t *cent, const char *notetrack);
00122 
00123 #include "../namespace_begin.h"
00124 void UI_CleanupGhoul2(void);
00125 #include "../namespace_end.h"
00126 
00127 static int      C_PointContents(void);
00128 static void C_GetLerpOrigin(void);
00129 static void C_GetLerpData(void);
00130 static void C_Trace(void);
00131 static void C_G2Trace(void);
00132 static void C_G2Mark(void);
00133 static int      CG_RagCallback(int callType);
00134 static void C_GetBoltPos(void);
00135 static void C_ImpactMark(void);
00136 
00137 #ifdef _XBOX
00138 #define MAX_MISC_ENTS   500
00139 #else
00140 #define MAX_MISC_ENTS   4000
00141 #endif
00142 
00143 //static refEntity_t    *MiscEnts = 0;
00144 //static float          *Radius = 0;
00145 static refEntity_t      MiscEnts[MAX_MISC_ENTS]; //statically allocated for now.
00146 static float            Radius[MAX_MISC_ENTS];
00147 static float            zOffset[MAX_MISC_ENTS]; //some models need a z offset for culling, because of stupid wrong model origins
00148 
00149 static int                      NumMiscEnts = 0;
00150 
00151 extern autoMapInput_t cg_autoMapInput; //cg_view.c
00152 extern int cg_autoMapInputTime;
00153 extern vec3_t cg_autoMapAngle;
00154 
00155 void CG_MiscEnt(void);
00156 void CG_DoCameraShake( vec3_t origin, float intensity, int radius, int time );
00157 
00158 //do we have any force powers that we would normally need to cycle to?
00159 qboolean CG_NoUseableForce(void)
00160 {
00161         int i = FP_HEAL;
00162         while (i < NUM_FORCE_POWERS)
00163         {
00164                 if (i != FP_SABERTHROW &&
00165                         i != FP_SABER_OFFENSE &&
00166                         i != FP_SABER_DEFENSE &&
00167                         i != FP_LEVITATION)
00168                 { //valid selectable power
00169                         if (cg.predictedPlayerState.fd.forcePowersKnown & (1 << i))
00170                         { //we have it
00171                                 return qfalse;
00172                         }
00173                 }
00174                 i++;
00175         }
00176 
00177         //no useable force powers, I guess.
00178         return qtrue;
00179 }
00180 
00181 /*
00182 ================
00183 vmMain
00184 
00185 This is the only way control passes into the module.
00186 This must be the very first function compiled into the .q3vm file
00187 ================
00188 */
00189 #include "../namespace_begin.h"
00190 int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11  ) {
00191 
00192         switch ( command ) {
00193         case CG_INIT:
00194                 CG_Init( arg0, arg1, arg2 );
00195                 return 0;
00196         case CG_SHUTDOWN:
00197                 CG_Shutdown();
00198                 return 0;
00199         case CG_CONSOLE_COMMAND:
00200                 return CG_ConsoleCommand();
00201         case CG_DRAW_ACTIVE_FRAME:
00202                 CG_DrawActiveFrame( arg0, arg1, arg2 );
00203                 return 0;
00204         case CG_CROSSHAIR_PLAYER:
00205                 return CG_CrosshairPlayer();
00206         case CG_LAST_ATTACKER:
00207                 return CG_LastAttacker();
00208         case CG_KEY_EVENT:
00209                 CG_KeyEvent(arg0, arg1);
00210                 return 0;
00211         case CG_MOUSE_EVENT:
00212                 cgDC.cursorx = cgs.cursorX;
00213                 cgDC.cursory = cgs.cursorY;
00214                 CG_MouseEvent(arg0, arg1);
00215                 return 0;
00216         case CG_EVENT_HANDLING:
00217                 CG_EventHandling(arg0);
00218                 return 0;
00219 
00220         case CG_POINT_CONTENTS:
00221                 return C_PointContents();
00222 
00223         case CG_GET_LERP_ORIGIN:
00224                 C_GetLerpOrigin();
00225                 return 0;
00226 
00227         case CG_GET_LERP_DATA:
00228                 C_GetLerpData();
00229                 return 0;
00230 
00231         case CG_GET_GHOUL2:
00232                 return (int)cg_entities[arg0].ghoul2; //NOTE: This is used by the effect bolting which is actually not used at all.
00233                                                                                           //I'm fairly sure if you try to use it with vm's it will just give you total
00234                                                                                           //garbage. In other words, use at your own risk.
00235 
00236         case CG_GET_MODEL_LIST:
00237                 return (int)cgs.gameModels;
00238 
00239         case CG_CALC_LERP_POSITIONS:
00240                 CG_CalcEntityLerpPositions( &cg_entities[arg0] );
00241                 return 0;
00242 
00243         case CG_TRACE:
00244                 C_Trace();
00245                 return 0;
00246         case CG_GET_SORTED_FORCE_POWER:
00247                 return forcePowerSorted[arg0];
00248         case CG_G2TRACE:
00249                 C_G2Trace();
00250                 return 0;
00251 
00252         case CG_G2MARK:
00253                 C_G2Mark();
00254                 return 0;
00255 
00256         case CG_RAG_CALLBACK:
00257                 return CG_RagCallback(arg0);
00258 
00259         case CG_INCOMING_CONSOLE_COMMAND:
00260                 //rww - let mod authors filter client console messages so they can cut them off if they want.
00261                 //return 1 if the command is ok. Otherwise, you can set char 0 on the command str to 0 and return
00262                 //0 to not execute anything, or you can fill conCommand in with something valid and return 0
00263                 //in order to have that string executed in place. Some example code:
00264 #if 0
00265                 {
00266                         TCGIncomingConsoleCommand       *icc = (TCGIncomingConsoleCommand *)cg.sharedBuffer;
00267                         if (strstr(icc->conCommand, "wait"))
00268                         { //filter out commands contaning wait
00269                                 Com_Printf("You can't use commands containing the string wait with MyMod v1.0\n");
00270                                 icc->conCommand[0] = 0;
00271                                 return 0;
00272                         }
00273                         else if (strstr(icc->conCommand, "blah"))
00274                         { //any command containing the string "blah" is redirected to "quit"
00275                                 strcpy(icc->conCommand, "quit");
00276                                 return 0;
00277                         }
00278                 }
00279 #endif
00280                 return 1;
00281 
00282         case CG_GET_USEABLE_FORCE:
00283                 return CG_NoUseableForce();
00284 
00285         case CG_GET_ORIGIN:
00286                 VectorCopy(cg_entities[arg0].currentState.pos.trBase, (float *)arg1);
00287                 return 0;
00288 
00289         case CG_GET_ANGLES:
00290                 VectorCopy(cg_entities[arg0].currentState.apos.trBase, (float *)arg1);
00291                 return 0;
00292 
00293         case CG_GET_ORIGIN_TRAJECTORY:
00294                 return (int)&cg_entities[arg0].nextState.pos;
00295 
00296         case CG_GET_ANGLE_TRAJECTORY:
00297                 return (int)&cg_entities[arg0].nextState.apos;
00298 
00299         case CG_ROFF_NOTETRACK_CALLBACK:
00300                 CG_ROFF_NotetrackCallback( &cg_entities[arg0], (const char *)arg1 );
00301                 return 0;
00302 
00303         case CG_IMPACT_MARK:
00304                 C_ImpactMark();
00305                 return 0;
00306 
00307         case CG_MAP_CHANGE:
00308                 // this trap map be called more than once for a given map change, as the
00309                 // server is going to attempt to send out multiple broadcasts in hopes that
00310                 // the client will receive one of them
00311                 cg.mMapChange = qtrue;
00312                 return 0;
00313 
00314         case CG_AUTOMAP_INPUT:
00315                 //special input during automap mode -rww
00316                 {
00317                         autoMapInput_t *autoInput = (autoMapInput_t *)cg.sharedBuffer;
00318 
00319                         memcpy(&cg_autoMapInput, autoInput, sizeof(autoMapInput_t));
00320 
00321                         if (!arg0)
00322                         { //if this is non-0, it's actually a one-frame mouse event
00323                                 cg_autoMapInputTime = cg.time + 1000;
00324                         }
00325                         else
00326                         {
00327                                 if (cg_autoMapInput.yaw)
00328                                 {
00329                                         cg_autoMapAngle[YAW] += cg_autoMapInput.yaw;
00330                                 }
00331 
00332                                 if (cg_autoMapInput.pitch)
00333                                 {
00334                                         cg_autoMapAngle[PITCH] += cg_autoMapInput.pitch;
00335                                 }
00336                                 cg_autoMapInput.yaw = 0.0f;
00337                                 cg_autoMapInput.pitch = 0.0f;
00338                         }
00339                 }
00340                 return 0;
00341 
00342         case CG_MISC_ENT:
00343                 CG_MiscEnt();
00344                 return 0;
00345 
00346         case CG_FX_CAMERASHAKE:
00347                 {
00348                         TCGCameraShake  *data = (TCGCameraShake *)cg.sharedBuffer;
00349                         
00350                         CG_DoCameraShake( data->mOrigin, data->mIntensity, data->mRadius, data->mTime );
00351                 }
00352                 return 0;
00353 
00354         default:
00355                 CG_Error( "vmMain: unknown command %i", command );
00356                 break;
00357         }
00358         return -1;
00359 }
00360 #include "../namespace_end.h"
00361 
00362 static int C_PointContents(void)
00363 {
00364         TCGPointContents        *data = (TCGPointContents *)cg.sharedBuffer;
00365 
00366         return CG_PointContents( data->mPoint, data->mPassEntityNum );
00367 }
00368 
00369 static void C_GetLerpOrigin(void)
00370 {
00371         TCGVectorData           *data = (TCGVectorData *)cg.sharedBuffer;
00372 
00373         VectorCopy(cg_entities[data->mEntityNum].lerpOrigin, data->mPoint);
00374 }
00375 
00376 static void C_GetLerpData(void)
00377 {//only used by FX system to pass to getboltmat
00378         TCGGetBoltData          *data = (TCGGetBoltData *)cg.sharedBuffer;
00379 
00380         VectorCopy(cg_entities[data->mEntityNum].lerpOrigin, data->mOrigin);
00381         VectorCopy(cg_entities[data->mEntityNum].modelScale, data->mScale);
00382         VectorCopy(cg_entities[data->mEntityNum].lerpAngles, data->mAngles);
00383         if (cg_entities[data->mEntityNum].currentState.eType == ET_PLAYER)
00384         { //normal player
00385                 data->mAngles[PITCH] = 0.0f;
00386                 data->mAngles[ROLL] = 0.0f;
00387         }
00388         else if (cg_entities[data->mEntityNum].currentState.eType == ET_NPC)
00389         { //an NPC
00390                 Vehicle_t *pVeh = cg_entities[data->mEntityNum].m_pVehicle;
00391                 if (!pVeh)
00392                 { //for vehicles, we may or may not want to 0 out pitch and roll
00393                         data->mAngles[PITCH] = 0.0f;
00394                         data->mAngles[ROLL] = 0.0f;
00395                 }
00396                 else if (pVeh->m_pVehicleInfo->type == VH_SPEEDER)
00397                 { //speeder wants no pitch but a roll
00398                         data->mAngles[PITCH] = 0.0f;
00399                 }
00400                 else if (pVeh->m_pVehicleInfo->type != VH_FIGHTER)
00401                 { //fighters want all angles
00402                         data->mAngles[PITCH] = 0.0f;
00403                         data->mAngles[ROLL] = 0.0f;
00404                 }
00405         }
00406 }
00407 
00408 static void C_Trace(void)
00409 {
00410         TCGTrace        *td = (TCGTrace *)cg.sharedBuffer;
00411 
00412         CG_Trace(&td->mResult, td->mStart, td->mMins, td->mMaxs, td->mEnd, td->mSkipNumber, td->mMask);
00413 }
00414 
00415 static void C_G2Trace(void)
00416 {
00417         TCGTrace        *td = (TCGTrace *)cg.sharedBuffer;
00418 
00419         CG_G2Trace(&td->mResult, td->mStart, td->mMins, td->mMaxs, td->mEnd, td->mSkipNumber, td->mMask);
00420 }
00421 
00422 static void C_G2Mark(void)
00423 {
00424         TCGG2Mark       *td = (TCGG2Mark *)cg.sharedBuffer;
00425         trace_t         tr;
00426         vec3_t          end;
00427 
00428         VectorMA(td->start, 64, td->dir, end);
00429         CG_G2Trace(&tr, td->start, NULL, NULL, end, ENTITYNUM_NONE, MASK_PLAYERSOLID);
00430 
00431         if (tr.entityNum < ENTITYNUM_WORLD &&
00432                 cg_entities[tr.entityNum].ghoul2)
00433         { //hit someone with a ghoul2 instance, let's project the decal on them then.
00434                 centity_t *cent = &cg_entities[tr.entityNum];
00435 
00436                 //CG_TestLine(tr.endpos, end, 2000, 0x0000ff, 1);
00437 
00438                 CG_AddGhoul2Mark(td->shader, td->size, tr.endpos, end, tr.entityNum,
00439                         cent->lerpOrigin, cent->lerpAngles[YAW], cent->ghoul2, cent->modelScale,
00440                         Q_irand(2000, 4000));
00441                 //I'm making fx system decals have a very short lifetime.
00442         }
00443 }
00444 
00445 static void CG_DebugBoxLines(vec3_t mins, vec3_t maxs, int duration)
00446 {
00447         vec3_t start;
00448         vec3_t end;
00449         vec3_t vert;
00450 
00451         float x = maxs[0] - mins[0];
00452         float y = maxs[1] - mins[1];
00453 
00454         start[2] = maxs[2];
00455         vert[2] = mins[2];
00456 
00457         vert[0] = mins[0];
00458         vert[1] = mins[1];
00459         start[0] = vert[0];
00460         start[1] = vert[1];
00461         CG_TestLine(start, vert, duration, 0x00000ff, 1);
00462 
00463         vert[0] = mins[0];
00464         vert[1] = maxs[1];
00465         start[0] = vert[0];
00466         start[1] = vert[1];
00467         CG_TestLine(start, vert, duration, 0x00000ff, 1);
00468 
00469         vert[0] = maxs[0];
00470         vert[1] = mins[1];
00471         start[0] = vert[0];
00472         start[1] = vert[1];
00473         CG_TestLine(start, vert, duration, 0x00000ff, 1);
00474 
00475         vert[0] = maxs[0];
00476         vert[1] = maxs[1];
00477         start[0] = vert[0];
00478         start[1] = vert[1];
00479         CG_TestLine(start, vert, duration, 0x00000ff, 1);
00480 
00481         // top of box
00482         VectorCopy(maxs, start);
00483         VectorCopy(maxs, end);
00484         start[0] -= x;
00485         CG_TestLine(start, end, duration, 0x00000ff, 1);
00486         end[0] = start[0];
00487         end[1] -= y;
00488         CG_TestLine(start, end, duration, 0x00000ff, 1);
00489         start[1] = end[1];
00490         start[0] += x;
00491         CG_TestLine(start, end, duration, 0x00000ff, 1);
00492         CG_TestLine(start, maxs, duration, 0x00000ff, 1);
00493         // bottom of box
00494         VectorCopy(mins, start);
00495         VectorCopy(mins, end);
00496         start[0] += x;
00497         CG_TestLine(start, end, duration, 0x00000ff, 1);
00498         end[0] = start[0];
00499         end[1] += y;
00500         CG_TestLine(start, end, duration, 0x00000ff, 1);
00501         start[1] = end[1];
00502         start[0] -= x;
00503         CG_TestLine(start, end, duration, 0x00000ff, 1);
00504         CG_TestLine(start, mins, duration, 0x00000ff, 1);
00505 }
00506 
00507 //handle ragdoll callbacks, for events and debugging -rww
00508 static int CG_RagCallback(int callType)
00509 {
00510         switch(callType)
00511         {
00512         case RAG_CALLBACK_DEBUGBOX:
00513                 {
00514                         ragCallbackDebugBox_t *callData = (ragCallbackDebugBox_t *)cg.sharedBuffer;
00515 
00516                         CG_DebugBoxLines(callData->mins, callData->maxs, callData->duration);
00517                 }
00518                 break;
00519         case RAG_CALLBACK_DEBUGLINE:
00520                 {
00521                         ragCallbackDebugLine_t *callData = (ragCallbackDebugLine_t *)cg.sharedBuffer;
00522 
00523                         CG_TestLine(callData->start, callData->end, callData->time, callData->color, callData->radius);
00524                 }
00525                 break;
00526         case RAG_CALLBACK_BONESNAP:
00527                 {
00528                         ragCallbackBoneSnap_t *callData = (ragCallbackBoneSnap_t *)cg.sharedBuffer;
00529                         centity_t *cent = &cg_entities[callData->entNum];
00530                         int snapSound = trap_S_RegisterSound(va("sound/player/bodyfall_human%i.wav", Q_irand(1, 3)));
00531 
00532                         trap_S_StartSound(cent->lerpOrigin, callData->entNum, CHAN_AUTO, snapSound);
00533                 }
00534         case RAG_CALLBACK_BONEIMPACT:
00535                 break;
00536         case RAG_CALLBACK_BONEINSOLID:
00537 #if 0
00538                 {
00539                         ragCallbackBoneInSolid_t *callData = (ragCallbackBoneInSolid_t *)cg.sharedBuffer;
00540 
00541                         if (callData->solidCount > 16)
00542                         { //don't bother if we're just tapping into solidity, we'll probably recover on our own
00543                                 centity_t *cent = &cg_entities[callData->entNum];
00544                                 vec3_t slideDir;
00545 
00546                                 VectorSubtract(cent->lerpOrigin, callData->bonePos, slideDir);
00547                                 VectorAdd(cent->ragOffsets, slideDir, cent->ragOffsets);
00548 
00549                                 cent->hasRagOffset = qtrue;
00550                         }
00551                 }
00552 #endif
00553                 break;
00554         case RAG_CALLBACK_TRACELINE:
00555                 {
00556                         ragCallbackTraceLine_t *callData = (ragCallbackTraceLine_t *)cg.sharedBuffer;
00557 
00558                         CG_Trace(&callData->tr, callData->start, callData->mins, callData->maxs,
00559                                 callData->end, callData->ignore, callData->mask);
00560                 }
00561                 break;
00562         default:
00563                 Com_Error(ERR_DROP, "Invalid callType in CG_RagCallback");
00564                 break;
00565         }
00566 
00567         return 0;
00568 }
00569 
00570 static void C_ImpactMark(void)
00571 {
00572         TCGImpactMark   *data = (TCGImpactMark *)cg.sharedBuffer;
00573 
00574         /*
00575         CG_ImpactMark((int)arg0, (const float *)arg1, (const float *)arg2, (float)arg3,
00576                 (float)arg4, (float)arg5, (float)arg6, (float)arg7, qtrue, (float)arg8, qfalse);
00577         */
00578         CG_ImpactMark(data->mHandle, data->mPoint, data->mAngle, data->mRotation,
00579                 data->mRed, data->mGreen, data->mBlue, data->mAlphaStart, qtrue, data->mSizeStart, qfalse);
00580 }
00581 
00582 void CG_MiscEnt(void)
00583 {
00584         int                     modelIndex;
00585         refEntity_t     *RefEnt;
00586         TCGMiscEnt      *data = (TCGMiscEnt *)cg.sharedBuffer;
00587         vec3_t          mins, maxs;
00588         float           *radius, *zOff;
00589 
00590         if (NumMiscEnts >= MAX_MISC_ENTS)
00591         {
00592                 return;
00593         }
00594         
00595         radius = &Radius[NumMiscEnts];
00596         zOff = &zOffset[NumMiscEnts];
00597         RefEnt = &MiscEnts[NumMiscEnts++];
00598 
00599         modelIndex = trap_R_RegisterModel(data->mModel);
00600         if (modelIndex == 0)
00601         {
00602                 Com_Error(ERR_DROP, "client_model has invalid model definition");
00603                 return;
00604         }
00605 
00606         *zOff = 0;
00607 
00608         memset(RefEnt, 0, sizeof(refEntity_t));
00609         RefEnt->reType = RT_MODEL;
00610         RefEnt->hModel = modelIndex;
00611         RefEnt->frame = 0;
00612         trap_R_ModelBounds(modelIndex, mins, maxs);
00613         VectorCopy(data->mScale, RefEnt->modelScale);
00614         VectorCopy(data->mOrigin, RefEnt->origin);
00615 
00616         VectorScaleVector(mins, data->mScale, mins);
00617         VectorScaleVector(maxs, data->mScale, maxs);
00618         *radius = Distance(mins, maxs);
00619 
00620         AnglesToAxis( data->mAngles, RefEnt->axis );
00621         ScaleModelAxis(RefEnt);
00622 }
00623 
00624 void CG_DrawMiscEnts(void)
00625 {
00626         int                     i;
00627         refEntity_t     *RefEnt;
00628         float           *radius, *zOff;
00629         vec3_t          difference;
00630         vec3_t          cullOrigin;
00631 
00632         RefEnt = MiscEnts;
00633         radius = Radius;
00634         zOff = zOffset;
00635         for(i=0;i<NumMiscEnts;i++)
00636         {
00637                 VectorCopy(RefEnt->origin, cullOrigin);
00638                 cullOrigin[2] += 1.0f;
00639 
00640                 if (*zOff)
00641                 {
00642                         cullOrigin[2] += *zOff;
00643                 }
00644 
00645                 if (cg.snap && trap_R_inPVS(cg.refdef.vieworg, cullOrigin, cg.snap->areamask))
00646                 {
00647                         VectorSubtract(RefEnt->origin, cg.refdef.vieworg, difference);
00648                         if (VectorLength(difference)-(*radius) <= cg.distanceCull)
00649                         {
00650                                 trap_R_AddRefEntityToScene(RefEnt);
00651                         }
00652                 }
00653                 RefEnt++;
00654                 radius++;
00655                 zOff++;
00656         }
00657 }
00658 
00659 /*
00660 Ghoul2 Insert Start
00661 */
00662 /*
00663 void CG_ResizeG2Bolt(boltInfo_v *bolt, int newCount)
00664 {
00665         bolt->resize(newCount);
00666 }
00667 
00668 void CG_ResizeG2Surface(surfaceInfo_v *surface, int newCount)
00669 {
00670         surface->resize(newCount);
00671 }
00672 
00673 void CG_ResizeG2Bone(boneInfo_v *bone, int newCount)
00674 {
00675         bone->resize(newCount);
00676 }
00677 
00678 void CG_ResizeG2(CGhoul2Info_v *ghoul2, int newCount)
00679 {
00680         ghoul2->resize(newCount);
00681 }
00682 
00683 void CG_ResizeG2TempBone(mdxaBone_v *tempBone, int newCount)
00684 {
00685         tempBone->resize(newCount);
00686 }
00687 */
00688 /*
00689 Ghoul2 Insert End
00690 */
00691 cg_t                            cg;
00692 cgs_t                           cgs;
00693 centity_t                       cg_entities[MAX_GENTITIES];
00694 
00695 centity_t                       *cg_permanents[MAX_GENTITIES]; //rwwRMG - added
00696 int                                     cg_numpermanents = 0;
00697 
00698 weaponInfo_t            cg_weapons[MAX_WEAPONS];
00699 itemInfo_t                      cg_items[MAX_ITEMS];
00700 
00701 
00702 vmCvar_t        cg_centertime;
00703 vmCvar_t        cg_runpitch;
00704 vmCvar_t        cg_runroll;
00705 vmCvar_t        cg_bobup;
00706 vmCvar_t        cg_bobpitch;
00707 vmCvar_t        cg_bobroll;
00708 //vmCvar_t      cg_swingSpeed;
00709 vmCvar_t        cg_shadows;
00710 vmCvar_t        cg_renderToTextureFX;
00711 vmCvar_t        cg_drawTimer;
00712 vmCvar_t        cg_drawFPS;
00713 vmCvar_t        cg_drawSnapshot;
00714 vmCvar_t        cg_draw3dIcons;
00715 vmCvar_t        cg_drawIcons;
00716 vmCvar_t        cg_drawAmmoWarning;
00717 vmCvar_t        cg_drawCrosshair;
00718 vmCvar_t        cg_drawCrosshairNames;
00719 vmCvar_t        cg_drawRadar;
00720 vmCvar_t        cg_drawVehLeadIndicator;
00721 vmCvar_t        cg_dynamicCrosshair;
00722 vmCvar_t        cg_dynamicCrosshairPrecision;
00723 vmCvar_t        cg_drawRewards;
00724 vmCvar_t        cg_drawScores;
00725 vmCvar_t        cg_crosshairSize;
00726 vmCvar_t        cg_crosshairX;
00727 vmCvar_t        cg_crosshairY;
00728 vmCvar_t        cg_crosshairHealth;
00729 vmCvar_t        cg_draw2D;
00730 vmCvar_t        cg_drawStatus;
00731 vmCvar_t        cg_animSpeed;
00732 vmCvar_t        cg_debugAnim;
00733 vmCvar_t        cg_debugSaber;
00734 vmCvar_t        cg_debugPosition;
00735 vmCvar_t        cg_debugEvents;
00736 vmCvar_t        cg_errorDecay;
00737 vmCvar_t        cg_nopredict;
00738 vmCvar_t        cg_noPlayerAnims;
00739 vmCvar_t        cg_showmiss;
00740 vmCvar_t        cg_showVehMiss;
00741 vmCvar_t        cg_footsteps;
00742 vmCvar_t        cg_addMarks;
00743 vmCvar_t        cg_viewsize;
00744 vmCvar_t        cg_drawGun;
00745 vmCvar_t        cg_gun_frame;
00746 vmCvar_t        cg_gun_x;
00747 vmCvar_t        cg_gun_y;
00748 vmCvar_t        cg_gun_z;
00749 vmCvar_t        cg_autoswitch;
00750 vmCvar_t        cg_ignore;
00751 vmCvar_t        cg_simpleItems;
00752 vmCvar_t        cg_fov;
00753 vmCvar_t        cg_zoomFov;
00754 
00755 vmCvar_t        cg_swingAngles;
00756 
00757 vmCvar_t        cg_oldPainSounds;
00758 
00759 vmCvar_t        cg_ragDoll;
00760 
00761 vmCvar_t        cg_jumpSounds;
00762 
00763 vmCvar_t        cg_autoMap;
00764 vmCvar_t        cg_autoMapX;
00765 vmCvar_t        cg_autoMapY;
00766 vmCvar_t        cg_autoMapW;
00767 vmCvar_t        cg_autoMapH;
00768 
00769 #ifndef _XBOX   // Hmmm. This is also in game. I think this is safe.
00770 vmCvar_t        bg_fighterAltControl;
00771 #endif
00772 
00773 vmCvar_t        cg_chatBox;
00774 vmCvar_t        cg_chatBoxHeight;
00775 
00776 vmCvar_t        cg_saberModelTraceEffect;
00777 
00778 vmCvar_t        cg_saberClientVisualCompensation;
00779 
00780 vmCvar_t        cg_g2TraceLod;
00781 
00782 vmCvar_t        cg_fpls;
00783 
00784 vmCvar_t        cg_ghoul2Marks;
00785 
00786 vmCvar_t        cg_optvehtrace;
00787 
00788 vmCvar_t        cg_saberDynamicMarks;
00789 vmCvar_t        cg_saberDynamicMarkTime;
00790 
00791 vmCvar_t        cg_saberContact;
00792 vmCvar_t        cg_saberTrail;
00793 
00794 vmCvar_t        cg_duelHeadAngles;
00795 
00796 vmCvar_t        cg_speedTrail;
00797 vmCvar_t        cg_auraShell;
00798 
00799 vmCvar_t        cg_repeaterOrb;
00800 
00801 vmCvar_t        cg_animBlend;
00802 
00803 vmCvar_t        cg_dismember;
00804 
00805 vmCvar_t        cg_thirdPersonSpecialCam;
00806 
00807 vmCvar_t        cg_thirdPerson;
00808 vmCvar_t        cg_thirdPersonRange;
00809 vmCvar_t        cg_thirdPersonAngle;
00810 vmCvar_t        cg_thirdPersonPitchOffset;
00811 vmCvar_t        cg_thirdPersonVertOffset;
00812 vmCvar_t        cg_thirdPersonCameraDamp;
00813 vmCvar_t        cg_thirdPersonTargetDamp;
00814 
00815 vmCvar_t        cg_thirdPersonAlpha;
00816 vmCvar_t        cg_thirdPersonHorzOffset;
00817 
00818 vmCvar_t        cg_stereoSeparation;
00819 vmCvar_t        cg_lagometer;
00820 vmCvar_t        cg_drawEnemyInfo;
00821 vmCvar_t        cg_synchronousClients;
00822 vmCvar_t        cg_stats;
00823 vmCvar_t        cg_buildScript;
00824 vmCvar_t        cg_forceModel;
00825 vmCvar_t        cg_paused;
00826 vmCvar_t        cg_blood;
00827 vmCvar_t        cg_predictItems;
00828 vmCvar_t        cg_deferPlayers;
00829 vmCvar_t        cg_drawTeamOverlay;
00830 vmCvar_t        cg_teamOverlayUserinfo;
00831 vmCvar_t        cg_drawFriend;
00832 vmCvar_t        cg_teamChatsOnly;
00833 vmCvar_t        cg_hudFiles;
00834 vmCvar_t        cg_scorePlum;
00835 vmCvar_t        cg_smoothClients;
00836 
00837 #include "../namespace_begin.h"
00838 vmCvar_t        pmove_fixed;
00839 //vmCvar_t      cg_pmove_fixed;
00840 vmCvar_t        pmove_msec;
00841 // nmckenzie: DUEL_HEALTH
00842 vmCvar_t        g_showDuelHealths;
00843 #include "../namespace_end.h"
00844 
00845 vmCvar_t        cg_pmove_msec;
00846 vmCvar_t        cg_cameraMode;
00847 vmCvar_t        cg_cameraOrbit;
00848 vmCvar_t        cg_cameraOrbitDelay;
00849 vmCvar_t        cg_timescaleFadeEnd;
00850 vmCvar_t        cg_timescaleFadeSpeed;
00851 vmCvar_t        cg_timescale;
00852 vmCvar_t        cg_noTaunt;
00853 vmCvar_t        cg_noProjectileTrail;
00854 //vmCvar_t      cg_trueLightning;
00855 /*
00856 Ghoul2 Insert Start
00857 */
00858 vmCvar_t        cg_debugBB;
00859 /*
00860 Ghoul2 Insert End
00861 */
00862 //vmCvar_t      cg_redTeamName;
00863 //vmCvar_t      cg_blueTeamName;
00864 vmCvar_t        cg_currentSelectedPlayer;
00865 vmCvar_t        cg_currentSelectedPlayerName;
00866 //vmCvar_t      cg_singlePlayerActive;
00867 vmCvar_t        cg_recordSPDemo;
00868 vmCvar_t        cg_recordSPDemoName;
00869 vmCvar_t        cg_showVehBounds;
00870 
00871 vmCvar_t        ui_myteam;
00872 
00873 vmCvar_t        cg_snapshotTimeout;
00874 
00875 typedef struct {
00876         vmCvar_t        *vmCvar;
00877         char            *cvarName;
00878         char            *defaultString;
00879         int                     cvarFlags;
00880 } cvarTable_t;
00881 
00882 static cvarTable_t cvarTable[] = { // bk001129
00883         { &cg_ignore, "cg_ignore", "0", 0 },    // used for debugging
00884         { &cg_autoswitch, "cg_autoswitch", "1", CVAR_ARCHIVE },
00885         { &cg_drawGun, "cg_drawGun", "1", CVAR_ARCHIVE },
00886         { &cg_zoomFov, "cg_zoomfov", "40.0", CVAR_ARCHIVE },
00887         { &cg_fov, "cg_fov", "80", CVAR_ARCHIVE },
00888         { &cg_viewsize, "cg_viewsize", "100", CVAR_ARCHIVE },
00889         { &cg_stereoSeparation, "cg_stereoSeparation", "0.4", CVAR_ARCHIVE  },
00890         { &cg_shadows, "cg_shadows", "1", CVAR_ARCHIVE  },
00891         { &cg_renderToTextureFX, "cg_renderToTextureFX", "1", CVAR_ARCHIVE  },
00892         { &cg_draw2D, "cg_draw2D", "1", CVAR_ARCHIVE  },
00893         { &cg_drawStatus, "cg_drawStatus", "1", CVAR_ARCHIVE  },
00894         { &cg_drawTimer, "cg_drawTimer", "0", CVAR_ARCHIVE  },
00895         { &cg_drawFPS, "cg_drawFPS", "0", CVAR_ARCHIVE  },
00896         { &cg_drawSnapshot, "cg_drawSnapshot", "0", CVAR_ARCHIVE  },
00897         { &cg_draw3dIcons, "cg_draw3dIcons", "1", CVAR_ARCHIVE  },
00898         { &cg_drawIcons, "cg_drawIcons", "1", CVAR_ARCHIVE  },
00899         { &cg_drawAmmoWarning, "cg_drawAmmoWarning", "0", CVAR_ARCHIVE  },
00900         { &cg_drawEnemyInfo, "cg_drawEnemyInfo", "1", CVAR_ARCHIVE  },
00901         { &cg_drawCrosshair, "cg_drawCrosshair", "1", CVAR_ARCHIVE },
00902         { &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE },
00903         { &cg_drawRadar, "cg_drawRadar", "1", CVAR_ARCHIVE },
00904         { &cg_drawVehLeadIndicator, "cg_drawVehLeadIndicator", "1", CVAR_ARCHIVE },
00905         { &cg_drawScores,                 "cg_drawScores", "1", CVAR_ARCHIVE },
00906         { &cg_dynamicCrosshair, "cg_dynamicCrosshair", "1", CVAR_ARCHIVE },
00907         //Enables ghoul2 traces for crosshair traces.. more precise when pointing at others, but slower.
00908         //And if the server doesn't have g2 col enabled, it won't match up the same.
00909         { &cg_dynamicCrosshairPrecision, "cg_dynamicCrosshairPrecision", "1", CVAR_ARCHIVE },
00910         { &cg_drawRewards, "cg_drawRewards", "1", CVAR_ARCHIVE },
00911         { &cg_crosshairSize, "cg_crosshairSize", "24", CVAR_ARCHIVE },
00912         { &cg_crosshairHealth, "cg_crosshairHealth", "0", CVAR_ARCHIVE },
00913         { &cg_crosshairX, "cg_crosshairX", "0", CVAR_ARCHIVE },
00914         { &cg_crosshairY, "cg_crosshairY", "0", CVAR_ARCHIVE },
00915         { &cg_simpleItems, "cg_simpleItems", "0", CVAR_ARCHIVE },
00916         { &cg_addMarks, "cg_marks", "1", CVAR_ARCHIVE },
00917         { &cg_lagometer, "cg_lagometer", "0", CVAR_ARCHIVE },
00918         { &cg_gun_x, "cg_gunX", "0", CVAR_CHEAT },
00919         { &cg_gun_y, "cg_gunY", "0", CVAR_CHEAT },
00920         { &cg_gun_z, "cg_gunZ", "0", CVAR_CHEAT },
00921         { &cg_centertime, "cg_centertime", "3", CVAR_CHEAT },
00922         { &cg_runpitch, "cg_runpitch", "0.002", CVAR_ARCHIVE},
00923         { &cg_runroll, "cg_runroll", "0.005", CVAR_ARCHIVE },
00924         { &cg_bobup , "cg_bobup", "0.005", CVAR_ARCHIVE },
00925         { &cg_bobpitch, "cg_bobpitch", "0.002", CVAR_ARCHIVE },
00926         { &cg_bobroll, "cg_bobroll", "0.002", CVAR_ARCHIVE },
00927         //{ &cg_swingSpeed, "cg_swingSpeed", "0.3", CVAR_CHEAT },
00928         { &cg_animSpeed, "cg_animspeed", "1", CVAR_CHEAT },
00929         { &cg_debugAnim, "cg_debuganim", "0", CVAR_CHEAT },
00930         { &cg_debugSaber, "cg_debugsaber", "0", CVAR_CHEAT },
00931         { &cg_debugPosition, "cg_debugposition", "0", CVAR_CHEAT },
00932         { &cg_debugEvents, "cg_debugevents", "0", CVAR_CHEAT },
00933         { &cg_errorDecay, "cg_errordecay", "100", 0 },
00934         { &cg_nopredict, "cg_nopredict", "0", 0 },
00935         { &cg_noPlayerAnims, "cg_noplayeranims", "0", CVAR_CHEAT },
00936         { &cg_showmiss, "cg_showmiss", "0", 0 },
00937         { &cg_showVehMiss, "cg_showVehMiss", "0", 0 },
00938         { &cg_footsteps, "cg_footsteps", "3", CVAR_ARCHIVE },
00939         { &cg_swingAngles, "cg_swingAngles", "1", 0 },
00940 
00941         { &cg_oldPainSounds, "cg_oldPainSounds", "0", 0 },
00942 
00943         { &cg_ragDoll, "broadsword", "0", 0 },
00944 
00945         { &cg_jumpSounds, "cg_jumpSounds", "0", 0 },
00946 
00947         { &cg_autoMap, "r_autoMap", "0", CVAR_ARCHIVE },
00948         { &cg_autoMapX, "r_autoMapX", "496", CVAR_ARCHIVE },
00949         { &cg_autoMapY, "r_autoMapY", "32", CVAR_ARCHIVE },
00950         { &cg_autoMapW, "r_autoMapW", "128", CVAR_ARCHIVE },
00951         { &cg_autoMapH, "r_autoMapH", "128", CVAR_ARCHIVE },
00952 
00953         { &bg_fighterAltControl, "bg_fighterAltControl", "0", CVAR_SERVERINFO },
00954 
00955         { &cg_chatBox, "cg_chatBox", "10000", CVAR_ARCHIVE },
00956         { &cg_chatBoxHeight, "cg_chatBoxHeight", "350", CVAR_ARCHIVE },
00957 
00958         { &cg_saberModelTraceEffect, "cg_saberModelTraceEffect", "0", 0 },
00959 
00960         //allows us to trace between server frames on the client to see if we're visually
00961         //hitting the last entity we detected a hit on from the server.
00962         { &cg_saberClientVisualCompensation, "cg_saberClientVisualCompensation", "1", 0 },
00963 
00964         { &cg_g2TraceLod, "cg_g2TraceLod", "2", 0 },
00965 
00966         { &cg_fpls, "cg_fpls", "0", 0 },
00967 
00968         { &cg_ghoul2Marks, "cg_ghoul2Marks", "16", 0 },
00969 
00970         { &cg_optvehtrace, "com_optvehtrace", "0", 0 },
00971 
00972         { &cg_saberDynamicMarks, "cg_saberDynamicMarks", "0", 0 },
00973         { &cg_saberDynamicMarkTime, "cg_saberDynamicMarkTime", "60000", 0 },
00974 
00975         { &cg_saberContact, "cg_saberContact", "1", 0 },
00976         { &cg_saberTrail, "cg_saberTrail", "1", 0 },
00977 
00978         { &cg_duelHeadAngles, "cg_duelHeadAngles", "0", 0 },
00979 
00980         { &cg_speedTrail, "cg_speedTrail", "1", 0 },
00981         { &cg_auraShell, "cg_auraShell", "1", 0 },
00982 
00983         { &cg_repeaterOrb, "cg_repeaterOrb", "0", 0 },
00984 
00985         { &cg_animBlend, "cg_animBlend", "1", 0 },
00986 
00987         { &cg_dismember, "cg_dismember", "0", CVAR_ARCHIVE },
00988 
00989         { &cg_thirdPersonSpecialCam, "cg_thirdPersonSpecialCam", "0", 0 },
00990 
00991         { &cg_thirdPerson, "cg_thirdPerson", "0", CVAR_ARCHIVE },
00992         { &cg_thirdPersonRange, "cg_thirdPersonRange", "80", CVAR_CHEAT },
00993         { &cg_thirdPersonAngle, "cg_thirdPersonAngle", "0", CVAR_CHEAT },
00994         { &cg_thirdPersonPitchOffset, "cg_thirdPersonPitchOffset", "0", CVAR_CHEAT },
00995         { &cg_thirdPersonVertOffset, "cg_thirdPersonVertOffset", "16", CVAR_CHEAT },
00996         { &cg_thirdPersonCameraDamp, "cg_thirdPersonCameraDamp", "0.3", 0 },
00997         { &cg_thirdPersonTargetDamp, "cg_thirdPersonTargetDamp", "0.5", CVAR_CHEAT },
00998         
00999         { &cg_thirdPersonHorzOffset, "cg_thirdPersonHorzOffset", "0", CVAR_CHEAT },
01000         { &cg_thirdPersonAlpha, "cg_thirdPersonAlpha",  "1.0", CVAR_CHEAT },
01001 
01002         { &cg_forceModel, "cg_forceModel", "0", CVAR_ARCHIVE  },
01003         { &cg_predictItems, "cg_predictItems", "1", CVAR_ARCHIVE },
01004         { &cg_deferPlayers, "cg_deferPlayers", "1", CVAR_ARCHIVE },
01005         { &cg_drawTeamOverlay, "cg_drawTeamOverlay", "0", CVAR_ARCHIVE },
01006         { &cg_teamOverlayUserinfo, "teamoverlay", "0", CVAR_ROM | CVAR_USERINFO },
01007         { &cg_stats, "cg_stats", "0", 0 },
01008         { &cg_drawFriend, "cg_drawFriend", "1", CVAR_ARCHIVE },
01009         { &cg_teamChatsOnly, "cg_teamChatsOnly", "0", CVAR_ARCHIVE },
01010         // the following variables are created in other parts of the system,
01011         // but we also reference them here
01012         { &cg_buildScript, "com_buildScript", "0", 0 }, // force loading of all possible data amd error on failures
01013         { &cg_paused, "cl_paused", "0", CVAR_ROM },
01014         { &cg_blood, "com_blood", "1", CVAR_ARCHIVE },
01015         { &cg_synchronousClients, "g_synchronousClients", "0", 0 },     // communicated by systeminfo
01016 
01017 //      { &cg_redTeamName, "g_redteam", DEFAULT_REDTEAM_NAME, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_USERINFO },
01018 //      { &cg_blueTeamName, "g_blueteam", DEFAULT_BLUETEAM_NAME, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_USERINFO },
01019         { &cg_currentSelectedPlayer, "cg_currentSelectedPlayer", "0", CVAR_ARCHIVE},
01020         { &cg_currentSelectedPlayerName, "cg_currentSelectedPlayerName", "", CVAR_ARCHIVE},
01021 //      { &cg_singlePlayerActive, "ui_singlePlayerActive", "0", CVAR_USERINFO},
01022         { &cg_recordSPDemo, "ui_recordSPDemo", "0", CVAR_ARCHIVE},
01023         { &cg_recordSPDemoName, "ui_recordSPDemoName", "", CVAR_ARCHIVE},
01024 
01025         { &cg_cameraOrbit, "cg_cameraOrbit", "0", CVAR_CHEAT},
01026         { &cg_cameraOrbitDelay, "cg_cameraOrbitDelay", "50", CVAR_ARCHIVE},
01027         { &cg_timescaleFadeEnd, "cg_timescaleFadeEnd", "1", 0},
01028         { &cg_timescaleFadeSpeed, "cg_timescaleFadeSpeed", "0", 0},
01029         { &cg_timescale, "timescale", "1", 0},
01030         { &cg_scorePlum, "cg_scorePlums", "1",  CVAR_ARCHIVE},
01031         { &cg_hudFiles, "cg_hudFiles", "ui/jahud.txt", CVAR_ARCHIVE},
01032         { &cg_smoothClients, "cg_smoothClients", "1",  CVAR_ARCHIVE},
01033         { &cg_cameraMode, "com_cameraMode", "0", CVAR_CHEAT},
01034 
01035         { &pmove_fixed, "pmove_fixed", "0", 0},
01036         { &pmove_msec, "pmove_msec", "8", 0},
01037         { &cg_noTaunt, "cg_noTaunt", "0", CVAR_ARCHIVE},
01038         { &cg_noProjectileTrail, "cg_noProjectileTrail", "0", CVAR_ARCHIVE},
01039 //      { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE},
01040         { &cg_showVehBounds, "cg_showVehBounds", "0", 0},
01041 
01042         { &ui_myteam, "ui_myteam", "0", CVAR_ROM|CVAR_INTERNAL},
01043         { &cg_snapshotTimeout, "cg_snapshotTimeout", "10", CVAR_ARCHIVE },
01044 
01045 //      { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE }
01046 /*
01047 Ghoul2 Insert Start
01048 */
01049         { &cg_debugBB, "debugBB", "0", 0},
01050 /*
01051 Ghoul2 Insert End
01052 */
01053 };
01054 
01055 static int  cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] );
01056 
01057 /*
01058 =================
01059 CG_RegisterCvars
01060 =================
01061 */
01062 void CG_RegisterCvars( void ) {
01063         int                     i;
01064         cvarTable_t     *cv;
01065         char            var[MAX_TOKEN_CHARS];
01066 
01067         for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
01068                 trap_Cvar_Register( cv->vmCvar, cv->cvarName,
01069                         cv->defaultString, cv->cvarFlags );
01070         }
01071 
01072         // see if we are also running the server on this machine
01073         trap_Cvar_VariableStringBuffer( "sv_running", var, sizeof( var ) );
01074         cgs.localServer = atoi( var );
01075 
01076         forceModelModificationCount = cg_forceModel.modificationCount;
01077 
01078         trap_Cvar_Register(NULL, "model", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
01079         trap_Cvar_Register(NULL, "forcepowers", DEFAULT_FORCEPOWERS, CVAR_USERINFO | CVAR_ARCHIVE );
01080 
01081         // Cvars uses for transferring data between client and server
01082         trap_Cvar_Register(NULL, "ui_about_gametype",           "0", CVAR_ROM|CVAR_INTERNAL );
01083         trap_Cvar_Register(NULL, "ui_about_fraglimit",          "0", CVAR_ROM|CVAR_INTERNAL );
01084         trap_Cvar_Register(NULL, "ui_about_capturelimit",       "0", CVAR_ROM|CVAR_INTERNAL );
01085         trap_Cvar_Register(NULL, "ui_about_duellimit",          "0", CVAR_ROM|CVAR_INTERNAL );
01086         trap_Cvar_Register(NULL, "ui_about_timelimit",          "0", CVAR_ROM|CVAR_INTERNAL );
01087         trap_Cvar_Register(NULL, "ui_about_maxclients",         "0", CVAR_ROM|CVAR_INTERNAL );
01088         trap_Cvar_Register(NULL, "ui_about_dmflags",            "0", CVAR_ROM|CVAR_INTERNAL );
01089         trap_Cvar_Register(NULL, "ui_about_mapname",            "0", CVAR_ROM|CVAR_INTERNAL );
01090         trap_Cvar_Register(NULL, "ui_about_hostname",           "0", CVAR_ROM|CVAR_INTERNAL );
01091         trap_Cvar_Register(NULL, "ui_about_needpass",           "0", CVAR_ROM|CVAR_INTERNAL );
01092         trap_Cvar_Register(NULL, "ui_about_botminplayers",      "0", CVAR_ROM|CVAR_INTERNAL );
01093 
01094         trap_Cvar_Register(NULL, "ui_tm1_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01095         trap_Cvar_Register(NULL, "ui_tm2_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01096         trap_Cvar_Register(NULL, "ui_tm3_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01097 
01098         trap_Cvar_Register(NULL, "ui_tm1_c0_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01099         trap_Cvar_Register(NULL, "ui_tm1_c1_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01100         trap_Cvar_Register(NULL, "ui_tm1_c2_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01101         trap_Cvar_Register(NULL, "ui_tm1_c3_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01102         trap_Cvar_Register(NULL, "ui_tm1_c4_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01103         trap_Cvar_Register(NULL, "ui_tm1_c5_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01104 
01105         trap_Cvar_Register(NULL, "ui_tm2_c0_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01106         trap_Cvar_Register(NULL, "ui_tm2_c1_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01107         trap_Cvar_Register(NULL, "ui_tm2_c2_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01108         trap_Cvar_Register(NULL, "ui_tm2_c3_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01109         trap_Cvar_Register(NULL, "ui_tm2_c4_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01110         trap_Cvar_Register(NULL, "ui_tm2_c5_cnt", "0", CVAR_ROM | CVAR_INTERNAL );
01111 
01112 }
01113 
01114 /*                                                                                                                                                                                                                                                                                      
01115 ===================
01116 CG_SetWeatherOverride
01117 ===================
01118 */
01119 #if 0
01120 void CG_SetWeatherOverride(int contents)
01121 {
01122         if (contents != cgWeatherOverride)
01123         { //only do the trap call if we aren't already set to this
01124                 trap_R_WeatherContentsOverride(contents);
01125         }
01126         cgWeatherOverride = contents; //keep track of it
01127 }
01128 #endif
01129 
01130 /*                                                                                                                                                                                                                                                                                      
01131 ===================
01132 CG_ForceModelChange
01133 ===================
01134 */
01135 static void CG_ForceModelChange( void ) {
01136         int             i;
01137 
01138         for (i=0 ; i<MAX_CLIENTS ; i++) {
01139                 const char              *clientInfo;
01140                 void    *oldGhoul2;
01141 
01142                 clientInfo = CG_ConfigString( CS_PLAYERS+i );
01143                 if ( !clientInfo[0] ) {
01144                         continue;
01145                 }
01146 
01147                 oldGhoul2 = cgs.clientinfo[i].ghoul2Model;
01148                 CG_NewClientInfo( i, qtrue);
01149         }
01150 }
01151 
01152 /*
01153 =================
01154 CG_UpdateCvars
01155 =================
01156 */
01157 void CG_UpdateCvars( void ) {
01158         int                     i;
01159         cvarTable_t     *cv;
01160         static int drawTeamOverlayModificationCount = -1;
01161 
01162         for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
01163                 trap_Cvar_Update( cv->vmCvar );
01164         }
01165 
01166         // check for modications here
01167 
01168         // If team overlay is on, ask for updates from the server.  If its off,
01169         // let the server know so we don't receive it
01170         if ( drawTeamOverlayModificationCount != cg_drawTeamOverlay.modificationCount ) {
01171                 drawTeamOverlayModificationCount = cg_drawTeamOverlay.modificationCount;
01172 
01173                 if ( cg_drawTeamOverlay.integer > 0 ) {
01174                         trap_Cvar_Set( "teamoverlay", "1" );
01175                 } else {
01176                         trap_Cvar_Set( "teamoverlay", "0" );
01177                 }
01178                 // FIXME E3 HACK
01179                 trap_Cvar_Set( "teamoverlay", "1" );
01180         }
01181 
01182         // if force model changed
01183         if ( forceModelModificationCount != cg_forceModel.modificationCount ) {
01184                 forceModelModificationCount = cg_forceModel.modificationCount;
01185                 CG_ForceModelChange();
01186         }
01187 }
01188 
01189 int CG_CrosshairPlayer( void ) {
01190         if ( cg.time > ( cg.crosshairClientTime + 1000 ) ) {
01191                 return -1;
01192         }
01193 
01194         if (cg.crosshairClientNum >= MAX_CLIENTS)
01195         {
01196                 return -1;
01197         }
01198 
01199         return cg.crosshairClientNum;
01200 }
01201 
01202 int CG_LastAttacker( void ) {
01203         if ( !cg.attackerTime ) {
01204                 return -1;
01205         }
01206         return cg.snap->ps.persistant[PERS_ATTACKER];
01207 }
01208 
01209 void QDECL CG_Printf( const char *msg, ... ) {
01210         va_list         argptr;
01211         char            text[1024];
01212 
01213         va_start (argptr, msg);
01214         vsprintf (text, msg, argptr);
01215         va_end (argptr);
01216 
01217         trap_Print( text );
01218 }
01219 
01220 void QDECL CG_Error( const char *msg, ... ) {
01221         va_list         argptr;
01222         char            text[1024];
01223 
01224         va_start (argptr, msg);
01225         vsprintf (text, msg, argptr);
01226         va_end (argptr);
01227 
01228         trap_Error( text );
01229 }
01230 
01231 #ifndef CGAME_HARD_LINKED
01232 // this is only here so the functions in q_shared.c and bg_*.c can link (FIXME)
01233 
01234 void QDECL Com_Error( int level, const char *error, ... ) {
01235         va_list         argptr;
01236         char            text[1024];
01237 
01238         va_start (argptr, error);
01239         vsprintf (text, error, argptr);
01240         va_end (argptr);
01241 
01242         CG_Error( "%s", text);
01243 }
01244 
01245 void QDECL Com_Printf( const char *msg, ... ) {
01246         va_list         argptr;
01247         char            text[1024];
01248 
01249         va_start (argptr, msg);
01250         vsprintf (text, msg, argptr);
01251         va_end (argptr);
01252 
01253         CG_Printf ("%s", text);
01254 }
01255 
01256 #endif
01257 
01258 /*
01259 ================
01260 CG_Argv
01261 ================
01262 */
01263 const char *CG_Argv( int arg ) {
01264         static char     buffer[MAX_STRING_CHARS];
01265 
01266         trap_Argv( arg, buffer, sizeof( buffer ) );
01267 
01268         return buffer;
01269 }
01270 
01271 
01272 //========================================================================
01273 
01274 //so shared code can get the local time depending on the side it's executed on
01275 #include "../namespace_begin.h"
01276 int BG_GetTime(void)
01277 {
01278         return cg.time;
01279 }
01280 #include "../namespace_end.h"
01281 
01282 /*
01283 =================
01284 CG_RegisterItemSounds
01285 
01286 The server says this item is used on this level
01287 =================
01288 */
01289 static void CG_RegisterItemSounds( int itemNum ) {
01290         gitem_t                 *item;
01291         char                    data[MAX_QPATH];
01292         char                    *s, *start;
01293         int                             len;
01294 
01295         item = &bg_itemlist[ itemNum ];
01296 
01297         if( item->pickup_sound ) {
01298                 trap_S_RegisterSound( item->pickup_sound );
01299         }
01300 
01301         // parse the space seperated precache string for other media
01302         s = item->sounds;
01303         if (!s || !s[0])
01304                 return;
01305 
01306         while (*s) {
01307                 start = s;
01308                 while (*s && *s != ' ') {
01309                         s++;
01310                 }
01311 
01312                 len = s-start;
01313                 if (len >= MAX_QPATH || len < 5) {
01314                         CG_Error( "PrecacheItem: %s has bad precache string", 
01315                                 item->classname);
01316                         return;
01317                 }
01318                 memcpy (data, start, len);
01319                 data[len] = 0;
01320                 if ( *s ) {
01321                         s++;
01322                 }
01323 
01324                 trap_S_RegisterSound( data );
01325         }
01326 
01327         // parse the space seperated precache string for other media
01328         s = item->precaches;
01329         if (!s || !s[0])
01330                 return;
01331 
01332         while (*s) {
01333                 start = s;
01334                 while (*s && *s != ' ') {
01335                         s++;
01336                 }
01337 
01338                 len = s-start;
01339                 if (len >= MAX_QPATH || len < 5) {
01340                         CG_Error( "PrecacheItem: %s has bad precache string", 
01341                                 item->classname);
01342                         return;
01343                 }
01344                 memcpy (data, start, len);
01345                 data[len] = 0;
01346                 if ( *s ) {
01347                         s++;
01348                 }
01349 
01350                 if ( !strcmp(data+len-3, "efx" )) {
01351                         trap_FX_RegisterEffect( data );
01352                 }
01353         }
01354 }
01355 
01356 static void CG_AS_Register(void)
01357 {
01358         const char *soundName;
01359         int i;
01360 
01361 //      CG_LoadingString( "ambient sound sets" );
01362 
01363         //Load the ambient sets
01364 #if 0 //as_preCacheMap was game-side.. that is evil.
01365         trap_AS_AddPrecacheEntry( "#clear" );   // ;-)
01366         //FIXME: Don't ask... I had to get around a really nasty MS error in the templates with this...
01367         namePrecache_m::iterator        pi;
01368         STL_ITERATE( pi, as_preCacheMap )
01369         {
01370                 cgi_AS_AddPrecacheEntry( ((*pi).first).c_str() );
01371         }
01372 #else
01373         trap_AS_AddPrecacheEntry( "#clear" );
01374 
01375         for ( i = 1 ; i < MAX_AMBIENT_SETS ; i++ ) {
01376                 soundName = CG_ConfigString( CS_AMBIENT_SET+i );
01377                 if ( !soundName || !soundName[0] )
01378                 {
01379                         break;
01380                 }
01381 
01382                 trap_AS_AddPrecacheEntry(soundName);
01383         }
01384         soundName = CG_ConfigString( CS_GLOBAL_AMBIENT_SET );
01385         if (soundName && soundName[0] && Q_stricmp(soundName, "default"))
01386         { //global soundset
01387                 trap_AS_AddPrecacheEntry(soundName);
01388         }
01389 #endif
01390 
01391         trap_AS_ParseSets();
01392 }
01393 
01394 //a global weather effect (rain, snow, etc)
01395 void CG_ParseWeatherEffect(const char *str)
01396 {
01397         char *sptr = (char *)str;
01398         sptr++; //pass the '*'
01399         trap_R_WorldEffectCommand(sptr);
01400 }
01401 
01402 extern int cgSiegeRoundBeganTime;
01403 void CG_ParseSiegeState(const char *str)
01404 {
01405         int i = 0;
01406         int j = 0;
01407 //      int prevState = cgSiegeRoundState;
01408         char b[1024];
01409 
01410         while (str[i] && str[i] != '|')
01411         {
01412                 b[j] = str[i];
01413                 i++;
01414                 j++;
01415         }
01416         b[j] = 0;
01417         cgSiegeRoundState = atoi(b);
01418 
01419         if (str[i] == '|')
01420         {
01421                 j = 0;
01422                 i++;
01423                 while (str[i])
01424                 {
01425                         b[j] = str[i];
01426                         i++;
01427                         j++;
01428                 }
01429                 b[j] = 0;
01430 //              if (cgSiegeRoundState != prevState)
01431                 { //it changed
01432                         cgSiegeRoundTime = atoi(b);
01433                         if (cgSiegeRoundState == 0 || cgSiegeRoundState == 2)
01434                         {
01435                                 cgSiegeRoundBeganTime = cgSiegeRoundTime;
01436                         }
01437                 }
01438         }
01439         else
01440         {
01441             cgSiegeRoundTime = cg.time;
01442         }
01443 }
01444 
01445 /*
01446 =================
01447 CG_RegisterSounds
01448 
01449 called during a precache command
01450 =================
01451 */
01452 void CG_PrecacheNPCSounds(const char *str);
01453 void CG_ParseSiegeObjectiveStatus(const char *str);
01454 extern int cg_beatingSiegeTime;
01455 extern int cg_siegeWinTeam;
01456 static void CG_RegisterSounds( void ) {
01457         int             i;
01458         char    items[MAX_ITEMS+1];
01459         char    name[MAX_QPATH];
01460         const char      *soundName;
01461 
01462         CG_AS_Register();
01463 
01464 //      CG_LoadingString( "sounds" );
01465 
01466         trap_S_RegisterSound( "sound/weapons/melee/punch1.mp3" );
01467         trap_S_RegisterSound( "sound/weapons/melee/punch2.mp3" );
01468         trap_S_RegisterSound( "sound/weapons/melee/punch3.mp3" );
01469         trap_S_RegisterSound( "sound/weapons/melee/punch4.mp3" );
01470         trap_S_RegisterSound("sound/movers/objects/saber_slam");
01471 
01472         trap_S_RegisterSound("sound/player/bodyfall_human1.wav");
01473         trap_S_RegisterSound("sound/player/bodyfall_human2.wav");
01474         trap_S_RegisterSound("sound/player/bodyfall_human3.wav");
01475 
01476         //test effects
01477         trap_FX_RegisterEffect("effects/mp/test_sparks.efx");
01478         trap_FX_RegisterEffect("effects/mp/test_wall_impact.efx");
01479 
01480         cgs.media.oneMinuteSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM004" );
01481         cgs.media.fiveMinuteSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM005" );
01482         cgs.media.oneFragSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM001" );
01483         cgs.media.twoFragSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM002" );
01484         cgs.media.threeFragSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM003");
01485         cgs.media.count3Sound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM035" );
01486         cgs.media.count2Sound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM036" );
01487         cgs.media.count1Sound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM037" );
01488         cgs.media.countFightSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM038" );
01489 
01490         cgs.media.hackerIconShader                      = trap_R_RegisterShaderNoMip("gfx/mp/c_icon_tech");
01491 
01492         cgs.media.redSaberGlowShader            = trap_R_RegisterShader( "gfx/effects/sabers/red_glow" );
01493         cgs.media.redSaberCoreShader            = trap_R_RegisterShader( "gfx/effects/sabers/red_line" );
01494         cgs.media.orangeSaberGlowShader         = trap_R_RegisterShader( "gfx/effects/sabers/orange_glow" );
01495         cgs.media.orangeSaberCoreShader         = trap_R_RegisterShader( "gfx/effects/sabers/orange_line" );
01496         cgs.media.yellowSaberGlowShader         = trap_R_RegisterShader( "gfx/effects/sabers/yellow_glow" );
01497         cgs.media.yellowSaberCoreShader         = trap_R_RegisterShader( "gfx/effects/sabers/yellow_line" );
01498         cgs.media.greenSaberGlowShader          = trap_R_RegisterShader( "gfx/effects/sabers/green_glow" );
01499         cgs.media.greenSaberCoreShader          = trap_R_RegisterShader( "gfx/effects/sabers/green_line" );
01500         cgs.media.blueSaberGlowShader           = trap_R_RegisterShader( "gfx/effects/sabers/blue_glow" );
01501         cgs.media.blueSaberCoreShader           = trap_R_RegisterShader( "gfx/effects/sabers/blue_line" );
01502         cgs.media.purpleSaberGlowShader         = trap_R_RegisterShader( "gfx/effects/sabers/purple_glow" );
01503         cgs.media.purpleSaberCoreShader         = trap_R_RegisterShader( "gfx/effects/sabers/purple_line" );
01504         cgs.media.saberBlurShader                       = trap_R_RegisterShader( "gfx/effects/sabers/saberBlur" );
01505         cgs.media.swordTrailShader                      = trap_R_RegisterShader( "gfx/effects/sabers/swordTrail" );
01506 
01507         cgs.media.forceCoronaShader                     = trap_R_RegisterShaderNoMip( "gfx/hud/force_swirl" );
01508 
01509         cgs.media.yellowDroppedSaberShader      = trap_R_RegisterShader("gfx/effects/yellow_glow");
01510 
01511         cgs.media.rivetMarkShader                       = trap_R_RegisterShader( "gfx/damage/rivetmark" );
01512 
01513         trap_R_RegisterShader( "gfx/effects/saberFlare" );
01514 
01515         trap_R_RegisterShader( "powerups/ysalimarishell" );
01516         
01517         trap_R_RegisterShader( "gfx/effects/forcePush" );
01518 
01519         trap_R_RegisterShader( "gfx/misc/red_dmgshield" );
01520         trap_R_RegisterShader( "gfx/misc/red_portashield" );
01521         trap_R_RegisterShader( "gfx/misc/blue_dmgshield" );
01522         trap_R_RegisterShader( "gfx/misc/blue_portashield" );
01523 
01524         trap_R_RegisterShader( "models/map_objects/imp_mine/turret_chair_dmg.tga" );
01525 
01526         for (i=1 ; i<9 ; i++)
01527         {
01528                 trap_S_RegisterSound(va("sound/weapons/saber/saberhup%i.wav", i));
01529         }
01530 
01531         for (i=1 ; i<10 ; i++)
01532         {
01533                 trap_S_RegisterSound(va("sound/weapons/saber/saberblock%i.wav", i));
01534         }
01535 
01536         for (i=1 ; i<4 ; i++)
01537         {
01538                 trap_S_RegisterSound(va("sound/weapons/saber/bounce%i.wav", i));
01539         }
01540 
01541         trap_S_RegisterSound( "sound/weapons/saber/enemy_saber_on.wav" );
01542         trap_S_RegisterSound( "sound/weapons/saber/enemy_saber_off.wav" );
01543 
01544         trap_S_RegisterSound( "sound/weapons/saber/saberhum1.wav" );
01545         trap_S_RegisterSound( "sound/weapons/saber/saberon.wav" );
01546         trap_S_RegisterSound( "sound/weapons/saber/saberoffquick.wav" );
01547         trap_S_RegisterSound( "sound/weapons/saber/saberhitwall1" );
01548         trap_S_RegisterSound( "sound/weapons/saber/saberhitwall2" );
01549         trap_S_RegisterSound( "sound/weapons/saber/saberhitwall3" );
01550         trap_S_RegisterSound("sound/weapons/saber/saberhit.wav");
01551         trap_S_RegisterSound("sound/weapons/saber/saberhit1.wav");
01552         trap_S_RegisterSound("sound/weapons/saber/saberhit2.wav");
01553         trap_S_RegisterSound("sound/weapons/saber/saberhit3.wav");
01554 
01555         trap_S_RegisterSound("sound/weapons/saber/saber_catch.wav");
01556 
01557         cgs.media.teamHealSound = trap_S_RegisterSound("sound/weapons/force/teamheal.wav");
01558         cgs.media.teamRegenSound = trap_S_RegisterSound("sound/weapons/force/teamforce.wav");
01559 
01560         trap_S_RegisterSound("sound/weapons/force/heal.wav");
01561         trap_S_RegisterSound("sound/weapons/force/speed.wav");
01562         trap_S_RegisterSound("sound/weapons/force/see.wav");
01563         trap_S_RegisterSound("sound/weapons/force/rage.wav");
01564         trap_S_RegisterSound("sound/weapons/force/lightning");
01565         trap_S_RegisterSound("sound/weapons/force/lightninghit1");
01566         trap_S_RegisterSound("sound/weapons/force/lightninghit2");
01567         trap_S_RegisterSound("sound/weapons/force/lightninghit3");
01568         trap_S_RegisterSound("sound/weapons/force/drain.wav");
01569         trap_S_RegisterSound("sound/weapons/force/jumpbuild.wav");
01570         trap_S_RegisterSound("sound/weapons/force/distract.wav");
01571         trap_S_RegisterSound("sound/weapons/force/distractstop.wav");
01572         trap_S_RegisterSound("sound/weapons/force/pull.wav");
01573         trap_S_RegisterSound("sound/weapons/force/push.wav");
01574 
01575         for (i=1 ; i<3 ; i++)
01576         {
01577                 trap_S_RegisterSound(va("sound/weapons/thermal/bounce%i.wav", i));
01578         }
01579 
01580         trap_S_RegisterSound("sound/movers/switches/switch2.wav");
01581         trap_S_RegisterSound("sound/movers/switches/switch3.wav");
01582         trap_S_RegisterSound("sound/ambience/spark5.wav");
01583         trap_S_RegisterSound("sound/chars/turret/ping.wav");
01584         trap_S_RegisterSound("sound/chars/turret/startup.wav");
01585         trap_S_RegisterSound("sound/chars/turret/shutdown.wav");
01586         trap_S_RegisterSound("sound/chars/turret/move.wav");
01587         trap_S_RegisterSound("sound/player/pickuphealth.wav");
01588         trap_S_RegisterSound("sound/player/pickupshield.wav");
01589 
01590         trap_S_RegisterSound("sound/effects/glassbreak1.wav");
01591 
01592         trap_S_RegisterSound( "sound/weapons/rocket/tick.wav" );
01593         trap_S_RegisterSound( "sound/weapons/rocket/lock.wav" );
01594 
01595         trap_S_RegisterSound("sound/weapons/force/speedloop.wav");
01596 
01597         trap_S_RegisterSound("sound/weapons/force/protecthit.mp3"); //PDSOUND_PROTECTHIT
01598         trap_S_RegisterSound("sound/weapons/force/protect.mp3"); //PDSOUND_PROTECT
01599         trap_S_RegisterSound("sound/weapons/force/absorbhit.mp3"); //PDSOUND_ABSORBHIT
01600         trap_S_RegisterSound("sound/weapons/force/absorb.mp3"); //PDSOUND_ABSORB
01601         trap_S_RegisterSound("sound/weapons/force/jump.mp3"); //PDSOUND_FORCEJUMP
01602         trap_S_RegisterSound("sound/weapons/force/grip.mp3"); //PDSOUND_FORCEGRIP
01603 
01604         if ( cgs.gametype >= GT_TEAM || cg_buildScript.integer ) {
01605 
01606 #ifdef JK2AWARDS
01607                 cgs.media.captureAwardSound = trap_S_RegisterSound( "sound/teamplay/flagcapture_yourteam.wav" );
01608 #endif
01609                 cgs.media.redLeadsSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM046");
01610                 cgs.media.blueLeadsSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM045");
01611                 cgs.media.teamsTiedSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM032" );
01612 
01613                 cgs.media.redScoredSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM044");
01614                 cgs.media.blueScoredSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM043" );
01615 
01616                 if ( cgs.gametype == GT_CTF || cg_buildScript.integer ) {
01617                         cgs.media.redFlagReturnedSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM042" );
01618                         cgs.media.blueFlagReturnedSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM041" );
01619                         cgs.media.redTookFlagSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM040" );
01620                         cgs.media.blueTookFlagSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM039" );
01621                 }
01622                 if ( cgs.gametype == GT_CTY /*|| cg_buildScript.integer*/ ) {
01623                         cgs.media.redYsalReturnedSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM050" );
01624                         cgs.media.blueYsalReturnedSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM049" );
01625                         cgs.media.redTookYsalSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM048" );
01626                         cgs.media.blueTookYsalSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM047" );
01627                 }
01628         }
01629 
01630         cgs.media.drainSound = trap_S_RegisterSound("sound/weapons/force/drained.mp3");
01631 
01632         cgs.media.happyMusic = trap_S_RegisterSound("music/goodsmall.mp3");
01633         cgs.media.dramaticFailure = trap_S_RegisterSound("music/badsmall.mp3");
01634 
01635         //PRECACHE ALL MUSIC HERE (don't need to precache normally because it's streamed off the disk)
01636         if (cg_buildScript.integer)
01637         {
01638                 trap_S_StartBackgroundTrack( "music/mp/duel.mp3", "music/mp/duel.mp3", qfalse );
01639         }
01640 
01641         cg.loadLCARSStage = 1;
01642 
01643         cgs.media.selectSound = trap_S_RegisterSound( "sound/weapons/change.wav" );
01644 
01645         cgs.media.teleInSound = trap_S_RegisterSound( "sound/player/telein.wav" );
01646         cgs.media.teleOutSound = trap_S_RegisterSound( "sound/player/teleout.wav" );
01647         cgs.media.respawnSound = trap_S_RegisterSound( "sound/items/respawn1.wav" );
01648 
01649         trap_S_RegisterSound( "sound/movers/objects/objectHit.wav" );
01650 
01651         cgs.media.talkSound = trap_S_RegisterSound( "sound/player/talk.wav" );
01652         cgs.media.landSound = trap_S_RegisterSound( "sound/player/land1.wav");
01653         cgs.media.fallSound = trap_S_RegisterSound( "sound/player/fallsplat.wav");
01654 
01655         cgs.media.crackleSound = trap_S_RegisterSound( "sound/effects/energy_crackle.wav" );
01656 #ifdef JK2AWARDS
01657         cgs.media.impressiveSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM025" );
01658         cgs.media.excellentSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM053" );
01659         cgs.media.deniedSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM017" );
01660         cgs.media.humiliationSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM019" );
01661         cgs.media.defendSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM024" );
01662 #endif
01663 
01664         /*
01665         cgs.media.takenLeadSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM051");
01666         cgs.media.tiedLeadSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM032");
01667         cgs.media.lostLeadSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM052");
01668         */
01669 
01670         cgs.media.rollSound                                     = trap_S_RegisterSound( "sound/player/roll1.wav");
01671 
01672         cgs.media.noforceSound                          = trap_S_RegisterSound( "sound/weapons/force/noforce" );
01673 
01674         cgs.media.watrInSound                           = trap_S_RegisterSound( "sound/player/watr_in.wav");
01675         cgs.media.watrOutSound                          = trap_S_RegisterSound( "sound/player/watr_out.wav");
01676         cgs.media.watrUnSound                           = trap_S_RegisterSound( "sound/player/watr_un.wav");
01677 
01678         cgs.media.explosionModel                        = trap_R_RegisterModel ( "models/map_objects/mp/sphere.md3" );
01679         cgs.media.surfaceExplosionShader        = trap_R_RegisterShader( "surfaceExplosion" );
01680 
01681         cgs.media.disruptorShader                       = trap_R_RegisterShader( "gfx/effects/burn");
01682 
01683         if (cg_buildScript.integer)
01684         {
01685                 trap_R_RegisterShader( "gfx/effects/turretflashdie" );
01686         }
01687 
01688         cgs.media.solidWhite = trap_R_RegisterShader( "gfx/effects/solidWhite_cull" );
01689 
01690         trap_R_RegisterShader("gfx/misc/mp_light_enlight_disable");
01691         trap_R_RegisterShader("gfx/misc/mp_dark_enlight_disable");
01692 
01693         trap_R_RegisterModel ( "models/map_objects/mp/sphere.md3" );
01694         trap_R_RegisterModel("models/items/remote.md3");
01695 
01696         cgs.media.holocronPickup = trap_S_RegisterSound( "sound/player/holocron.wav" );
01697 
01698         // Zoom
01699         cgs.media.zoomStart = trap_S_RegisterSound( "sound/interface/zoomstart.wav" );
01700         cgs.media.zoomLoop      = trap_S_RegisterSound( "sound/interface/zoomloop.wav" );
01701         cgs.media.zoomEnd       = trap_S_RegisterSound( "sound/interface/zoomend.wav" );
01702 
01703         for (i=0 ; i<4 ; i++) {
01704                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/stone_step%i.wav", i+1);
01705                 cgs.media.footsteps[FOOTSTEP_STONEWALK][i] = trap_S_RegisterSound (name);
01706                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/stone_run%i.wav", i+1);
01707                 cgs.media.footsteps[FOOTSTEP_STONERUN][i] = trap_S_RegisterSound (name);
01708 
01709                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/metal_step%i.wav", i+1);
01710                 cgs.media.footsteps[FOOTSTEP_METALWALK][i] = trap_S_RegisterSound (name);
01711                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/metal_run%i.wav", i+1);
01712                 cgs.media.footsteps[FOOTSTEP_METALRUN][i] = trap_S_RegisterSound (name);
01713 
01714                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/pipe_step%i.wav", i+1);
01715                 cgs.media.footsteps[FOOTSTEP_PIPEWALK][i] = trap_S_RegisterSound (name);
01716                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/pipe_run%i.wav", i+1);
01717                 cgs.media.footsteps[FOOTSTEP_PIPERUN][i] = trap_S_RegisterSound (name);
01718 
01719                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/water_run%i.wav", i+1);
01720                 cgs.media.footsteps[FOOTSTEP_SPLASH][i] = trap_S_RegisterSound (name);
01721 
01722                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/water_walk%i.wav", i+1);
01723                 cgs.media.footsteps[FOOTSTEP_WADE][i] = trap_S_RegisterSound (name);
01724 
01725                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/water_wade_0%i.wav", i+1);
01726                 cgs.media.footsteps[FOOTSTEP_SWIM][i] = trap_S_RegisterSound (name);
01727 
01728                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/snow_step%i.wav", i+1);
01729                 cgs.media.footsteps[FOOTSTEP_SNOWWALK][i] = trap_S_RegisterSound (name);
01730                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/snow_run%i.wav", i+1);
01731                 cgs.media.footsteps[FOOTSTEP_SNOWRUN][i] = trap_S_RegisterSound (name);
01732 
01733                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/sand_walk%i.wav", i+1);
01734                 cgs.media.footsteps[FOOTSTEP_SANDWALK][i] = trap_S_RegisterSound (name);
01735                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/sand_run%i.wav", i+1);
01736                 cgs.media.footsteps[FOOTSTEP_SANDRUN][i] = trap_S_RegisterSound (name);
01737 
01738                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/grass_step%i.wav", i+1);
01739                 cgs.media.footsteps[FOOTSTEP_GRASSWALK][i] = trap_S_RegisterSound (name);
01740                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/grass_run%i.wav", i+1);
01741                 cgs.media.footsteps[FOOTSTEP_GRASSRUN][i] = trap_S_RegisterSound (name);
01742 
01743                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/dirt_step%i.wav", i+1);
01744                 cgs.media.footsteps[FOOTSTEP_DIRTWALK][i] = trap_S_RegisterSound (name);
01745                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/dirt_run%i.wav", i+1);
01746                 cgs.media.footsteps[FOOTSTEP_DIRTRUN][i] = trap_S_RegisterSound (name);
01747 
01748                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/mud_walk%i.wav", i+1);
01749                 cgs.media.footsteps[FOOTSTEP_MUDWALK][i] = trap_S_RegisterSound (name);
01750                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/mud_run%i.wav", i+1);
01751                 cgs.media.footsteps[FOOTSTEP_MUDRUN][i] = trap_S_RegisterSound (name);
01752 
01753                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/gravel_walk%i.wav", i+1);
01754                 cgs.media.footsteps[FOOTSTEP_GRAVELWALK][i] = trap_S_RegisterSound (name);
01755                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/gravel_run%i.wav", i+1);
01756                 cgs.media.footsteps[FOOTSTEP_GRAVELRUN][i] = trap_S_RegisterSound (name);
01757 
01758                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/rug_step%i.wav", i+1);
01759                 cgs.media.footsteps[FOOTSTEP_RUGWALK][i] = trap_S_RegisterSound (name);
01760                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/rug_run%i.wav", i+1);
01761                 cgs.media.footsteps[FOOTSTEP_RUGRUN][i] = trap_S_RegisterSound (name);
01762 
01763                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/wood_walk%i.wav", i+1);
01764                 cgs.media.footsteps[FOOTSTEP_WOODWALK][i] = trap_S_RegisterSound (name);
01765                 Com_sprintf (name, sizeof(name), "sound/player/footsteps/wood_run%i.wav", i+1);
01766                 cgs.media.footsteps[FOOTSTEP_WOODRUN][i] = trap_S_RegisterSound (name);
01767         }
01768 
01769         // only register the items that the server says we need
01770         strcpy( items, CG_ConfigString( CS_ITEMS ) );
01771 
01772         for ( i = 1 ; i < bg_numItems ; i++ ) {
01773                 if ( items[ i ] == '1' || cg_buildScript.integer ) {
01774                         CG_RegisterItemSounds( i );
01775                 }
01776         }
01777 
01778         for ( i = 1 ; i < MAX_SOUNDS ; i++ ) {
01779                 soundName = CG_ConfigString( CS_SOUNDS+i );
01780                 if ( !soundName[0] ) {
01781                         break;
01782                 }
01783                 if ( soundName[0] == '*' )
01784                 {
01785                         if (soundName[1] == '$')
01786                         { //an NPC soundset
01787                                 CG_PrecacheNPCSounds(soundName);
01788                         }
01789                         continue;       // custom sound
01790                 }
01791                 cgs.gameSounds[i] = trap_S_RegisterSound( soundName );
01792         }
01793 
01794         for ( i = 1 ; i < MAX_FX ; i++ ) {
01795                 soundName = CG_ConfigString( CS_EFFECTS+i );
01796                 if ( !soundName[0] ) {
01797                         break;
01798                 }
01799 
01800                 if (soundName[0] == '*')
01801                 { //it's a special global weather effect
01802                         CG_ParseWeatherEffect(soundName);
01803                         cgs.gameEffects[i] = 0;
01804                 }
01805                 else
01806                 {
01807                         cgs.gameEffects[i] = trap_FX_RegisterEffect( soundName );
01808                 }
01809         }
01810 
01811         // register all the server specified icons
01812         for ( i = 1; i < MAX_ICONS; i ++ )
01813         {
01814                 const char* iconName;
01815 
01816                 iconName = CG_ConfigString ( CS_ICONS + i );
01817                 if ( !iconName[0] )
01818                 {
01819                         break;
01820                 }
01821 
01822                 cgs.gameIcons[i] = trap_R_RegisterShaderNoMip ( iconName );
01823         }
01824 
01825         soundName = CG_ConfigString(CS_SIEGE_STATE);
01826 
01827         if (soundName[0])
01828         {
01829                 CG_ParseSiegeState(soundName);
01830         }
01831 
01832         soundName = CG_ConfigString(CS_SIEGE_WINTEAM);
01833 
01834         if (soundName[0])
01835         {
01836                 cg_siegeWinTeam = atoi(soundName);
01837         }
01838 
01839         if (cgs.gametype == GT_SIEGE)
01840         {
01841                 CG_ParseSiegeObjectiveStatus(CG_ConfigString(CS_SIEGE_OBJECTIVES));
01842                 cg_beatingSiegeTime = atoi(CG_ConfigString(CS_SIEGE_TIMEOVERRIDE));
01843                 if ( cg_beatingSiegeTime )
01844                 {
01845                         CG_SetSiegeTimerCvar ( cg_beatingSiegeTime );
01846                 }
01847         }
01848 
01849         cg.loadLCARSStage = 2;
01850 
01851         // FIXME: only needed with item
01852         cgs.media.deploySeeker = trap_S_RegisterSound ("sound/chars/seeker/misc/hiss");
01853         cgs.media.medkitSound = trap_S_RegisterSound ("sound/items/use_bacta.wav");
01854         
01855         cgs.media.winnerSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM006" );
01856         cgs.media.loserSound = trap_S_RegisterSound( "sound/chars/protocol/misc/40MOM010" );
01857 }
01858 
01859 
01860 //-------------------------------------
01861 // CG_RegisterEffects
01862 // 
01863 // Handles precaching all effect files
01864 //      and any shader, model, or sound
01865 //      files an effect may use.
01866 //-------------------------------------
01867 static void CG_RegisterEffects( void )
01868 {
01869         /*
01870         const char      *effectName;
01871         int                     i;
01872 
01873         for ( i = 1 ; i < MAX_FX ; i++ ) 
01874         {
01875                 effectName = CG_ConfigString( CS_EFFECTS + i );
01876 
01877                 if ( !effectName[0] ) 
01878                 {
01879                         break;
01880                 }
01881 
01882                 trap_FX_RegisterEffect( effectName );
01883         }
01884         */
01885         //the above was redundant as it's being done in CG_RegisterSounds
01886 
01887         // Set up the glass effects mini-system.
01888         CG_InitGlass();
01889 
01890         //footstep effects
01891         cgs.effects.footstepMud = trap_FX_RegisterEffect( "materials/mud" );
01892         cgs.effects.footstepSand = trap_FX_RegisterEffect( "materials/sand" );
01893         cgs.effects.footstepSnow = trap_FX_RegisterEffect( "materials/snow" );
01894         cgs.effects.footstepGravel = trap_FX_RegisterEffect( "materials/gravel" );
01895         //landing effects
01896         cgs.effects.landingMud = trap_FX_RegisterEffect( "materials/mud_large" );
01897         cgs.effects.landingSand = trap_FX_RegisterEffect( "materials/sand_large" );
01898         cgs.effects.landingDirt = trap_FX_RegisterEffect( "materials/dirt_large" );
01899         cgs.effects.landingSnow = trap_FX_RegisterEffect( "materials/snow_large" );
01900         cgs.effects.landingGravel = trap_FX_RegisterEffect( "materials/gravel_large" );
01901         //splashes
01902         cgs.effects.waterSplash = trap_FX_RegisterEffect( "env/water_impact" );
01903         cgs.effects.lavaSplash = trap_FX_RegisterEffect( "env/lava_splash" );
01904         cgs.effects.acidSplash = trap_FX_RegisterEffect( "env/acid_splash" );
01905 }
01906 
01907 //===================================================================================
01908 
01909 extern char *forceHolocronModels[];
01910 int CG_HandleAppendedSkin(char *modelName);
01911 void CG_CacheG2AnimInfo(char *modelName);
01912 /*
01913 =================
01914 CG_RegisterGraphics
01915 
01916 This function may execute for a couple of minutes with a slow disk.
01917 =================
01918 */
01919 static void CG_RegisterGraphics( void ) {
01920         int                     i;
01921         int                     breakPoint;
01922         char            items[MAX_ITEMS+1];
01923         const char      *terrainInfo;
01924         int                     terrainID;
01925 
01926         static char             *sb_nums[11] = {
01927                 "gfx/2d/numbers/zero",
01928                 "gfx/2d/numbers/one",
01929                 "gfx/2d/numbers/two",
01930                 "gfx/2d/numbers/three",
01931                 "gfx/2d/numbers/four",
01932                 "gfx/2d/numbers/five",
01933                 "gfx/2d/numbers/six",
01934                 "gfx/2d/numbers/seven",
01935                 "gfx/2d/numbers/eight",
01936                 "gfx/2d/numbers/nine",
01937                 "gfx/2d/numbers/minus",
01938         };
01939 
01940         static char             *sb_t_nums[11] = {
01941                 "gfx/2d/numbers/t_zero",
01942                 "gfx/2d/numbers/t_one",
01943                 "gfx/2d/numbers/t_two",
01944                 "gfx/2d/numbers/t_three",
01945                 "gfx/2d/numbers/t_four",
01946                 "gfx/2d/numbers/t_five",
01947                 "gfx/2d/numbers/t_six",
01948                 "gfx/2d/numbers/t_seven",
01949                 "gfx/2d/numbers/t_eight",
01950                 "gfx/2d/numbers/t_nine",
01951                 "gfx/2d/numbers/t_minus",
01952         };
01953 
01954         static char             *sb_c_nums[11] = {
01955                 "gfx/2d/numbers/c_zero",
01956                 "gfx/2d/numbers/c_one",
01957                 "gfx/2d/numbers/c_two",
01958                 "gfx/2d/numbers/c_three",
01959                 "gfx/2d/numbers/c_four",
01960                 "gfx/2d/numbers/c_five",
01961                 "gfx/2d/numbers/c_six",
01962                 "gfx/2d/numbers/c_seven",
01963                 "gfx/2d/numbers/c_eight",
01964                 "gfx/2d/numbers/c_nine",
01965                 "gfx/2d/numbers/t_minus", //?????
01966         };
01967 
01968         // clear any references to old media
01969         memset( &cg.refdef, 0, sizeof( cg.refdef ) );
01970         trap_R_ClearScene();
01971 
01972         CG_LoadingString( cgs.mapname );        
01973 
01974 //#ifndef _XBOX
01975         trap_R_LoadWorldMap( cgs.mapname );
01976 //#endif
01977 
01978         // precache status bar pics
01979 //      CG_LoadingString( "game media" );
01980 
01981         for ( i=0 ; i<11 ; i++) {
01982                 cgs.media.numberShaders[i] = trap_R_RegisterShader( sb_nums[i] );
01983         }
01984 
01985         cg.loadLCARSStage = 3;
01986 
01987         for ( i=0; i < 11; i++ )
01988         {
01989                 cgs.media.numberShaders[i]                      = trap_R_RegisterShaderNoMip( sb_nums[i] );
01990                 cgs.media.smallnumberShaders[i]         = trap_R_RegisterShaderNoMip( sb_t_nums[i] );
01991                 cgs.media.chunkyNumberShaders[i]        = trap_R_RegisterShaderNoMip( sb_c_nums[i] );
01992         }
01993 
01994         trap_R_RegisterShaderNoMip ( "gfx/mp/pduel_icon_lone" );
01995         trap_R_RegisterShaderNoMip ( "gfx/mp/pduel_icon_double" );
01996 
01997         cgs.media.balloonShader = trap_R_RegisterShader( "gfx/mp/chat_icon" );
01998         cgs.media.vchatShader = trap_R_RegisterShader( "gfx/mp/vchat_icon" );
01999 
02000         cgs.media.deferShader = trap_R_RegisterShaderNoMip( "gfx/2d/defer.tga" );
02001 
02002         cgs.media.radarShader                   = trap_R_RegisterShaderNoMip ( "gfx/menus/radar/radar.png" );
02003         cgs.media.siegeItemShader               = trap_R_RegisterShaderNoMip ( "gfx/menus/radar/goalitem" );
02004         cgs.media.mAutomapPlayerIcon    = trap_R_RegisterShader( "gfx/menus/radar/arrow_w" );
02005         cgs.media.mAutomapRocketIcon    = trap_R_RegisterShader( "gfx/menus/radar/rocket" );
02006 
02007         cgs.media.wireframeAutomapFrame_left = trap_R_RegisterShader( "gfx/mp_automap/mpauto_frame_left" );
02008         cgs.media.wireframeAutomapFrame_right = trap_R_RegisterShader( "gfx/mp_automap/mpauto_frame_right" );
02009         cgs.media.wireframeAutomapFrame_top = trap_R_RegisterShader( "gfx/mp_automap/mpauto_frame_top" );
02010         cgs.media.wireframeAutomapFrame_bottom = trap_R_RegisterShader( "gfx/mp_automap/mpauto_frame_bottom" );
02011 
02012         cgs.media.lagometerShader = trap_R_RegisterShaderNoMip("gfx/2d/lag" );
02013         cgs.media.connectionShader = trap_R_RegisterShaderNoMip( "gfx/2d/net" );
02014 
02015         trap_FX_InitSystem(&cg.refdef);
02016         CG_RegisterEffects();
02017 
02018         cgs.media.boltShader = trap_R_RegisterShader( "gfx/misc/blueLine" );
02019 
02020         cgs.effects.turretShotEffect = trap_FX_RegisterEffect( "turret/shot" );
02021         cgs.effects.mEmplacedDeadSmoke = trap_FX_RegisterEffect("emplaced/dead_smoke.efx");
02022         cgs.effects.mEmplacedExplode = trap_FX_RegisterEffect("emplaced/explode.efx");
02023         cgs.effects.mTurretExplode = trap_FX_RegisterEffect("turret/explode.efx");
02024         cgs.effects.mSparkExplosion = trap_FX_RegisterEffect("sparks/spark_explosion.efx");
02025         cgs.effects.mTripmineExplosion = trap_FX_RegisterEffect("tripMine/explosion.efx");
02026         cgs.effects.mDetpackExplosion = trap_FX_RegisterEffect("detpack/explosion.efx");
02027         cgs.effects.mFlechetteAltBlow = trap_FX_RegisterEffect("flechette/alt_blow.efx");
02028         cgs.effects.mStunBatonFleshImpact = trap_FX_RegisterEffect("stunBaton/flesh_impact.efx");
02029         cgs.effects.mAltDetonate = trap_FX_RegisterEffect("demp2/altDetonate.efx");
02030         cgs.effects.mSparksExplodeNoSound = trap_FX_RegisterEffect("sparks/spark_exp_nosnd");
02031         cgs.effects.mTripMineLaster = trap_FX_RegisterEffect("tripMine/laser.efx");
02032         cgs.effects.mEmplacedMuzzleFlash = trap_FX_RegisterEffect( "effects/emplaced/muzzle_flash" );
02033         cgs.effects.mConcussionAltRing = trap_FX_RegisterEffect("concussion/alt_ring");
02034 
02035         cgs.effects.mHyperspaceStars = trap_FX_RegisterEffect("ships/hyperspace_stars");
02036         cgs.effects.mBlackSmoke = trap_FX_RegisterEffect( "volumetric/black_smoke" );
02037         cgs.effects.mShipDestDestroyed = trap_FX_RegisterEffect("effects/ships/dest_destroyed.efx");
02038         cgs.effects.mShipDestBurning = trap_FX_RegisterEffect("effects/ships/dest_burning.efx");
02039         cgs.effects.mBobaJet = trap_FX_RegisterEffect("effects/boba/jet.efx");
02040 
02041 
02042         cgs.effects.itemCone = trap_FX_RegisterEffect("mp/itemcone.efx");
02043         cgs.effects.mTurretMuzzleFlash = trap_FX_RegisterEffect("effects/turret/muzzle_flash.efx");
02044         cgs.effects.mSparks = trap_FX_RegisterEffect("sparks/spark_nosnd.efx"); //sparks/spark.efx
02045         cgs.effects.mSaberCut = trap_FX_RegisterEffect("saber/saber_cut.efx");
02046         cgs.effects.mSaberBlock = trap_FX_RegisterEffect("saber/saber_block.efx");
02047         cgs.effects.mSaberBloodSparks = trap_FX_RegisterEffect("saber/blood_sparks_mp.efx");
02048         cgs.effects.mSaberBloodSparksSmall = trap_FX_RegisterEffect("saber/blood_sparks_25_mp.efx");
02049         cgs.effects.mSaberBloodSparksMid = trap_FX_RegisterEffect("saber/blood_sparks_50_mp.efx");
02050         cgs.effects.mSpawn = trap_FX_RegisterEffect("mp/spawn.efx");
02051         cgs.effects.mJediSpawn = trap_FX_RegisterEffect("mp/jedispawn.efx");
02052         cgs.effects.mBlasterDeflect = trap_FX_RegisterEffect("blaster/deflect.efx");
02053         cgs.effects.mBlasterSmoke = trap_FX_RegisterEffect("blaster/smoke_bolton");
02054         cgs.effects.mForceConfustionOld = trap_FX_RegisterEffect("force/confusion_old.efx");
02055 
02056         cgs.effects.forceLightning              = trap_FX_RegisterEffect( "effects/force/lightning.efx" );
02057         cgs.effects.forceLightningWide  = trap_FX_RegisterEffect( "effects/force/lightningwide.efx" );
02058         cgs.effects.forceDrain          = trap_FX_RegisterEffect( "effects/mp/drain.efx" );
02059         cgs.effects.forceDrainWide      = trap_FX_RegisterEffect( "effects/mp/drainwide.efx" );
02060         cgs.effects.forceDrained        = trap_FX_RegisterEffect( "effects/mp/drainhit.efx");
02061 
02062         cgs.effects.mDisruptorDeathSmoke = trap_FX_RegisterEffect("disruptor/death_smoke");
02063 
02064         for ( i = 0 ; i < NUM_CROSSHAIRS ; i++ ) {
02065                 cgs.media.crosshairShader[i] = trap_R_RegisterShaderNoMip( va("gfx/2d/crosshair%c", 'a'+i) );
02066         }
02067 
02068         cg.loadLCARSStage = 4;
02069 
02070         cgs.media.backTileShader = trap_R_RegisterShader( "gfx/2d/backtile" );
02071 
02072         //precache the fpls skin
02073         //trap_R_RegisterSkin("models/players/kyle/model_fpls2.skin");
02074 
02075         cgs.media.itemRespawningPlaceholder = trap_R_RegisterShader("powerups/placeholder");
02076         cgs.media.itemRespawningRezOut = trap_R_RegisterShader("powerups/rezout");
02077 
02078         cgs.media.playerShieldDamage = trap_R_RegisterShader("gfx/misc/personalshield");
02079         cgs.media.protectShader = trap_R_RegisterShader("gfx/misc/forceprotect");
02080         cgs.media.forceSightBubble = trap_R_RegisterShader("gfx/misc/sightbubble");
02081         cgs.media.forceShell = trap_R_RegisterShader("powerups/forceshell");
02082         cgs.media.sightShell = trap_R_RegisterShader("powerups/sightshell");
02083 
02084         cgs.media.itemHoloModel = trap_R_RegisterModel("models/map_objects/mp/holo.md3");
02085 
02086         if (cgs.gametype == GT_HOLOCRON || cg_buildScript.integer)
02087         {
02088                 for ( i=0; i < NUM_FORCE_POWERS; i++ )
02089                 {
02090                         if (forceHolocronModels[i] &&
02091                                 forceHolocronModels[i][0])
02092                         {
02093                                 trap_R_RegisterModel(forceHolocronModels[i]);
02094                         }
02095                 }
02096         }
02097 
02098         if ( cgs.gametype == GT_CTF || cgs.gametype == GT_CTY || cg_buildScript.integer ) {
02099                 if (cg_buildScript.integer)
02100                 {
02101                         trap_R_RegisterModel( "models/flags/r_flag.md3" );
02102                         trap_R_RegisterModel( "models/flags/b_flag.md3" );
02103                         trap_R_RegisterModel( "models/flags/r_flag_ysal.md3" );
02104                         trap_R_RegisterModel( "models/flags/b_flag_ysal.md3" );
02105                 }
02106 
02107                 if (cgs.gametype == GT_CTF)
02108                 {
02109                         cgs.media.redFlagModel = trap_R_RegisterModel( "models/flags/r_flag.md3" );
02110                         cgs.media.blueFlagModel = trap_R_RegisterModel( "models/flags/b_flag.md3" );
02111                 }
02112                 else
02113                 {
02114                         cgs.media.redFlagModel = trap_R_RegisterModel( "models/flags/r_flag_ysal.md3" );
02115                         cgs.media.blueFlagModel = trap_R_RegisterModel( "models/flags/b_flag_ysal.md3" );
02116                 }
02117 
02118                 trap_R_RegisterShaderNoMip( "gfx/hud/mpi_rflag_x" );
02119                 trap_R_RegisterShaderNoMip( "gfx/hud/mpi_bflag_x" );
02120 
02121                 trap_R_RegisterShaderNoMip( "gfx/hud/mpi_rflag_ys" );
02122                 trap_R_RegisterShaderNoMip( "gfx/hud/mpi_bflag_ys" );
02123 
02124                 trap_R_RegisterShaderNoMip( "gfx/hud/mpi_rflag" );
02125                 trap_R_RegisterShaderNoMip( "gfx/hud/mpi_bflag" );
02126 
02127                 trap_R_RegisterShaderNoMip("gfx/2d/net.tga");
02128 
02129                 cgs.media.flagPoleModel = trap_R_RegisterModel( "models/flag2/flagpole.md3" );
02130                 cgs.media.flagFlapModel = trap_R_RegisterModel( "models/flag2/flagflap3.md3" );
02131 
02132                 cgs.media.redFlagBaseModel = trap_R_RegisterModel( "models/mapobjects/flagbase/red_base.md3" );
02133                 cgs.media.blueFlagBaseModel = trap_R_RegisterModel( "models/mapobjects/flagbase/blue_base.md3" );
02134                 cgs.media.neutralFlagBaseModel = trap_R_RegisterModel( "models/mapobjects/flagbase/ntrl_base.md3" );
02135         }
02136 
02137         if ( cgs.gametype >= GT_TEAM || cg_buildScript.integer ) {
02138                 cgs.media.teamRedShader = trap_R_RegisterShader( "sprites/team_red" );
02139                 cgs.media.teamBlueShader = trap_R_RegisterShader( "sprites/team_blue" );
02140                 //cgs.media.redQuadShader = trap_R_RegisterShader("powerups/blueflag" );
02141                 cgs.media.teamStatusBar = trap_R_RegisterShader( "gfx/2d/colorbar.tga" );
02142         }
02143         else if ( cgs.gametype == GT_JEDIMASTER )
02144         {
02145                 cgs.media.teamRedShader = trap_R_RegisterShader( "sprites/team_red" );
02146         }
02147 
02148         if (cgs.gametype == GT_POWERDUEL || cg_buildScript.integer)
02149         {
02150                 cgs.media.powerDuelAllyShader = trap_R_RegisterShader("gfx/mp/pduel_icon_double");//trap_R_RegisterShader("gfx/mp/pduel_gameicon_ally");
02151         }
02152 
02153         cgs.media.heartShader                   = trap_R_RegisterShaderNoMip( "ui/assets/statusbar/selectedhealth.tga" );
02154 
02155         cgs.media.ysaliredShader                = trap_R_RegisterShader( "powerups/ysaliredshell");
02156         cgs.media.ysaliblueShader               = trap_R_RegisterShader( "powerups/ysaliblueshell");
02157         cgs.media.ysalimariShader               = trap_R_RegisterShader( "powerups/ysalimarishell");
02158         cgs.media.boonShader                    = trap_R_RegisterShader( "powerups/boonshell");
02159         cgs.media.endarkenmentShader    = trap_R_RegisterShader( "powerups/endarkenmentshell");
02160         cgs.media.enlightenmentShader   = trap_R_RegisterShader( "powerups/enlightenmentshell");
02161         cgs.media.invulnerabilityShader = trap_R_RegisterShader( "powerups/invulnerabilityshell");
02162 
02163 #ifdef JK2AWARDS
02164         cgs.media.medalImpressive               = trap_R_RegisterShaderNoMip( "medal_impressive" );
02165         cgs.media.medalExcellent                = trap_R_RegisterShaderNoMip( "medal_excellent" );
02166         cgs.media.medalGauntlet                 = trap_R_RegisterShaderNoMip( "medal_gauntlet" );
02167         cgs.media.medalDefend                   = trap_R_RegisterShaderNoMip( "medal_defend" );
02168         cgs.media.medalAssist                   = trap_R_RegisterShaderNoMip( "medal_assist" );
02169         cgs.media.medalCapture                  = trap_R_RegisterShaderNoMip( "medal_capture" );
02170 #endif
02171 
02172         // Binocular interface
02173         cgs.media.binocularCircle               = trap_R_RegisterShader( "gfx/2d/binCircle" );
02174         cgs.media.binocularMask                 = trap_R_RegisterShader( "gfx/2d/binMask" );
02175         cgs.media.binocularArrow                = trap_R_RegisterShader( "gfx/2d/binSideArrow" );
02176         cgs.media.binocularTri                  = trap_R_RegisterShader( "gfx/2d/binTopTri" );
02177         cgs.media.binocularStatic               = trap_R_RegisterShader( "gfx/2d/binocularWindow" );
02178         cgs.media.binocularOverlay              = trap_R_RegisterShader( "gfx/2d/binocularNumOverlay" );
02179 
02180         cg.loadLCARSStage = 5;
02181 
02182         // Chunk models
02183         //FIXME: jfm:? bother to conditionally load these if an ent has this material type?
02184         for ( i = 0; i < NUM_CHUNK_MODELS; i++ )
02185         {
02186                 cgs.media.chunkModels[CHUNK_METAL2][i]  = trap_R_RegisterModel( va( "models/chunks/metal/metal1_%i.md3", i+1 ) ); //_ /switched\ _
02187                 cgs.media.chunkModels[CHUNK_METAL1][i]  = trap_R_RegisterModel( va( "models/chunks/metal/metal2_%i.md3", i+1 ) ); //  \switched/
02188                 cgs.media.chunkModels[CHUNK_ROCK1][i]   = trap_R_RegisterModel( va( "models/chunks/rock/rock1_%i.md3", i+1 ) );
02189                 cgs.media.chunkModels[CHUNK_ROCK2][i]   = trap_R_RegisterModel( va( "models/chunks/rock/rock2_%i.md3", i+1 ) );
02190                 cgs.media.chunkModels[CHUNK_ROCK3][i]   = trap_R_RegisterModel( va( "models/chunks/rock/rock3_%i.md3", i+1 ) );
02191                 cgs.media.chunkModels[CHUNK_CRATE1][i]  = trap_R_RegisterModel( va( "models/chunks/crate/crate1_%i.md3", i+1 ) );
02192                 cgs.media.chunkModels[CHUNK_CRATE2][i]  = trap_R_RegisterModel( va( "models/chunks/crate/crate2_%i.md3", i+1 ) );
02193                 cgs.media.chunkModels[CHUNK_WHITE_METAL][i]     = trap_R_RegisterModel( va( "models/chunks/metal/wmetal1_%i.md3", i+1 ) );
02194         }
02195 
02196         cgs.media.chunkSound                    = trap_S_RegisterSound("sound/weapons/explosions/glasslcar");
02197         cgs.media.grateSound                    = trap_S_RegisterSound( "sound/effects/grate_destroy" );
02198         cgs.media.rockBreakSound                = trap_S_RegisterSound("sound/effects/wall_smash");
02199         cgs.media.rockBounceSound[0]    = trap_S_RegisterSound("sound/effects/stone_bounce");
02200         cgs.media.rockBounceSound[1]    = trap_S_RegisterSound("sound/effects/stone_bounce2");
02201         cgs.media.metalBounceSound[0]   = trap_S_RegisterSound("sound/effects/metal_bounce");
02202         cgs.media.metalBounceSound[1]   = trap_S_RegisterSound("sound/effects/metal_bounce2");
02203         cgs.media.glassChunkSound               = trap_S_RegisterSound("sound/weapons/explosions/glassbreak1");
02204         cgs.media.crateBreakSound[0]    = trap_S_RegisterSound("sound/weapons/explosions/crateBust1" );
02205         cgs.media.crateBreakSound[1]    = trap_S_RegisterSound("sound/weapons/explosions/crateBust2" );
02206 
02207 /*
02208 Ghoul2 Insert Start
02209 */
02210         CG_InitItems();
02211 /*
02212 Ghoul2 Insert End
02213 */
02214         memset( cg_weapons, 0, sizeof( cg_weapons ) );
02215 
02216         // only register the items that the server says we need
02217         strcpy( items, CG_ConfigString( CS_ITEMS) );
02218 
02219         for ( i = 1 ; i < bg_numItems ; i++ ) {
02220                 if ( items[ i ] == '1' || cg_buildScript.integer ) {
02221                         CG_LoadingItem( i );
02222                         CG_RegisterItemVisuals( i );
02223                 }
02224         }
02225 
02226         cg.loadLCARSStage = 6;
02227 
02228         cgs.media.glassShardShader      = trap_R_RegisterShader( "gfx/misc/test_crackle" );
02229 
02230         // doing one shader just makes it look like a shell.  By using two shaders with different bulge offsets and different texture scales, it has a much more chaotic look
02231         cgs.media.electricBodyShader                    = trap_R_RegisterShader( "gfx/misc/electric" );
02232         cgs.media.electricBody2Shader                   = trap_R_RegisterShader( "gfx/misc/fullbodyelectric2" );
02233 
02234         cgs.media.fsrMarkShader                                 = trap_R_RegisterShader( "footstep_r" );
02235         cgs.media.fslMarkShader                                 = trap_R_RegisterShader( "footstep_l" );
02236         cgs.media.fshrMarkShader                                = trap_R_RegisterShader( "footstep_heavy_r" );
02237         cgs.media.fshlMarkShader                                = trap_R_RegisterShader( "footstep_heavy_l" );
02238 
02239         cgs.media.refractionShader                              = trap_R_RegisterShader("effects/refraction");
02240 
02241         cgs.media.cloakedShader                                 = trap_R_RegisterShader( "gfx/effects/cloakedShader" );
02242 
02243         // wall marks
02244         cgs.media.shadowMarkShader      = trap_R_RegisterShader( "markShadow" );
02245         cgs.media.wakeMarkShader        = trap_R_RegisterShader( "wake" );
02246 
02247         cgs.media.viewPainShader                                        = trap_R_RegisterShader( "gfx/misc/borgeyeflare" );
02248         cgs.media.viewPainShader_Shields                        = trap_R_RegisterShader( "gfx/mp/dmgshader_shields" );
02249         cgs.media.viewPainShader_ShieldsAndHealth       = trap_R_RegisterShader( "gfx/mp/dmgshader_shieldsandhealth" );
02250 
02251         // register the inline models
02252         breakPoint = cgs.numInlineModels = trap_CM_NumInlineModels();
02253         for ( i = 1 ; i < cgs.numInlineModels ; i++ ) {
02254                 char    name[10];
02255                 vec3_t                  mins, maxs;
02256                 int                             j;
02257 
02258                 Com_sprintf( name, sizeof(name), "*%i", i );
02259                 cgs.inlineDrawModel[i] = trap_R_RegisterModel( name );
02260                 if (!cgs.inlineDrawModel[i])
02261                 {
02262                         breakPoint = i;
02263                         break;
02264                 }
02265 
02266                 trap_R_ModelBounds( cgs.inlineDrawModel[i], mins, maxs );
02267                 for ( j = 0 ; j < 3 ; j++ ) {
02268                         cgs.inlineModelMidpoints[i][j] = mins[j] + 0.5 * ( maxs[j] - mins[j] );
02269                 }
02270         }
02271 
02272         cg.loadLCARSStage = 7;
02273 
02274         // register all the server specified models
02275         for (i=1 ; i<MAX_MODELS ; i++) {
02276                 const char              *cModelName;
02277                 char modelName[MAX_QPATH];
02278 
02279                 cModelName = CG_ConfigString( CS_MODELS+i );
02280                 if ( !cModelName[0] ) {
02281                         break;
02282                 }
02283 
02284                 strcpy(modelName, cModelName);
02285                 if (strstr(modelName, ".glm") || modelName[0] == '$')
02286                 { //Check to see if it has a custom skin attached.
02287                         CG_HandleAppendedSkin(modelName);
02288                         CG_CacheG2AnimInfo(modelName);
02289                 }
02290 
02291                 if (modelName[0] != '$' && modelName[0] != '@')
02292                 { //don't register vehicle names and saber names as models.
02293                         cgs.gameModels[i] = trap_R_RegisterModel( modelName );
02294                 }
02295                 else
02296                 {//FIXME: register here so that stuff gets precached!!!
02297                         cgs.gameModels[i] = 0;
02298                 }
02299         }
02300         cg.loadLCARSStage = 8;
02301 /*
02302 Ghoul2 Insert Start
02303 */
02304 
02305 
02306 //      CG_LoadingString( "BSP instances" );
02307 
02308         for(i = 1; i < MAX_SUB_BSP; i++)
02309         {
02310                 const char              *bspName = 0;
02311                 vec3_t                  mins, maxs;
02312                 int                             j;
02313                 int                             sub = 0;
02314                 char                    temp[MAX_QPATH];
02315 
02316                 bspName = CG_ConfigString( CS_BSP_MODELS+i );
02317                 if ( !bspName[0] ) 
02318                 {
02319                         break;
02320                 }
02321 
02322                 trap_CM_LoadMap( bspName, qtrue );
02323                 cgs.inlineDrawModel[breakPoint] = trap_R_RegisterModel( bspName );
02324                 trap_R_ModelBounds( cgs.inlineDrawModel[breakPoint], mins, maxs );
02325                 for ( j = 0 ; j < 3 ; j++ ) 
02326                 {
02327                         cgs.inlineModelMidpoints[breakPoint][j] = mins[j] + 0.5 * ( maxs[j] - mins[j] );
02328                 }
02329                 breakPoint++;
02330                 for(sub=1;sub<MAX_MODELS;sub++)
02331                 {
02332                         Com_sprintf(temp, MAX_QPATH, "*%d-%d", i, sub);
02333                         cgs.inlineDrawModel[breakPoint] = trap_R_RegisterModel( temp );
02334                         if (!cgs.inlineDrawModel[breakPoint])
02335                         {
02336                                 break;
02337                         }
02338                         trap_R_ModelBounds( cgs.inlineDrawModel[breakPoint], mins, maxs );
02339                         for ( j = 0 ; j < 3 ; j++ ) 
02340                         {
02341                                 cgs.inlineModelMidpoints[breakPoint][j] = mins[j] + 0.5 * ( maxs[j] - mins[j] );
02342                         }
02343                         breakPoint++;
02344                 }
02345         }
02346 
02347 //      CG_LoadingString( "Creating terrain" );
02348         for(i = 1; i < MAX_TERRAINS; i++)
02349         {
02350                 terrainInfo = CG_ConfigString( CS_TERRAINS + i );
02351                 if ( !terrainInfo[0] )
02352                 {
02353                         break;
02354                 }
02355 
02356                 terrainID = trap_CM_RegisterTerrain(terrainInfo);
02357 
02358                 trap_RMG_Init(terrainID, terrainInfo);
02359 
02360                 // Send off the terrainInfo to the renderer
02361                 trap_RE_InitRendererTerrain( terrainInfo );
02362         }
02363 
02364         /*
02365         CG_LoadingString("skins");
02366         // register all the server specified models
02367         for (i=1 ; i<MAX_CHARSKINS ; i++) {
02368                 const char              *modelName;
02369 
02370                 modelName = CG_ConfigString( CS_CHARSKINS+i );
02371                 if ( !modelName[0] ) {
02372                         break;
02373                 }
02374                 cgs.skins[i] = trap_R_RegisterSkin( modelName );
02375         }
02376         */
02377         //rww - removed and replaced with CS_G2BONES. For custom skins
02378         //the new method is to append a * after an indexed model name and
02379         //then append the skin name after that (note that this is only
02380         //used for NPCs)
02381 
02382 //      CG_LoadingString("weapons");
02383 
02384         CG_InitG2Weapons();
02385 
02386 /*
02387 Ghoul2 Insert End
02388 */
02389         cg.loadLCARSStage = 9;
02390 
02391 
02392         // new stuff
02393         cgs.media.patrolShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/patrol.tga");
02394         cgs.media.assaultShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/assault.tga");
02395         cgs.media.campShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/camp.tga");
02396         cgs.media.followShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/follow.tga");
02397         cgs.media.defendShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/defend.tga");
02398         cgs.media.teamLeaderShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/team_leader.tga");
02399         cgs.media.retrieveShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/retrieve.tga");
02400         cgs.media.escortShader = trap_R_RegisterShaderNoMip("ui/assets/statusbar/escort.tga");
02401         cgs.media.cursor = trap_R_RegisterShaderNoMip( "menu/art/3_cursor2" );
02402         cgs.media.sizeCursor = trap_R_RegisterShaderNoMip( "ui/assets/sizecursor.tga" );
02403         cgs.media.selectCursor = trap_R_RegisterShaderNoMip( "ui/assets/selectcursor.tga" );
02404         cgs.media.flagShaders[0] = trap_R_RegisterShaderNoMip("ui/assets/statusbar/flag_in_base.tga");
02405         cgs.media.flagShaders[1] = trap_R_RegisterShaderNoMip("ui/assets/statusbar/flag_capture.tga");
02406         cgs.media.flagShaders[2] = trap_R_RegisterShaderNoMip("ui/assets/statusbar/flag_missing.tga");
02407 
02408         cgs.media.halfShieldModel       = trap_R_RegisterModel ( "models/weaphits/testboom.md3" );
02409         cgs.media.halfShieldShader      = trap_R_RegisterShader( "halfShieldShell" );
02410 
02411         trap_FX_RegisterEffect("force/force_touch");
02412 
02413         CG_ClearParticles ();
02414 /*
02415         for (i=1; i<MAX_PARTICLES_AREAS; i++)
02416         {
02417                 {
02418                         int rval;
02419 
02420                         rval = CG_NewParticleArea ( CS_PARTICLES + i);
02421                         if (!rval)
02422                                 break;
02423                 }
02424         }
02425 */
02426 }
02427 
02428 
02429 const char *CG_GetStringEdString(char *refSection, char *refName)
02430 {
02431         static char text[2][1024]={0};  //just incase it's nested
02432         static int              index = 0;
02433 
02434         index ^= 1;
02435         trap_SP_GetStringTextString(va("%s_%s", refSection, refName), text[index], sizeof(text[0]));
02436         return text[index];
02437 }
02438 
02439 int     CG_GetClassCount(team_t team,int siegeClass );
02440 int CG_GetTeamNonScoreCount(team_t team);
02441 
02442 void CG_SiegeCountCvars( void )
02443 {
02444         int classGfx[6];
02445 
02446         trap_Cvar_Set( "ui_tm1_cnt",va("%d",CG_GetTeamNonScoreCount(TEAM_RED )));
02447         trap_Cvar_Set( "ui_tm2_cnt",va("%d",CG_GetTeamNonScoreCount(TEAM_BLUE )));
02448         trap_Cvar_Set( "ui_tm3_cnt",va("%d",CG_GetTeamNonScoreCount(TEAM_SPECTATOR )));
02449         
02450         // This is because the only way we can match up classes is by the gfx handle. 
02451         classGfx[0] = trap_R_RegisterShaderNoMip("gfx/mp/c_icon_infantry");
02452         classGfx[1] = trap_R_RegisterShaderNoMip("gfx/mp/c_icon_heavy_weapons");
02453         classGfx[2] = trap_R_RegisterShaderNoMip("gfx/mp/c_icon_demolitionist");
02454         classGfx[3] = trap_R_RegisterShaderNoMip("gfx/mp/c_icon_vanguard");
02455         classGfx[4] = trap_R_RegisterShaderNoMip("gfx/mp/c_icon_support");
02456         classGfx[5] = trap_R_RegisterShaderNoMip("gfx/mp/c_icon_jedi_general");
02457 
02458         trap_Cvar_Set( "ui_tm1_c0_cnt",va("%d",CG_GetClassCount(TEAM_RED,classGfx[0])));
02459         trap_Cvar_Set( "ui_tm1_c1_cnt",va("%d",CG_GetClassCount(TEAM_RED,classGfx[1])));
02460         trap_Cvar_Set( "ui_tm1_c2_cnt",va("%d",CG_GetClassCount(TEAM_RED,classGfx[2])));
02461         trap_Cvar_Set( "ui_tm1_c3_cnt",va("%d",CG_GetClassCount(TEAM_RED,classGfx[3])));
02462         trap_Cvar_Set( "ui_tm1_c4_cnt",va("%d",CG_GetClassCount(TEAM_RED,classGfx[4])));
02463         trap_Cvar_Set( "ui_tm1_c5_cnt",va("%d",CG_GetClassCount(TEAM_RED,classGfx[5])));
02464 
02465         trap_Cvar_Set( "ui_tm2_c0_cnt",va("%d",CG_GetClassCount(TEAM_BLUE,classGfx[0])));
02466         trap_Cvar_Set( "ui_tm2_c1_cnt",va("%d",CG_GetClassCount(TEAM_BLUE,classGfx[1])));
02467         trap_Cvar_Set( "ui_tm2_c2_cnt",va("%d",CG_GetClassCount(TEAM_BLUE,classGfx[2])));
02468         trap_Cvar_Set( "ui_tm2_c3_cnt",va("%d",CG_GetClassCount(TEAM_BLUE,classGfx[3])));
02469         trap_Cvar_Set( "ui_tm2_c4_cnt",va("%d",CG_GetClassCount(TEAM_BLUE,classGfx[4])));
02470         trap_Cvar_Set( "ui_tm2_c5_cnt",va("%d",CG_GetClassCount(TEAM_BLUE,classGfx[5])));
02471 
02472 }
02473 
02474 /*                                                                                                                                                                                                                                                                                      
02475 =======================
02476 CG_BuildSpectatorString
02477 
02478 =======================
02479 */
02480 void CG_BuildSpectatorString(void) {
02481         int i;
02482         cg.spectatorList[0] = 0;
02483 
02484         // Count up the number of players per team and per class
02485         CG_SiegeCountCvars();
02486 
02487         for (i = 0; i < MAX_CLIENTS; i++) {
02488                 if (cgs.clientinfo[i].infoValid && cgs.clientinfo[i].team == TEAM_SPECTATOR ) {
02489                         Q_strcat(cg.spectatorList, sizeof(cg.spectatorList), va("%s     ", cgs.clientinfo[i].name));
02490                 }
02491         }
02492         i = strlen(cg.spectatorList);
02493         if (i != cg.spectatorLen) {
02494                 cg.spectatorLen = i;
02495                 cg.spectatorWidth = -1;
02496         }
02497 }
02498 
02499 
02500 /*                                                                                                                                                                                                                                                                                      
02501 ===================
02502 CG_RegisterClients
02503 ===================
02504 */
02505 static void CG_RegisterClients( void ) {
02506         int             i;
02507 
02508         CG_LoadingClient(cg.clientNum);
02509         CG_NewClientInfo(cg.clientNum, qfalse);
02510 
02511         for (i=0 ; i<MAX_CLIENTS ; i++) {
02512                 const char              *clientInfo;
02513 
02514                 if (cg.clientNum == i) {
02515                         continue;
02516                 }
02517 
02518                 clientInfo = CG_ConfigString( CS_PLAYERS+i );
02519                 if ( !clientInfo[0]) {
02520                         continue;
02521                 }
02522                 CG_LoadingClient( i );
02523                 CG_NewClientInfo( i, qfalse);
02524         }
02525         CG_BuildSpectatorString();
02526 }
02527 
02528 //===========================================================================
02529 
02530 /*
02531 =================
02532 CG_ConfigString
02533 =================
02534 */
02535 const char *CG_ConfigString( int index ) {
02536         if ( index < 0 || index >= MAX_CONFIGSTRINGS ) {
02537                 CG_Error( "CG_ConfigString: bad index: %i", index );
02538         }
02539         return cgs.gameState.stringData + cgs.gameState.stringOffsets[ index ];
02540 }
02541 
02542 //==================================================================
02543 
02544 /*
02545 ======================
02546 CG_StartMusic
02547 
02548 ======================
02549 */
02550 void CG_StartMusic( qboolean bForceStart ) {
02551         char    *s;
02552         char    parm1[MAX_QPATH], parm2[MAX_QPATH];
02553 
02554         // start the background music
02555         s = (char *)CG_ConfigString( CS_MUSIC );
02556         Q_strncpyz( parm1, COM_Parse( (const char **)&s ), sizeof( parm1 ) );
02557         Q_strncpyz( parm2, COM_Parse( (const char **)&s ), sizeof( parm2 ) );
02558 
02559         trap_S_StartBackgroundTrack( parm1, parm2, !bForceStart );
02560 }
02561 
02562 #ifndef _XBOX
02563 char *CG_GetMenuBuffer(const char *filename) {
02564         int     len;
02565         fileHandle_t    f;
02566         static char buf[MAX_MENUFILE];
02567 
02568         len = trap_FS_FOpenFile( filename, &f, FS_READ );
02569         if ( !f ) {
02570                 trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) );
02571                 return NULL;
02572         }
02573         if ( len >= MAX_MENUFILE ) {
02574                 trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) );
02575                 trap_FS_FCloseFile( f );
02576                 return NULL;
02577         }
02578 
02579         trap_FS_Read( buf, len, f );
02580         buf[len] = 0;
02581         trap_FS_FCloseFile( f );
02582 
02583         return buf;
02584 }
02585 #endif
02586 
02587 //
02588 // ==============================
02589 // new hud stuff ( mission pack )
02590 // ==============================
02591 //
02592 qboolean CG_Asset_Parse(int handle) {
02593         pc_token_t token;
02594 
02595         if (!trap_PC_ReadToken(handle, &token))
02596                 return qfalse;
02597         if (Q_stricmp(token.string, "{") != 0) {
02598                 return qfalse;
02599         }
02600     
02601         while ( 1 ) {
02602                 if (!trap_PC_ReadToken(handle, &token))
02603                         return qfalse;
02604 
02605                 if (Q_stricmp(token.string, "}") == 0) {
02606                         return qtrue;
02607                 }
02608 
02609                 // font
02610                 if (Q_stricmp(token.string, "font") == 0) {
02611                         int pointSize;
02612                         if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle, &pointSize)) {
02613                                 return qfalse;
02614                         }
02615 
02616 //                      cgDC.registerFont(token.string, pointSize, &cgDC.Assets.textFont);
02617                         cgDC.Assets.qhMediumFont = cgDC.RegisterFont(token.string);
02618                         continue;
02619                 }
02620 
02621                 // smallFont
02622                 if (Q_stricmp(token.string, "smallFont") == 0) {
02623                         int pointSize;
02624                         if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle, &pointSize)) {
02625                                 return qfalse;
02626                         }
02627 //                      cgDC.registerFont(token.string, pointSize, &cgDC.Assets.smallFont);
02628                         cgDC.Assets.qhSmallFont = cgDC.RegisterFont(token.string);
02629                         continue;
02630                 }
02631 
02632                 // smallFont
02633                 if (Q_stricmp(token.string, "small2Font") == 0) {
02634                         int pointSize;
02635                         if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle, &pointSize)) {
02636                                 return qfalse;
02637                         }
02638 //                      cgDC.registerFont(token.string, pointSize, &cgDC.Assets.smallFont);
02639                         cgDC.Assets.qhSmall2Font = cgDC.RegisterFont(token.string);
02640                         continue;
02641                 }
02642 
02643                 // font
02644                 if (Q_stricmp(token.string, "bigfont") == 0) {
02645                         int pointSize;
02646                         if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle, &pointSize)) {
02647                                 return qfalse;
02648                         }
02649 //                      cgDC.registerFont(token.string, pointSize, &cgDC.Assets.bigFont);
02650                         cgDC.Assets.qhBigFont = cgDC.RegisterFont(token.string);
02651                         continue;
02652                 }
02653 
02654                 // gradientbar
02655                 if (Q_stricmp(token.string, "gradientbar") == 0) {
02656                         if (!trap_PC_ReadToken(handle, &token)) {
02657                                 return qfalse;
02658                         }
02659                         cgDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(token.string);
02660                         continue;
02661                 }
02662 
02663                 // enterMenuSound
02664                 if (Q_stricmp(token.string, "menuEnterSound") == 0) {
02665                         if (!trap_PC_ReadToken(handle, &token)) {
02666                                 return qfalse;
02667                         }
02668                         cgDC.Assets.menuEnterSound = trap_S_RegisterSound( token.string );
02669                         continue;
02670                 }
02671 
02672                 // exitMenuSound
02673                 if (Q_stricmp(token.string, "menuExitSound") == 0) {
02674                         if (!trap_PC_ReadToken(handle, &token)) {
02675                                 return qfalse;
02676                         }
02677                         cgDC.Assets.menuExitSound = trap_S_RegisterSound( token.string );
02678                         continue;
02679                 }
02680 
02681                 // itemFocusSound
02682                 if (Q_stricmp(token.string, "itemFocusSound") == 0) {
02683                         if (!trap_PC_ReadToken(handle, &token)) {
02684                                 return qfalse;
02685                         }
02686                         cgDC.Assets.itemFocusSound = trap_S_RegisterSound( token.string );
02687                         continue;
02688                 }
02689 
02690                 // menuBuzzSound
02691                 if (Q_stricmp(token.string, "menuBuzzSound") == 0) {
02692                         if (!trap_PC_ReadToken(handle, &token)) {
02693                                 return qfalse;
02694                         }
02695                         cgDC.Assets.menuBuzzSound = trap_S_RegisterSound( token.string );
02696                         continue;
02697                 }
02698 
02699                 if (Q_stricmp(token.string, "cursor") == 0) {
02700                         if (!PC_String_Parse(handle, &cgDC.Assets.cursorStr)) {
02701                                 return qfalse;
02702                         }
02703                         cgDC.Assets.cursor = trap_R_RegisterShaderNoMip( cgDC.Assets.cursorStr);
02704                         continue;
02705                 }
02706 
02707                 if (Q_stricmp(token.string, "fadeClamp") == 0) {
02708                         if (!PC_Float_Parse(handle, &cgDC.Assets.fadeClamp)) {
02709                                 return qfalse;
02710                         }
02711                         continue;
02712                 }
02713 
02714                 if (Q_stricmp(token.string, "fadeCycle") == 0) {
02715                         if (!PC_Int_Parse(handle, &cgDC.Assets.fadeCycle)) {
02716                                 return qfalse;
02717                         }
02718                         continue;
02719                 }
02720 
02721                 if (Q_stricmp(token.string, "fadeAmount") == 0) {
02722                         if (!PC_Float_Parse(handle, &cgDC.Assets.fadeAmount)) {
02723                                 return qfalse;
02724                         }
02725                         continue;
02726                 }
02727 
02728                 if (Q_stricmp(token.string, "shadowX") == 0) {
02729                         if (!PC_Float_Parse(handle, &cgDC.Assets.shadowX)) {
02730                                 return qfalse;
02731                         }
02732                         continue;
02733                 }
02734 
02735                 if (Q_stricmp(token.string, "shadowY") == 0) {
02736                         if (!PC_Float_Parse(handle, &cgDC.Assets.shadowY)) {
02737                                 return qfalse;
02738                         }
02739                         continue;
02740                 }
02741 
02742                 if (Q_stricmp(token.string, "shadowColor") == 0) {
02743                         if (!PC_Color_Parse(handle, &cgDC.Assets.shadowColor)) {
02744                                 return qfalse;
02745                         }
02746                         cgDC.Assets.shadowFadeClamp = cgDC.Assets.shadowColor[3];
02747                         continue;
02748                 }
02749         }
02750         return qfalse; // bk001204 - why not?
02751 }
02752 
02753 void CG_ParseMenu(const char *menuFile) {
02754         pc_token_t token;
02755         int handle;
02756 
02757         handle = trap_PC_LoadSource(menuFile);
02758         if (!handle)
02759                 handle = trap_PC_LoadSource("ui/testhud.menu");
02760         if (!handle)
02761                 return;
02762 
02763         while ( 1 ) {
02764                 if (!trap_PC_ReadToken( handle, &token )) {
02765                         break;
02766                 }
02767 
02768                 //if ( Q_stricmp( token, "{" ) ) {
02769                 //      Com_Printf( "Missing { in menu file\n" );
02770                 //      break;
02771                 //}
02772 
02773                 //if ( menuCount == MAX_MENUS ) {
02774                 //      Com_Printf( "Too many menus!\n" );
02775                 //      break;
02776                 //}
02777 
02778                 if ( token.string[0] == '}' ) {
02779                         break;
02780                 }
02781 
02782                 if (Q_stricmp(token.string, "assetGlobalDef") == 0) {
02783                         if (CG_Asset_Parse(handle)) {
02784                                 continue;
02785                         } else {
02786                                 break;
02787                         }
02788                 }
02789 
02790 
02791                 if (Q_stricmp(token.string, "menudef") == 0) {
02792                         // start a new menu
02793                         Menu_New(handle);
02794                 }
02795         }
02796         trap_PC_FreeSource(handle);
02797 }
02798 
02799 
02800 qboolean CG_Load_Menu(const char **p) 
02801 {
02802 
02803         char *token;
02804 
02805         token = COM_ParseExt((const char **)p, qtrue);
02806 
02807         if (token[0] != '{') {
02808                 return qfalse;
02809         }
02810 
02811         while ( 1 ) {
02812 
02813                 token = COM_ParseExt((const char **)p, qtrue);
02814     
02815                 if (Q_stricmp(token, "}") == 0) {
02816                         return qtrue;
02817                 }
02818 
02819                 if ( !token || token[0] == 0 ) {
02820                         return qfalse;
02821                 }
02822 
02823                 CG_ParseMenu(token); 
02824         }
02825         return qfalse;
02826 }
02827 
02828 
02829 static qboolean CG_OwnerDrawHandleKey(int ownerDraw, int flags, float *special, int key) {
02830         return qfalse;
02831 }
02832 
02833 
02834 static int CG_FeederCount(float feederID) {
02835         int i, count;
02836         count = 0;
02837         if (feederID == FEEDER_REDTEAM_LIST) {
02838                 for (i = 0; i < cg.numScores; i++) {
02839                         if (cg.scores[i].team == TEAM_RED) {
02840                                 count++;
02841                         }
02842                 }
02843         } else if (feederID == FEEDER_BLUETEAM_LIST) {
02844                 for (i = 0; i < cg.numScores; i++) {
02845                         if (cg.scores[i].team == TEAM_BLUE) {
02846                                 count++;
02847                         }
02848                 }
02849         } else if (feederID == FEEDER_SCOREBOARD) {
02850                 return cg.numScores;
02851         }
02852         return count;
02853 }
02854 
02855 
02856 void CG_SetScoreSelection(void *p) {
02857         menuDef_t *menu = (menuDef_t*)p;
02858         playerState_t *ps = &cg.snap->ps;
02859         int i, red, blue;
02860         red = blue = 0;
02861         for (i = 0; i < cg.numScores; i++) {
02862                 if (cg.scores[i].team == TEAM_RED) {
02863                         red++;
02864                 } else if (cg.scores[i].team == TEAM_BLUE) {
02865                         blue++;
02866                 }
02867                 if (ps->clientNum == cg.scores[i].client) {
02868                         cg.selectedScore = i;
02869                 }
02870         }
02871 
02872         if (menu == NULL) {
02873                 // just interested in setting the selected score
02874                 return;
02875         }
02876 
02877         if ( cgs.gametype >= GT_TEAM ) {
02878                 int feeder = FEEDER_REDTEAM_LIST;
02879                 i = red;
02880                 if (cg.scores[cg.selectedScore].team == TEAM_BLUE) {
02881                         feeder = FEEDER_BLUETEAM_LIST;
02882                         i = blue;
02883                 }
02884                 Menu_SetFeederSelection(menu, feeder, i, NULL);
02885         } else {
02886                 Menu_SetFeederSelection(menu, FEEDER_SCOREBOARD, cg.selectedScore, NULL);
02887         }
02888 }
02889 
02890 // FIXME: might need to cache this info
02891 static clientInfo_t * CG_InfoFromScoreIndex(int index, int team, int *scoreIndex) {
02892         int i, count;
02893         if ( cgs.gametype >= GT_TEAM ) {
02894                 count = 0;
02895                 for (i = 0; i < cg.numScores; i++) {
02896                         if (cg.scores[i].team == team) {
02897                                 if (count == index) {
02898                                         *scoreIndex = i;
02899                                         return &cgs.clientinfo[cg.scores[i].client];
02900                                 }
02901                                 count++;
02902                         }
02903                 }
02904         }
02905         *scoreIndex = index;
02906         return &cgs.clientinfo[ cg.scores[index].client ];
02907 }
02908 
02909 static const char *CG_FeederItemText(float feederID, int index, int column,
02910                                                                          qhandle_t *handle1, qhandle_t *handle2, qhandle_t *handle3) {
02911         gitem_t *item;
02912         int scoreIndex = 0;
02913         clientInfo_t *info = NULL;
02914         int team = -1;
02915         score_t *sp = NULL;
02916 
02917         *handle1 = *handle2 = *handle3 = -1;
02918 
02919         if (feederID == FEEDER_REDTEAM_LIST) {
02920                 team = TEAM_RED;
02921         } else if (feederID == FEEDER_BLUETEAM_LIST) {
02922                 team = TEAM_BLUE;
02923         }
02924 
02925         info = CG_InfoFromScoreIndex(index, team, &scoreIndex);
02926         sp = &cg.scores[scoreIndex];
02927 
02928         if (info && info->infoValid) {
02929                 switch (column) {
02930                         case 0:
02931                                 if ( info->powerups & ( 1 << PW_NEUTRALFLAG ) ) {
02932                                         item = BG_FindItemForPowerup( PW_NEUTRALFLAG );
02933                                         *handle1 = cg_items[ ITEM_INDEX(item) ].icon;
02934                                 } else if ( info->powerups & ( 1 << PW_REDFLAG ) ) {
02935                                         item = BG_FindItemForPowerup( PW_REDFLAG );
02936                                         *handle1 = cg_items[ ITEM_INDEX(item) ].icon;
02937                                 } else if ( info->powerups & ( 1 << PW_BLUEFLAG ) ) {
02938                                         item = BG_FindItemForPowerup( PW_BLUEFLAG );
02939                                         *handle1 = cg_items[ ITEM_INDEX(item) ].icon;
02940                                 } else {
02941                                         /*      
02942                                         if ( info->botSkill > 0 && info->botSkill <= 5 ) {
02943                                                 *handle1 = cgs.media.botSkillShaders[ info->botSkill - 1 ];
02944                                         } else if ( info->handicap < 100 ) {
02945                                         return va("%i", info->handicap );
02946                                         }
02947                                         */
02948                                 }
02949                         break;
02950                         case 1:
02951                                 if (team == -1) {
02952                                         return "";
02953                                 } else {
02954                                         *handle1 = CG_StatusHandle(info->teamTask);
02955                                 }
02956                   break;
02957                         case 2:
02958                                 if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << sp->client ) ) {
02959                                         return "Ready";
02960                                 }
02961                                 if (team == -1) {
02962                                         if (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL) {
02963                                                 return va("%i/%i", info->wins, info->losses);
02964                                         } else if (info->infoValid && info->team == TEAM_SPECTATOR ) {
02965                                                 return "Spectator";
02966                                         } else {
02967                                                 return "";
02968                                         }
02969                                 } else {
02970                                         if (info->teamLeader) {
02971                                                 return "Leader";
02972                                         }
02973                                 }
02974                         break;
02975                         case 3:
02976                                 return info->name;
02977                         break;
02978                         case 4:
02979                                 return va("%i", info->score);
02980                         break;
02981                         case 5:
02982                                 return va("%4i", sp->time);
02983                         break;
02984                         case 6:
02985                                 if ( sp->ping == -1 ) {
02986                                         return "connecting";
02987                                 } 
02988                                 return va("%4i", sp->ping);
02989                         break;
02990                 }
02991         }
02992 
02993         return "";
02994 }
02995 
02996 static qhandle_t CG_FeederItemImage(float feederID, int index) {
02997         return 0;
02998 }
02999 
03000 static qboolean CG_FeederSelection(float feederID, int index, itemDef_t *item) {
03001         if ( cgs.gametype >= GT_TEAM ) {
03002                 int i, count;
03003                 int team = (feederID == FEEDER_REDTEAM_LIST) ? TEAM_RED : TEAM_BLUE;
03004                 count = 0;
03005                 for (i = 0; i < cg.numScores; i++) {
03006                         if (cg.scores[i].team == team) {
03007                                 if (index == count) {
03008                                         cg.selectedScore = i;
03009                                 }
03010                                 count++;
03011                         }
03012                 }
03013         } else {
03014                 cg.selectedScore = index;
03015         }
03016 
03017         return qtrue;
03018 }
03019 
03020 static float CG_Cvar_Get(const char *cvar) {
03021         char buff[128];
03022         memset(buff, 0, sizeof(buff));
03023         trap_Cvar_VariableStringBuffer(cvar, buff, sizeof(buff));
03024         return atof(buff);
03025 }
03026 
03027 void CG_Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style, int iMenuFont) {
03028         CG_Text_Paint(x, y, scale, color, text, 0, limit, style, iMenuFont);
03029 }
03030 
03031 static int CG_OwnerDrawWidth(int ownerDraw, float scale) {
03032         switch (ownerDraw) {
03033           case CG_GAME_TYPE:
03034                         return CG_Text_Width(CG_GameTypeString(), scale, FONT_MEDIUM);
03035           case CG_GAME_STATUS:
03036                         return CG_Text_Width(CG_GetGameStatusText(), scale, FONT_MEDIUM);
03037                         break;
03038           case CG_KILLER:
03039                         return CG_Text_Width(CG_GetKillerText(), scale, FONT_MEDIUM);
03040                         break;
03041           case CG_RED_NAME:
03042                         return CG_Text_Width(DEFAULT_REDTEAM_NAME/*cg_redTeamName.string*/, scale, FONT_MEDIUM);
03043                         break;
03044           case CG_BLUE_NAME:
03045                         return CG_Text_Width(DEFAULT_BLUETEAM_NAME/*cg_blueTeamName.string*/, scale, FONT_MEDIUM);
03046                         break;
03047 
03048 
03049         }
03050         return 0;
03051 }
03052 
03053 static int CG_PlayCinematic(const char *name, float x, float y, float w, float h) {
03054   return trap_CIN_PlayCinematic(name, x, y, w, h, CIN_loop);
03055 }
03056 
03057 static void CG_StopCinematic(int handle) {
03058   trap_CIN_StopCinematic(handle);
03059 }
03060 
03061 static void CG_DrawCinematic(int handle, float x, float y, float w, float h) {
03062   trap_CIN_SetExtents(handle, x, y, w, h);
03063   trap_CIN_DrawCinematic(handle);
03064 }
03065 
03066 static void CG_RunCinematicFrame(int handle) {
03067   trap_CIN_RunCinematic(handle);
03068 }
03069 
03070 /*
03071 =================
03072 CG_LoadMenus();
03073 
03074 =================
03075 */
03076 void CG_LoadMenus(const char *menuFile) 
03077 {
03078         const char      *token;
03079         const char      *p;
03080         int     len;
03081         fileHandle_t    f;
03082         static char buf[MAX_MENUDEFFILE];
03083 
03084         len = trap_FS_FOpenFile( menuFile, &f, FS_READ );
03085 
03086         if ( !f ) 
03087         {
03088                 trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", menuFile ) );
03089 
03090                 len = trap_FS_FOpenFile( "ui/jahud.txt", &f, FS_READ );
03091                 if (!f) 
03092                 {
03093                         trap_Print( va( S_COLOR_RED "default menu file not found: ui/hud.txt, unable to continue!\n", menuFile ) );
03094                 }
03095         }
03096 
03097         if ( len >= MAX_MENUDEFFILE ) 
03098         {
03099                 trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", menuFile, len, MAX_MENUDEFFILE ) );
03100                 trap_FS_FCloseFile( f );
03101                 return;
03102         }
03103 
03104         trap_FS_Read( buf, len, f );
03105         buf[len] = 0;
03106         trap_FS_FCloseFile( f );
03107         
03108         p = buf;
03109 
03110         while ( 1 ) 
03111         {
03112                 token = COM_ParseExt( &p, qtrue );
03113                 if( !token || token[0] == 0 || token[0] == '}') 
03114                 {
03115                         break;
03116                 }
03117 
03118                 if ( Q_stricmp( token, "}" ) == 0 ) 
03119                 {
03120                         break;
03121                 }
03122 
03123                 if (Q_stricmp(token, "loadmenu") == 0) 
03124                 {
03125                         if (CG_Load_Menu(&p)) 
03126                         {
03127                                 continue;
03128                         } 
03129                         else 
03130                         {
03131                                 break;
03132                         }
03133                 }
03134         }
03135 
03136         //Com_Printf("UI menu load time = %d milli seconds\n", cgi_Milliseconds() - start);
03137 }
03138 
03139 /*
03140 =================
03141 CG_LoadHudMenu();
03142 
03143 =================
03144 */
03145 void CG_LoadHudMenu() 
03146 {
03147         const char *hudSet;
03148 
03149         cgDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip;
03150         cgDC.setColor = &trap_R_SetColor;
03151         cgDC.drawHandlePic = &CG_DrawPic;
03152         cgDC.drawStretchPic = &trap_R_DrawStretchPic;
03153         cgDC.drawText = &CG_Text_Paint;
03154         cgDC.textWidth = &CG_Text_Width;
03155         cgDC.textHeight = &CG_Text_Height;
03156         cgDC.registerModel = &trap_R_RegisterModel;
03157         cgDC.modelBounds = &trap_R_ModelBounds;
03158         cgDC.fillRect = &CG_FillRect;
03159         cgDC.drawRect = &CG_DrawRect;   
03160         cgDC.drawSides = &CG_DrawSides;
03161         cgDC.drawTopBottom = &CG_DrawTopBottom;
03162         cgDC.clearScene = &trap_R_ClearScene;
03163         cgDC.addRefEntityToScene = &trap_R_AddRefEntityToScene;
03164         cgDC.renderScene = &trap_R_RenderScene;
03165         cgDC.RegisterFont = &trap_R_RegisterFont;
03166         cgDC.Font_StrLenPixels = &trap_R_Font_StrLenPixels;
03167         cgDC.Font_StrLenChars = &trap_R_Font_StrLenChars;
03168         cgDC.Font_HeightPixels = &trap_R_Font_HeightPixels;
03169         cgDC.Font_DrawString = &trap_R_Font_DrawString;
03170         cgDC.Language_IsAsian = &trap_Language_IsAsian;
03171         cgDC.Language_UsesSpaces = &trap_Language_UsesSpaces;
03172         cgDC.AnyLanguage_ReadCharFromString = &trap_AnyLanguage_ReadCharFromString;
03173         cgDC.ownerDrawItem = &CG_OwnerDraw;
03174         cgDC.getValue = &CG_GetValue;
03175         cgDC.ownerDrawVisible = &CG_OwnerDrawVisible;
03176         cgDC.runScript = &CG_RunMenuScript;
03177         cgDC.deferScript = &CG_DeferMenuScript;
03178         cgDC.getTeamColor = &CG_GetTeamColor;
03179         cgDC.setCVar = trap_Cvar_Set;
03180         cgDC.getCVarString = trap_Cvar_VariableStringBuffer;
03181         cgDC.getCVarValue = CG_Cvar_Get;
03182         cgDC.drawTextWithCursor = &CG_Text_PaintWithCursor;
03183         //cgDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode;
03184         //cgDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode;
03185         cgDC.startLocalSound = &trap_S_StartLocalSound;
03186         cgDC.ownerDrawHandleKey = &CG_OwnerDrawHandleKey;
03187         cgDC.feederCount = &CG_FeederCount;
03188         cgDC.feederItemImage = &CG_FeederItemImage;
03189         cgDC.feederItemText = &CG_FeederItemText;
03190         cgDC.feederSelection = &CG_FeederSelection;
03191         //cgDC.setBinding = &trap_Key_SetBinding;
03192         //cgDC.getBindingBuf = &trap_Key_GetBindingBuf;
03193         //cgDC.keynumToStringBuf = &trap_Key_KeynumToStringBuf;
03194         //cgDC.executeText = &trap_Cmd_ExecuteText;
03195         cgDC.Error = &Com_Error; 
03196         cgDC.Print = &Com_Printf; 
03197         cgDC.ownerDrawWidth = &CG_OwnerDrawWidth;
03198         //cgDC.Pause = &CG_Pause;
03199         cgDC.registerSound = &trap_S_RegisterSound;
03200         cgDC.startBackgroundTrack = &trap_S_StartBackgroundTrack;
03201         cgDC.stopBackgroundTrack = &trap_S_StopBackgroundTrack;
03202         cgDC.playCinematic = &CG_PlayCinematic;
03203         cgDC.stopCinematic = &CG_StopCinematic;
03204         cgDC.drawCinematic = &CG_DrawCinematic;
03205         cgDC.runCinematicFrame = &CG_RunCinematicFrame;
03206         
03207         Init_Display(&cgDC);
03208 
03209         Menu_Reset();
03210 
03211         hudSet = cg_hudFiles.string;
03212         if (hudSet[0] == '\0') 
03213         {
03214                 hudSet = "ui/jahud.txt";
03215         }
03216 
03217         CG_LoadMenus(hudSet);
03218 
03219 }
03220 
03221 void CG_AssetCache() {
03222         //if (Assets.textFont == NULL) {
03223         //  trap_R_RegisterFont("fonts/arial.ttf", 72, &Assets.textFont);
03224         //}
03225         //Assets.background = trap_R_RegisterShaderNoMip( ASSET_BACKGROUND );
03226         //Com_Printf("Menu Size: %i bytes\n", sizeof(Menus));
03227         cgDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR );
03228         cgDC.Assets.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE );
03229         cgDC.Assets.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED );
03230         cgDC.Assets.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW );
03231         cgDC.Assets.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_GREEN );
03232         cgDC.Assets.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_TEAL );
03233         cgDC.Assets.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_BLUE );
03234         cgDC.Assets.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_CYAN );
03235         cgDC.Assets.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE );
03236         cgDC.Assets.scrollBar = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR );
03237         cgDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN );
03238         cgDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP );
03239         cgDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT );
03240         cgDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT );
03241         cgDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip( ASSET_SCROLL_THUMB );
03242         cgDC.Assets.sliderBar = trap_R_RegisterShaderNoMip( ASSET_SLIDER_BAR );
03243         cgDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip( ASSET_SLIDER_THUMB );
03244 }
03245 
03246 /*
03247 
03248 
03249 /*
03250 Ghoul2 Insert Start
03251 */
03252 
03253 // initialise the cg_entities structure - take into account the ghoul2 stl stuff in the active snap shots
03254 void CG_Init_CG(void)
03255 {
03256 #ifdef _XBOX
03257         qboolean widescreen = cg.widescreen;
03258 #endif
03259         memset( &cg, 0, sizeof(cg));
03260 #ifdef _XBOX
03261         cg.widescreen = widescreen;
03262 #endif
03263 }
03264 
03265 #ifdef _XBOX
03266 void CG_SetWidescreen(qboolean widescreen)
03267 {
03268         cg.widescreen = widescreen;
03269 }
03270 #endif
03271 
03272 
03273 // initialise the cg_entities structure - take into account the ghoul2 stl stuff
03274 void CG_Init_CGents(void)
03275 {
03276         
03277         memset(&cg_entities, 0, sizeof(cg_entities));
03278 }
03279 
03280 
03281 void CG_InitItems(void)
03282 {
03283         memset( cg_items, 0, sizeof( cg_items ) );
03284 }
03285 
03286 void CG_TransitionPermanent(void)
03287 {
03288         centity_t       *cent = cg_entities;
03289         int                     i;
03290 
03291         cg_numpermanents = 0;
03292         for(i=0;i<MAX_GENTITIES;i++,cent++)
03293         {
03294                 if (trap_GetDefaultState(i, &cent->currentState))
03295                 {
03296                         cent->nextState = cent->currentState;
03297                         VectorCopy (cent->currentState.origin, cent->lerpOrigin);
03298                         VectorCopy (cent->currentState.angles, cent->lerpAngles);
03299                         cent->currentValid = qtrue;
03300 
03301                         cg_permanents[cg_numpermanents++] = cent;
03302                 }
03303         }
03304 }
03305 
03306 
03307 //this is a 32k custom pool for parsing ents, it can get reset between ent parsing
03308 //so we don't need a whole lot of memory -rww
03309 #define MAX_CGSTRPOOL_SIZE              32768
03310 static int cg_strPoolSize = 0;
03311 static byte cg_strPool[MAX_CGSTRPOOL_SIZE];
03312 
03313 char *CG_StrPool_Alloc(int size)
03314 {
03315         char *giveThemThis;
03316 
03317         if (cg_strPoolSize+size >= MAX_CGSTRPOOL_SIZE)
03318         {
03319                 Com_Error(ERR_DROP, "You exceeded the cgame string pool size. Bad programmer!\n");
03320         }
03321 
03322         giveThemThis = (char *) &cg_strPool[cg_strPoolSize];
03323         cg_strPoolSize += size;
03324 
03325         //memset it for them, just to be nice.
03326         memset(giveThemThis, 0, size);
03327 
03328         return giveThemThis;
03329 }
03330 
03331 void CG_StrPool_Reset(void)
03332 {
03333         cg_strPoolSize = 0;
03334 }
03335 
03336 /*
03337 =============
03338 CG_NewString
03339 
03340 Builds a copy of the string, translating \n to real linefeeds
03341 so message texts can be multi-line
03342 =============
03343 */
03344 char *CG_NewString( const char *string )
03345 {
03346         char    *newb, *new_p;
03347         int             i,l;
03348         
03349         l = strlen(string) + 1;
03350 
03351         newb = CG_StrPool_Alloc( l );
03352 
03353         new_p = newb;
03354 
03355         // turn \n into a real linefeed
03356         for ( i=0 ; i< l ; i++ ) {
03357                 if (string[i] == '\\' && i < l-1) {
03358                         i++;
03359                         if (string[i] == 'n') {
03360                                 *new_p++ = '\n';
03361                         } else {
03362                                 *new_p++ = '\\';
03363                         }
03364                 } else {
03365                         *new_p++ = string[i];
03366                 }
03367         }
03368         
03369         return newb;
03370 }
03371 
03372 //data to grab our spawn info into
03373 typedef struct cgSpawnEnt_s
03374 {
03375         char            *classname;
03376         vec3_t          origin;
03377         vec3_t          angles;
03378         float           angle;
03379         vec3_t          scale;
03380         float           fScale;
03381         vec3_t          mins;
03382         vec3_t          maxs;
03383         char            *model;
03384         float           zoffset;
03385         int                     onlyFogHere;
03386         float           fogstart;
03387         float           radarrange;
03388 } cgSpawnEnt_t;
03389 
03390 #define CGFOFS(x) ((int)&(((cgSpawnEnt_t *)0)->x))
03391 
03392 //spawn fields for our cgame "entity"
03393 BG_field_t cg_spawnFields[] =
03394 {
03395         {"classname", CGFOFS(classname), F_LSTRING},
03396         {"origin", CGFOFS(origin), F_VECTOR},
03397         {"angles", CGFOFS(angles), F_VECTOR},
03398         {"angle", CGFOFS(angle), F_FLOAT},
03399         {"modelscale", CGFOFS(fScale), F_FLOAT},
03400         {"modelscale_vec", CGFOFS(scale), F_VECTOR},
03401         {"model", CGFOFS(model), F_LSTRING},
03402         {"mins", CGFOFS(mins), F_VECTOR},
03403         {"maxs", CGFOFS(maxs), F_VECTOR},
03404         {"zoffset", CGFOFS(zoffset), F_FLOAT},
03405         {"onlyfoghere", CGFOFS(onlyFogHere), F_INT},
03406         {"fogstart", CGFOFS(fogstart), F_FLOAT},
03407         {"radarrange", CGFOFS(radarrange), F_FLOAT},
03408         {NULL}
03409 };
03410 
03411 static int cg_numSpawnVars;
03412 static int cg_numSpawnVarChars;
03413 static char *cg_spawnVars[MAX_SPAWN_VARS][2];
03414 static char cg_spawnVarChars[MAX_SPAWN_VARS_CHARS];
03415 
03416 //get some info from the skyportal ent on the map
03417 qboolean cg_noFogOutsidePortal = qfalse;
03418 void CG_CreateSkyPortalFromSpawnEnt(cgSpawnEnt_t *ent)
03419 {
03420         if (ent->onlyFogHere)
03421         { //only globally fog INSIDE the sky portal
03422                 cg_noFogOutsidePortal = qtrue;
03423         }
03424 }
03425 
03426 //create a skybox portal orientation entity. there -should- only
03427 //be one of these things per level. if there's more than one the
03428 //next will just stomp over the last. -rww
03429 qboolean cg_skyOri = qfalse;
03430 vec3_t cg_skyOriPos;
03431 float cg_skyOriScale = 0.0f;
03432 void CG_CreateSkyOriFromSpawnEnt(cgSpawnEnt_t *ent)
03433 {
03434     cg_skyOri = qtrue;
03435         VectorCopy(ent->origin, cg_skyOriPos);
03436         cg_skyOriScale = ent->fScale;
03437 }
03438 
03439 //get brush box extents, note this does not care about bsp instances.
03440 void CG_CreateBrushEntData(cgSpawnEnt_t *ent)
03441 {
03442         trap_R_ModelBounds(trap_R_RegisterModel(ent->model), ent->mins, ent->maxs);
03443 }
03444 
03445 void CG_CreateWeatherZoneFromSpawnEnt(cgSpawnEnt_t *ent)
03446 {
03447         CG_CreateBrushEntData(ent);
03448         trap_WE_AddWeatherZone(ent->mins, ent->maxs);
03449 }
03450 
03451 //create a new cgame-only model
03452 void CG_CreateModelFromSpawnEnt(cgSpawnEnt_t *ent)
03453 {
03454         int                     modelIndex;
03455         refEntity_t     *RefEnt;
03456         vec3_t          mins, maxs;
03457         float           *radius;
03458         float           *zOff;
03459 
03460         if (NumMiscEnts >= MAX_MISC_ENTS)
03461         {
03462                 Com_Error(ERR_DROP, "Too many misc_model_static's on level, ask a programmer to raise the limit (currently %i), or take some out.", MAX_MISC_ENTS);
03463                 return;
03464         }
03465         
03466         if (!ent || !ent->model || !ent->model[0])
03467         {
03468                 Com_Error(ERR_DROP, "misc_model_static with no model.");
03469                 return;
03470         }
03471 
03472         radius = &Radius[NumMiscEnts];
03473         zOff = &zOffset[NumMiscEnts];
03474         RefEnt = &MiscEnts[NumMiscEnts++];
03475 
03476         modelIndex = trap_R_RegisterModel(ent->model);
03477         if (modelIndex == 0)
03478         {
03479                 Com_Error(ERR_DROP, "misc_model_static failed to load model '%s'",ent->model);
03480                 return;
03481         }
03482 
03483         memset(RefEnt, 0, sizeof(refEntity_t));
03484         RefEnt->reType = RT_MODEL;
03485         RefEnt->hModel = modelIndex;
03486         RefEnt->frame = 0;
03487         trap_R_ModelBounds(modelIndex, mins, maxs);
03488         VectorCopy(ent->scale, RefEnt->modelScale);
03489         if (ent->fScale)
03490         { //use same scale on each axis then
03491                 RefEnt->modelScale[0] = RefEnt->modelScale[1] = RefEnt->modelScale[2] = ent->fScale;
03492         }
03493         VectorCopy(ent->origin, RefEnt->origin);
03494         VectorCopy(ent->origin, RefEnt->lightingOrigin);
03495 
03496         VectorScaleVector(mins, ent->scale, mins);
03497         VectorScaleVector(maxs, ent->scale, maxs);
03498         *radius = Distance(mins, maxs);
03499         *zOff = ent->zoffset;
03500 
03501         if (ent->angle)
03502         { //only yaw supplied...
03503                 ent->angles[YAW] = ent->angle;
03504         }
03505 
03506         AnglesToAxis( ent->angles, RefEnt->axis );
03507         ScaleModelAxis(RefEnt);
03508 }
03509 
03510 /*
03511 ====================
03512 CG_AddSpawnVarToken
03513 ====================
03514 */
03515 char *CG_AddSpawnVarToken( const char *string )
03516 {
03517         int             l;
03518         char    *dest;
03519 
03520         l = strlen( string );
03521         if ( cg_numSpawnVarChars + l + 1 > MAX_SPAWN_VARS_CHARS ) {
03522                 CG_Error( "CG_AddSpawnVarToken: MAX_SPAWN_VARS" );
03523         }
03524 
03525         dest = cg_spawnVarChars + cg_numSpawnVarChars;
03526         memcpy( dest, string, l+1 );
03527 
03528         cg_numSpawnVarChars += l + 1;
03529 
03530         return dest;
03531 }
03532 
03533 /*
03534 ====================
03535 CG_ParseSpawnVars
03536 
03537 cgame version of G_ParseSpawnVars, for ents that don't really
03538 need to take up an entity slot (e.g. static models) -rww
03539 ====================
03540 */
03541 qboolean CG_ParseSpawnVars( void )
03542 {
03543         char            keyname[MAX_TOKEN_CHARS];
03544         char            com_token[MAX_TOKEN_CHARS];
03545 
03546         cg_numSpawnVars = 0;
03547         cg_numSpawnVarChars = 0;
03548 
03549         // parse the opening brace
03550         if ( !trap_GetEntityToken( com_token, sizeof( com_token ) ) ) {
03551                 // end of spawn string
03552                 return qfalse;
03553         }
03554         if ( com_token[0] != '{' ) {
03555                 CG_Error( "CG_ParseSpawnVars: found %s when expecting {",com_token );
03556         }
03557 
03558         // go through all the key / value pairs
03559         while ( 1 )
03560         {       
03561                 // parse key
03562                 if ( !trap_GetEntityToken( keyname, sizeof( keyname ) ) )
03563                 {
03564                         CG_Error( "CG_ParseSpawnVars: EOF without closing brace" );
03565                 }
03566 
03567                 if ( keyname[0] == '}' )
03568                 {
03569                         break;
03570                 }
03571                 
03572                 // parse value  
03573                 if ( !trap_GetEntityToken( com_token, sizeof( com_token ) ) )
03574                 { //this happens on mike's test level, I don't know why. Fixme?
03575                         //CG_Error( "CG_ParseSpawnVars: EOF without closing brace" );
03576                         break;
03577                 }
03578 
03579                 if ( com_token[0] == '}' )
03580                 {
03581                         CG_Error( "CG_ParseSpawnVars: closing brace without data" );
03582                 }
03583                 if ( cg_numSpawnVars == MAX_SPAWN_VARS )
03584                 {
03585                         CG_Error( "CG_ParseSpawnVars: MAX_SPAWN_VARS" );
03586                 }
03587                 cg_spawnVars[ cg_numSpawnVars ][0] = CG_AddSpawnVarToken( keyname );
03588                 cg_spawnVars[ cg_numSpawnVars ][1] = CG_AddSpawnVarToken( com_token );
03589                 cg_numSpawnVars++;
03590         }
03591 
03592         return qtrue;
03593 }
03594 
03595 /*
03596 ==============
03597 CG_SpawnCGameEntFromVars
03598 
03599 See if we should do something for this ent cgame-side -rww
03600 ==============
03601 */
03602 #include "../namespace_begin.h"
03603 void BG_ParseField( BG_field_t *l_fields, const char *key, const char *value, byte *ent );
03604 #include "../namespace_end.h"
03605 
03606 extern float cg_linearFogOverride; //cg_view.c
03607 extern float cg_radarRange;//cg_draw.c
03608 void CG_SpawnCGameEntFromVars(void)
03609 {
03610         int i;
03611         cgSpawnEnt_t ent;
03612 
03613         memset(&ent, 0, sizeof(cgSpawnEnt_t));
03614 
03615         for (i = 0; i < cg_numSpawnVars; i++)
03616         { //shove all this stuff into our data structure used specifically for getting spawn info
03617                 BG_ParseField( cg_spawnFields, cg_spawnVars[i][0], cg_spawnVars[i][1], (byte *)&ent );
03618         }
03619 
03620         if (ent.classname && ent.classname[0])
03621         { //we'll just stricmp this bastard, since there aren't all that many cgame-only things, and they all have special handling
03622                 if (!Q_stricmp(ent.classname, "worldspawn"))
03623                 { //I'd like some info off this guy
03624             if (ent.fogstart)
03625                         { //linear fog method
03626                                 cg_linearFogOverride = ent.fogstart;
03627                         }
03628                         //get radarRange off of worldspawn
03629             if (ent.radarrange)
03630                         { //linear fog method
03631                                 cg_radarRange = ent.radarrange;
03632                         }
03633                 }
03634                 else if (!Q_stricmp(ent.classname, "misc_model_static"))
03635                 { //we've got us a static model
03636             CG_CreateModelFromSpawnEnt(&ent);                   
03637                 }
03638                 else if (!Q_stricmp(ent.classname, "misc_skyportal_orient"))
03639                 { //a sky portal orientation point
03640             CG_CreateSkyOriFromSpawnEnt(&ent);            
03641                 }
03642                 else if (!Q_stricmp(ent.classname, "misc_skyportal"))
03643                 { //might as well parse this thing cgame side for the extra info I want out of it
03644                         CG_CreateSkyPortalFromSpawnEnt(&ent);            
03645                 }
03646                 else if (!Q_stricmp(ent.classname, "misc_weather_zone"))
03647                 { //might as well parse this thing cgame side for the extra info I want out of it
03648                         CG_CreateWeatherZoneFromSpawnEnt(&ent);
03649                 }
03650         }
03651 
03652         //reset the string pool for the next entity, if there is one
03653     CG_StrPool_Reset();
03654 }
03655 
03656 /*
03657 ==============
03658 CG_SpawnCGameOnlyEnts
03659 
03660 Parses entity string data for cgame-only entities, that we can throw away on
03661 the server and never even bother sending. -rww
03662 ==============
03663 */
03664 void CG_SpawnCGameOnlyEnts(void)
03665 {
03666         //make sure it is reset
03667         trap_GetEntityToken(NULL, -1);
03668 
03669         if (!CG_ParseSpawnVars())
03670         { //first one is gonna be the world spawn
03671                 CG_Error("no entities for cgame parse");
03672         }
03673         else
03674         { //parse the world spawn info we want
03675                 CG_SpawnCGameEntFromVars();
03676         }
03677 
03678         while(CG_ParseSpawnVars())
03679         { //now run through the whole list, and look for things we care about cgame-side
03680                 CG_SpawnCGameEntFromVars();
03681         }               
03682 }
03683 
03684 /*
03685 Ghoul2 Insert End
03686 */
03687 
03688 extern playerState_t *cgSendPS[MAX_GENTITIES]; //is not MAX_CLIENTS because NPCs exceed MAX_CLIENTS
03689 void CG_PmoveClientPointerUpdate();
03690 
03691 #include "../namespace_begin.h"
03692 void WP_SaberLoadParms( void );
03693 void BG_VehicleLoadParms( void );
03694 #include "../namespace_end.h"
03695 
03696 /*
03697 =================
03698 CG_Init
03699 
03700 Called after every level change or subsystem restart
03701 Will perform callbacks to make the loading info screen update.
03702 =================
03703 */
03704 void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
03705 {
03706         static gitem_t *item;
03707         char buf[64];
03708         const char      *s;
03709         int i = 0;
03710 
03711         BG_InitAnimsets(); //clear it out
03712 
03713         trap_CG_RegisterSharedMemory(cg.sharedBuffer);
03714 
03715         //Load external vehicle data
03716         BG_VehicleLoadParms();
03717 
03718         // clear everything
03719 /*
03720 Ghoul2 Insert Start
03721 */
03722 
03723 //      memset( cg_entities, 0, sizeof( cg_entities ) );
03724         CG_Init_CGents();
03725 // this is a No-No now we have stl vector classes in here.
03726 //      memset( &cg, 0, sizeof( cg ) );
03727         CG_Init_CG();
03728         CG_InitItems();
03729 
03730         //create the global jetpack instance
03731         CG_InitJetpackGhoul2();
03732 
03733         CG_PmoveClientPointerUpdate();
03734 
03735 /*
03736 Ghoul2 Insert End
03737 */
03738 
03739         //Load sabers.cfg data
03740         WP_SaberLoadParms();
03741 
03742         // this is kinda dumb as well, but I need to pre-load some fonts in order to have the text available
03743         //      to say I'm loading the assets.... which includes loading the fonts. So I'll set these up as reasonable
03744         //      defaults, then let the menu asset parser (which actually specifies the ingame fonts) load over them
03745         //      if desired during parse.  Dunno how legal it is to store in these cgDC things, but it causes no harm
03746         //      and even if/when they get overwritten they'll be legalised by the menu asset parser :-)
03747 //      CG_LoadFonts();
03748         cgDC.Assets.qhSmallFont  = trap_R_RegisterFont("ocr_a");
03749         cgDC.Assets.qhMediumFont = trap_R_RegisterFont("ergoec");
03750         cgDC.Assets.qhBigFont = cgDC.Assets.qhMediumFont;
03751 
03752         memset( &cgs, 0, sizeof( cgs ) );
03753         memset( cg_weapons, 0, sizeof(cg_weapons) );
03754 
03755         cg.clientNum = clientNum;
03756 
03757         cgs.processedSnapshotNum = serverMessageNum;
03758         cgs.serverCommandSequence = serverCommandSequence;
03759 
03760         cg.loadLCARSStage               = 0;
03761 
03762         cg.itemSelect = -1;
03763         cg.forceSelect = -1;
03764         
03765         // load a few needed things before we do any screen updates
03766         cgs.media.charsetShader         = trap_R_RegisterShaderNoMip( "gfx/2d/charsgrid_med" );
03767         cgs.media.whiteShader           = trap_R_RegisterShader( "white" );
03768 
03769         cgs.media.loadBarLED            = trap_R_RegisterShaderNoMip( "gfx/hud/load_tick" );
03770         cgs.media.loadBarLEDCap         = trap_R_RegisterShaderNoMip( "gfx/hud/load_tick_cap" );
03771         cgs.media.loadBarLEDSurround= trap_R_RegisterShaderNoMip( "gfx/hud/mp_levelload" );
03772 
03773         // Force HUD set up
03774         cg.forceHUDActive = qtrue;
03775         cg.forceHUDTotalFlashTime = 0;
03776         cg.forceHUDNextFlashTime = 0;
03777 
03778         i = WP_NONE+1;
03779         while (i <= LAST_USEABLE_WEAPON)
03780         {
03781                 item = BG_FindItemForWeapon(i);
03782 
03783                 if (item && item->icon && item->icon[0])
03784                 {
03785                         cgs.media.weaponIcons[i] = trap_R_RegisterShaderNoMip(item->icon);
03786                         cgs.media.weaponIcons_NA[i] = trap_R_RegisterShaderNoMip(va("%s_na", item->icon));
03787                 }
03788                 else
03789                 { //make sure it is zero'd (default shader)
03790                         cgs.media.weaponIcons[i] = 0;
03791                         cgs.media.weaponIcons_NA[i] = 0;
03792                 }
03793                 i++;
03794         }
03795         trap_Cvar_VariableStringBuffer("com_buildscript", buf, sizeof(buf));
03796         if (atoi(buf))
03797         {
03798                 trap_R_RegisterShaderNoMip("gfx/hud/w_icon_saberstaff");
03799                 trap_R_RegisterShaderNoMip("gfx/hud/w_icon_duallightsaber");
03800         }
03801         i = 0;
03802 
03803         // HUD artwork for cycling inventory,weapons and force powers 
03804         cgs.media.weaponIconBackground          = trap_R_RegisterShaderNoMip( "gfx/hud/background");
03805         cgs.media.forceIconBackground           = trap_R_RegisterShaderNoMip( "gfx/hud/background_f");
03806         cgs.media.inventoryIconBackground       = trap_R_RegisterShaderNoMip( "gfx/hud/background_i");
03807 
03808         //rww - precache holdable item icons here
03809         while (i < bg_numItems)
03810         {
03811                 if (bg_itemlist[i].giType == IT_HOLDABLE)
03812                 {
03813                         if (bg_itemlist[i].icon)
03814                         {
03815                                 cgs.media.invenIcons[bg_itemlist[i].giTag] = trap_R_RegisterShaderNoMip(bg_itemlist[i].icon);
03816                         }
03817                         else
03818                         {
03819                                 cgs.media.invenIcons[bg_itemlist[i].giTag] = 0;
03820                         }
03821                 }
03822 
03823                 i++;
03824         }
03825 
03826         //rww - precache force power icons here
03827         i = 0;
03828 
03829         while (i < NUM_FORCE_POWERS)
03830         {
03831                 cgs.media.forcePowerIcons[i] = trap_R_RegisterShaderNoMip(HolocronIcons[i]);
03832 
03833                 i++;
03834         }
03835         cgs.media.rageRecShader = trap_R_RegisterShaderNoMip("gfx/mp/f_icon_ragerec");
03836 
03837 
03838         //body decal shaders -rww
03839         cgs.media.bdecal_bodyburn1 = trap_R_RegisterShader("gfx/damage/bodyburnmark1");
03840         cgs.media.bdecal_saberglow = trap_R_RegisterShader("gfx/damage/saberglowmark");
03841         cgs.media.bdecal_burn1 = trap_R_RegisterShader("gfx/damage/bodybigburnmark1");
03842         cgs.media.mSaberDamageGlow = trap_R_RegisterShader("gfx/effects/saberDamageGlow");
03843 
03844         CG_RegisterCvars();
03845 
03846         CG_InitConsoleCommands();
03847 
03848         cg.weaponSelect = WP_BRYAR_PISTOL;
03849 
03850         cgs.redflag = cgs.blueflag = -1; // For compatibily, default to unset for
03851         cgs.flagStatus = -1;
03852         // old servers
03853 
03854         // get the rendering configuration from the client system
03855         trap_GetGlconfig( &cgs.glconfig );
03856         cgs.screenXScale = cgs.glconfig.vidWidth / 640.0;
03857         cgs.screenYScale = cgs.glconfig.vidHeight / 480.0;
03858 
03859         // get the gamestate from the client system
03860         trap_GetGameState( &cgs.gameState );
03861 
03862         CG_TransitionPermanent(); //rwwRMG - added
03863 
03864         // check version
03865         s = CG_ConfigString( CS_GAME_VERSION );
03866         if ( strcmp( s, GAME_VERSION ) ) {
03867                 CG_Error( "Client/Server game mismatch: %s/%s", GAME_VERSION, s );
03868         }
03869 
03870         s = CG_ConfigString( CS_LEVEL_START_TIME );
03871         cgs.levelStartTime = atoi( s );
03872 
03873         CG_ParseServerinfo();
03874 
03875         // load the new map
03876 //      CG_LoadingString( "collision map" );
03877 
03878         trap_CM_LoadMap( cgs.mapname, qfalse );
03879 
03880         String_Init();
03881 
03882         cg.loading = qtrue;             // force players to load instead of defer
03883 
03884         //make sure saber data is loaded before this! (so we can precache the appropriate hilts)
03885         CG_InitSiegeMode();
03886 
03887         CG_RegisterSounds();
03888 
03889 //      CG_LoadingString( "graphics" );
03890 
03891         CG_RegisterGraphics();
03892 
03893 //      CG_LoadingString( "clients" );
03894 
03895         CG_RegisterClients();           // if low on memory, some clients will be deferred
03896 
03897         CG_AssetCache();
03898         CG_LoadHudMenu();      // load new hud stuff
03899 
03900         cg.loading = qfalse;    // future players will be deferred
03901 
03902         CG_InitLocalEntities();
03903 
03904         CG_InitMarkPolys();
03905 
03906         // remove the last loading update
03907         cg.infoScreenText[0] = 0;
03908 
03909         // Make sure we have update values (scores)
03910         CG_SetConfigValues();
03911 
03912         CG_StartMusic(qfalse);
03913 
03914 //      CG_LoadingString( "Clearing light styles" );
03915         CG_ClearLightStyles();
03916 
03917 //      CG_LoadingString( "Creating automap data" );
03918         //init automap
03919 #ifndef _XBOX
03920         trap_R_InitWireframeAutomap();
03921 #endif
03922 
03923         CG_LoadingString( "" );
03924 
03925         CG_ShaderStateChanged();
03926 
03927         trap_S_ClearLoopingSounds();
03928 
03929         trap_R_GetDistanceCull(&cg.distanceCull);
03930 
03931         //now get all the cgame only cents
03932         CG_SpawnCGameOnlyEnts();
03933 }
03934 
03935 //makes sure returned string is in localized format
03936 const char *CG_GetLocationString(const char *loc)
03937 {
03938         static char text[1024]={0};
03939 
03940         if (!loc || loc[0] != '@')
03941         { //just a raw string
03942                 return loc;
03943         }
03944 
03945         trap_SP_GetStringTextString(loc+1, text, sizeof(text));
03946         return text;
03947 }
03948 
03949 //clean up all the ghoul2 allocations, the nice and non-hackly way -rww
03950 void CG_KillCEntityG2(int entNum);
03951 void CG_DestroyAllGhoul2(void)
03952 {
03953         int i = 0;
03954         int j;
03955 
03956 //      Com_Printf("... CGameside GHOUL2 Cleanup\n");
03957         while (i < MAX_GENTITIES)
03958         { //free all dynamically allocated npc client info structs and ghoul2 instances
03959                 CG_KillCEntityG2(i);    
03960                 i++;
03961         }
03962         
03963         //Clean the weapon instances
03964         CG_ShutDownG2Weapons();
03965 
03966         i = 0;
03967         while (i < MAX_ITEMS)
03968         { //and now for items
03969                 j = 0;
03970                 while (j < MAX_ITEM_MODELS)
03971                 {
03972                         if (cg_items[i].g2Models[j] && trap_G2_HaveWeGhoul2Models(cg_items[i].g2Models[j]))
03973                         {
03974                                 trap_G2API_CleanGhoul2Models(&cg_items[i].g2Models[j]);
03975                                 cg_items[i].g2Models[j] = NULL;
03976                         }
03977                         j++;
03978                 }
03979                 i++;
03980         }
03981 
03982         //Clean the global jetpack instance
03983         CG_CleanJetpackGhoul2();
03984 }
03985 
03986 /*
03987 =================
03988 CG_Shutdown
03989 
03990 Called before every level change or subsystem restart
03991 =================
03992 */
03993 void CG_Shutdown( void ) 
03994 {
03995         BG_ClearAnimsets(); //free all dynamic allocations made through the engine
03996 
03997     CG_DestroyAllGhoul2();
03998 
03999 //      Com_Printf("... FX System Cleanup\n");
04000         trap_FX_FreeSystem();
04001         trap_ROFF_Clean();
04002 
04003         if (cgWeatherOverride)
04004         {
04005                 trap_R_WeatherContentsOverride(0); //rwwRMG - reset it engine-side
04006         }
04007 
04008         //reset weather
04009         trap_R_WorldEffectCommand("die");
04010 
04011         UI_CleanupGhoul2();
04012         //If there was any ghoul2 stuff in our side of the shared ui code, then remove it now.
04013 
04014         // some mods may need to do cleanup work here,
04015         // like closing files or archiving session data
04016 }
04017 
04018 /*
04019 ===============
04020 CG_NextForcePower_f
04021 ===============
04022 */
04023 void CG_NextForcePower_f( void ) 
04024 {
04025         int current;
04026         usercmd_t cmd;
04027         if ( !cg.snap )
04028         {
04029                 return;
04030         }
04031 
04032         if (cg.predictedPlayerState.pm_type == PM_SPECTATOR)
04033         {
04034                 return;
04035         }
04036 
04037         current = trap_GetCurrentCmdNumber();
04038         trap_GetUserCmd(current, &cmd);
04039         if ((cmd.buttons & BUTTON_USE) || CG_NoUseableForce())
04040         {
04041                 CG_NextInventory_f();
04042                 return;
04043         }
04044 
04045         if (cg.snap->ps.pm_flags & PMF_FOLLOW)
04046         {
04047                 return;
04048         }
04049 
04050 //      BG_CycleForce(&cg.snap->ps, 1);
04051         if (cg.forceSelect != -1)
04052         {
04053                 cg.snap->ps.fd.forcePowerSelected = cg.forceSelect;
04054         }
04055 
04056         BG_CycleForce(&cg.snap->ps, 1);
04057 
04058         if (cg.snap->ps.fd.forcePowersKnown & (1 << cg.snap->ps.fd.forcePowerSelected))
04059         {
04060                 cg.forceSelect = cg.snap->ps.fd.forcePowerSelected;
04061                 cg.forceSelectTime = cg.time;
04062         }
04063 }
04064 
04065 /*
04066 ===============
04067 CG_PrevForcePower_f
04068 ===============
04069 */
04070 void CG_PrevForcePower_f( void ) 
04071 {
04072         int current;
04073         usercmd_t cmd;
04074         if ( !cg.snap )
04075         {
04076                 return;
04077         }
04078 
04079         if (cg.predictedPlayerState.pm_type == PM_SPECTATOR)
04080         {
04081                 return;
04082         }
04083 
04084         current = trap_GetCurrentCmdNumber();
04085         trap_GetUserCmd(current, &cmd);
04086         if ((cmd.buttons & BUTTON_USE) || CG_NoUseableForce())
04087         {
04088                 CG_PrevInventory_f();
04089                 return;
04090         }
04091 
04092         if (cg.snap->ps.pm_flags & PMF_FOLLOW)
04093         {
04094                 return;
04095         }
04096 
04097 //      BG_CycleForce(&cg.snap->ps, -1);
04098         if (cg.forceSelect != -1)
04099         {
04100                 cg.snap->ps.fd.forcePowerSelected = cg.forceSelect;
04101         }
04102 
04103         BG_CycleForce(&cg.snap->ps, -1);
04104 
04105         if (cg.snap->ps.fd.forcePowersKnown & (1 << cg.snap->ps.fd.forcePowerSelected))
04106         {
04107                 cg.forceSelect = cg.snap->ps.fd.forcePowerSelected;
04108                 cg.forceSelectTime = cg.time;
04109         }
04110 }
04111 
04112 void CG_NextInventory_f(void)
04113 {
04114         if ( !cg.snap )
04115         {
04116                 return;
04117         }
04118 
04119         if (cg.snap->ps.pm_flags & PMF_FOLLOW)
04120         {
04121                 return;
04122         }
04123 
04124         if (cg.predictedPlayerState.pm_type == PM_SPECTATOR)
04125         {
04126                 return;
04127         }
04128 
04129         if (cg.itemSelect != -1)
04130         {
04131                 cg.snap->ps.stats[STAT_HOLDABLE_ITEM] = BG_GetItemIndexByTag(cg.itemSelect, IT_HOLDABLE);
04132         }
04133         BG_CycleInven(&cg.snap->ps, 1);
04134 
04135         if (cg.snap->ps.stats[STAT_HOLDABLE_ITEM])
04136         {
04137                 cg.itemSelect = bg_itemlist[cg.snap->ps.stats[STAT_HOLDABLE_ITEM]].giTag;
04138                 cg.invenSelectTime = cg.time;
04139         }
04140 }
04141 
04142 void CG_PrevInventory_f(void)
04143 {
04144         if ( !cg.snap )
04145         {
04146                 return;
04147         }
04148 
04149         if (cg.snap->ps.pm_flags & PMF_FOLLOW)
04150         {
04151                 return;
04152         }
04153 
04154         if (cg.predictedPlayerState.pm_type == PM_SPECTATOR)
04155         {
04156                 return;
04157         }
04158 
04159         if (cg.itemSelect != -1)
04160         {
04161                 cg.snap->ps.stats[STAT_HOLDABLE_ITEM] = BG_GetItemIndexByTag(cg.itemSelect, IT_HOLDABLE);
04162         }
04163         BG_CycleInven(&cg.snap->ps, -1);
04164 
04165         if (cg.snap->ps.stats[STAT_HOLDABLE_ITEM])
04166         {
04167                 cg.itemSelect = bg_itemlist[cg.snap->ps.stats[STAT_HOLDABLE_ITEM]].giTag;
04168                 cg.invenSelectTime = cg.time;
04169         }
04170 }