2022-09-18 15:37:21 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Copyright ( C ) 1999 - 2005 , Id Software , Inc .
Copyright ( C ) 2000 - 2013 , Raven Software , Inc .
Copyright ( C ) 2001 - 2013 , Activision , Inc .
Copyright ( C ) 2013 - 2015 , OpenJK contributors
This file is part of the OpenJK source code .
OpenJK is free software ; you can redistribute it and / or modify it
under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , see < http : //www.gnu.org/licenses/>.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# include "cg_media.h"
# include "FxScheduler.h"
# include "../client/vmachine.h"
# include "g_local.h"
# include "../qcommon/sstring.h"
# include "qcommon/ojk_saved_game_helper.h"
2022-09-24 19:08:43 +00:00
# include <JKVR/VrClientInfo.h>
2022-09-18 15:37:21 +00:00
//NOTENOTE: Be sure to change the mirrored code in g_shared.h
typedef std : : map < sstring_t , unsigned char > namePrecache_m ;
extern namePrecache_m * as_preCacheMap ;
extern void CG_RegisterNPCCustomSounds ( clientInfo_t * ci ) ;
extern qboolean G_AddSexToMunroString ( char * string , qboolean qDoBoth ) ;
extern int G_ParseAnimFileSet ( const char * skeletonName , const char * modelName = 0 ) ;
extern void CG_DrawDataPadInventorySelect ( void ) ;
void CG_Init ( int serverCommandSequence ) ;
qboolean CG_ConsoleCommand ( void ) ;
void CG_Shutdown ( void ) ;
int CG_GetCameraPos ( vec3_t camerapos ) ;
int CG_GetCameraAng ( vec3_t cameraang ) ;
void UseItem ( int itemNum ) ;
const char * CG_DisplayBoxedText ( int iBoxX , int iBoxY , int iBoxWidth , int iBoxHeight ,
const char * psText , int iFontHandle , float fScale ,
const vec4_t v4Color ) ;
# define NUM_CHUNKS 6
/*
Ghoul2 Insert Start
*/
void CG_ResizeG2Bolt ( boltInfo_v * bolt , int newCount ) ;
void CG_ResizeG2Surface ( surfaceInfo_v * surface , int newCount ) ;
void CG_ResizeG2Bone ( boneInfo_v * bone , int newCount ) ;
void CG_ResizeG2 ( CGhoul2Info_v * ghoul2 , int newCount ) ;
void CG_ResizeG2TempBone ( mdxaBone_v * tempBone , int newCount ) ;
/*
Ghoul2 Insert End
*/
void CG_LoadHudMenu ( void ) ;
int inv_icons [ INV_MAX ] ;
const char * inv_names [ ] =
{
" ELECTROBINOCULARS " ,
" BACTA CANISTER " ,
" SEEKER " ,
" LIGHT AMP GOGGLES " ,
" ASSAULT SENTRY " ,
" GOODIE KEY " ,
" GOODIE KEY " ,
" GOODIE KEY " ,
" GOODIE KEY " ,
" GOODIE KEY " ,
" SECURITY KEY " ,
" SECURITY KEY " ,
" SECURITY KEY " ,
" SECURITY KEY " ,
" SECURITY KEY " ,
} ;
int force_icons [ NUM_FORCE_POWERS ] ;
2022-09-24 19:08:43 +00:00
extern vr_client_info_t * vr ;
2022-09-18 15:37:21 +00:00
void CG_DrawDataPadHUD ( centity_t * cent ) ;
void CG_DrawDataPadObjectives ( const centity_t * cent ) ;
void CG_DrawDataPadIconBackground ( const int backgroundType ) ;
void CG_DrawDataPadWeaponSelect ( void ) ;
void CG_DrawDataPadForceSelect ( void ) ;
/*
= = = = = = = = = = = = = = = =
vmMain
This is the only way control passes into the cgame module .
This must be the very first function compiled into the . q3vm file
= = = = = = = = = = = = = = = =
*/
extern " C " Q_EXPORT intptr_t QDECL vmMain ( intptr_t command , intptr_t arg0 , intptr_t arg1 , intptr_t arg2 , intptr_t arg3 , intptr_t arg4 , intptr_t arg5 , intptr_t arg6 , intptr_t arg7 ) {
centity_t * cent ;
switch ( command ) {
2022-09-24 19:08:43 +00:00
case CG_INIT : {
vr = ( vr_client_info_t * ) ( arg1 ) ;
CG_Init ( arg0 ) ;
}
2022-09-18 15:37:21 +00:00
return 0 ;
case CG_SHUTDOWN :
CG_Shutdown ( ) ;
return 0 ;
case CG_CONSOLE_COMMAND :
return CG_ConsoleCommand ( ) ;
case CG_DRAW_ACTIVE_FRAME :
CG_DrawActiveFrame ( arg0 , ( stereoFrame_t ) arg1 ) ;
return 0 ;
case CG_CROSSHAIR_PLAYER :
return CG_CrosshairPlayer ( ) ;
case CG_CAMERA_POS :
return CG_GetCameraPos ( ( float * ) arg0 ) ;
case CG_CAMERA_ANG :
return CG_GetCameraAng ( ( float * ) arg0 ) ;
/*
Ghoul2 Insert Start
*/
case CG_RESIZE_G2 :
CG_ResizeG2 ( ( CGhoul2Info_v * ) arg0 , arg1 ) ;
return 0 ;
case CG_RESIZE_G2_BOLT :
CG_ResizeG2Bolt ( ( boltInfo_v * ) arg0 , arg1 ) ;
return 0 ;
case CG_RESIZE_G2_BONE :
CG_ResizeG2Bone ( ( boneInfo_v * ) arg0 , arg1 ) ;
return 0 ;
case CG_RESIZE_G2_SURFACE :
CG_ResizeG2Surface ( ( surfaceInfo_v * ) arg0 , arg1 ) ;
return 0 ;
case CG_RESIZE_G2_TEMPBONE :
CG_ResizeG2TempBone ( ( mdxaBone_v * ) arg0 , arg1 ) ;
return 0 ;
/*
Ghoul2 Insert End
*/
case CG_DRAW_DATAPAD_HUD :
if ( cg . snap )
{
cent = & cg_entities [ cg . snap - > ps . clientNum ] ;
CG_DrawDataPadHUD ( cent ) ;
}
return 0 ;
case CG_DRAW_DATAPAD_OBJECTIVES :
if ( cg . snap )
{
cent = & cg_entities [ cg . snap - > ps . clientNum ] ;
CG_DrawDataPadObjectives ( cent ) ;
}
return 0 ;
case CG_DRAW_DATAPAD_WEAPONS :
if ( cg . snap )
{
CG_DrawDataPadIconBackground ( ICON_WEAPONS ) ;
CG_DrawDataPadWeaponSelect ( ) ;
}
return 0 ;
case CG_DRAW_DATAPAD_INVENTORY :
if ( cg . snap )
{
CG_DrawDataPadIconBackground ( ICON_INVENTORY ) ;
CG_DrawDataPadInventorySelect ( ) ;
}
return 0 ;
case CG_DRAW_DATAPAD_FORCEPOWERS :
if ( cg . snap )
{
CG_DrawDataPadIconBackground ( ICON_FORCE ) ;
CG_DrawDataPadForceSelect ( ) ;
}
return 0 ;
}
return - 1 ;
}
/*
Ghoul2 Insert Start
*/
void CG_ResizeG2Bolt ( boltInfo_v * bolt , int newCount )
{
bolt - > resize ( newCount ) ;
}
void CG_ResizeG2Surface ( surfaceInfo_v * surface , int newCount )
{
surface - > resize ( newCount ) ;
}
void CG_ResizeG2Bone ( boneInfo_v * bone , int newCount )
{
bone - > resize ( newCount ) ;
}
void CG_ResizeG2 ( CGhoul2Info_v * ghoul2 , int newCount )
{
ghoul2 - > resize ( newCount ) ;
}
void CG_ResizeG2TempBone ( mdxaBone_v * tempBone , int newCount )
{
tempBone - > resize ( newCount ) ;
}
/*
Ghoul2 Insert End
*/
cg_t cg ;
cgs_t cgs ;
centity_t cg_entities [ MAX_GENTITIES ] ;
centity_t * cg_permanents [ MAX_GENTITIES ] ;
int cg_numpermanents = 0 ;
weaponInfo_t cg_weapons [ MAX_WEAPONS ] ;
itemInfo_t cg_items [ MAX_ITEMS ] ;
2022-09-24 19:08:43 +00:00
vr_client_info_t * vr ;
2022-09-18 15:37:21 +00:00
typedef struct {
qboolean registered ; // Has the player picked it up
qboolean active ; // Is it the chosen inventory item
int count ; // Count of items.
char description [ 128 ] ;
} inventoryInfo_t ;
inventoryInfo_t cg_inventory [ INV_MAX ] ;
vmCvar_t cg_runpitch ;
vmCvar_t cg_runroll ;
vmCvar_t cg_bobup ;
vmCvar_t cg_bobpitch ;
vmCvar_t cg_bobroll ;
vmCvar_t cg_shadows ;
vmCvar_t cg_renderToTextureFX ;
vmCvar_t cg_shadowCullDistance ;
vmCvar_t cg_footsteps ;
vmCvar_t cg_saberEntMarks ;
vmCvar_t cg_paused ;
vmCvar_t cg_drawTimer ;
vmCvar_t cg_drawFPS ;
vmCvar_t cg_drawSnapshot ;
vmCvar_t cg_drawAmmoWarning ;
vmCvar_t cg_drawCrosshair ;
vmCvar_t cg_crosshairIdentifyTarget ;
vmCvar_t cg_dynamicCrosshair ;
vmCvar_t cg_crosshairForceHint ;
vmCvar_t cg_crosshairX ;
vmCvar_t cg_crosshairY ;
vmCvar_t cg_crosshairSize ;
vmCvar_t cg_draw2D ;
vmCvar_t cg_drawStatus ;
vmCvar_t cg_drawHUD ;
vmCvar_t cg_debugAnim ;
# ifndef FINAL_BUILD
vmCvar_t cg_debugAnimTarget ;
vmCvar_t cg_gun_frame ;
# endif
vmCvar_t cg_gun_x ;
vmCvar_t cg_gun_y ;
vmCvar_t cg_gun_z ;
vmCvar_t cg_debugSaber ;
vmCvar_t cg_debugEvents ;
vmCvar_t cg_errorDecay ;
vmCvar_t cg_addMarks ;
vmCvar_t cg_drawGun ;
vmCvar_t cg_autoswitch ;
vmCvar_t cg_simpleItems ;
vmCvar_t cg_fov ;
vmCvar_t cg_fovAspectAdjust ;
vmCvar_t cg_endcredits ;
vmCvar_t cg_updatedDataPadForcePower1 ;
vmCvar_t cg_updatedDataPadForcePower2 ;
vmCvar_t cg_updatedDataPadForcePower3 ;
vmCvar_t cg_updatedDataPadObjective ;
vmCvar_t cg_drawBreath ;
vmCvar_t cg_roffdebug ;
# ifndef FINAL_BUILD
vmCvar_t cg_roffval1 ;
vmCvar_t cg_roffval2 ;
vmCvar_t cg_roffval3 ;
vmCvar_t cg_roffval4 ;
# endif
vmCvar_t cg_thirdPerson ;
vmCvar_t cg_thirdPersonRange ;
vmCvar_t cg_thirdPersonMaxRange ;
vmCvar_t cg_thirdPersonAngle ;
vmCvar_t cg_thirdPersonPitchOffset ;
vmCvar_t cg_thirdPersonVertOffset ;
vmCvar_t cg_thirdPersonCameraDamp ;
vmCvar_t cg_thirdPersonTargetDamp ;
vmCvar_t cg_gunAutoFirst ;
vmCvar_t cg_thirdPersonAlpha ;
vmCvar_t cg_thirdPersonAutoAlpha ;
vmCvar_t cg_thirdPersonHorzOffset ;
vmCvar_t cg_stereoSeparation ;
2022-09-24 19:08:43 +00:00
vmCvar_t cg_worldScale ;
vmCvar_t cg_heightAdjust ;
2022-09-18 15:37:21 +00:00
vmCvar_t cg_developer ;
vmCvar_t cg_timescale ;
vmCvar_t cg_skippingcin ;
vmCvar_t cg_pano ;
vmCvar_t cg_panoNumShots ;
vmCvar_t fx_freeze ;
vmCvar_t fx_debug ;
vmCvar_t cg_missionInfoFlashTime ;
vmCvar_t cg_hudFiles ;
vmCvar_t cg_neverHearThatDumbBeepingSoundAgain ;
vmCvar_t cg_VariantSoundCap ; // 0 = no capping, else cap to (n) max (typically just 1, but allows more)
vmCvar_t cg_turnAnims ;
vmCvar_t cg_motionBoneComp ;
vmCvar_t cg_distributeMBCorrection ;
vmCvar_t cg_reliableAnimEvents ;
vmCvar_t cg_smoothPlayerPos ;
vmCvar_t cg_smoothPlayerPlat ;
vmCvar_t cg_smoothPlayerPlatAccel ;
vmCvar_t cg_g2Marks ;
vmCvar_t fx_expensivePhysics ;
vmCvar_t cg_debugHealthBars ;
vmCvar_t cg_smoothCamera ;
vmCvar_t cg_speedTrail ;
vmCvar_t cg_fovViewmodel ;
vmCvar_t cg_fovViewmodelAdjust ;
vmCvar_t cg_scaleVehicleSensitivity ;
typedef struct {
vmCvar_t * vmCvar ;
const char * cvarName ;
const char * defaultString ;
int cvarFlags ;
} cvarTable_t ;
static cvarTable_t cvarTable [ ] = {
{ & cg_autoswitch , " cg_autoswitch " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_drawGun , " cg_drawGun " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_fov , " cg_fov " , " 80 " , CVAR_ARCHIVE } ,
{ & cg_fovAspectAdjust , " cg_fovAspectAdjust " , " 0 " , CVAR_ARCHIVE } ,
2022-09-24 19:08:43 +00:00
{ & cg_stereoSeparation , " cg_stereoSeparation " , " 0.065 " , CVAR_ARCHIVE } ,
{ & cg_worldScale , " cg_worldScale " , " 37.5 " , CVAR_ARCHIVE } ,
{ & cg_heightAdjust , " cg_heightAdjust " , " 0.0 " , CVAR_ARCHIVE } ,
2022-09-18 15:37:21 +00:00
{ & cg_shadows , " cg_shadows " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_renderToTextureFX , " cg_renderToTextureFX " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_shadowCullDistance , " r_shadowRange " , " 1000 " , CVAR_ARCHIVE } ,
{ & cg_footsteps , " cg_footsteps " , " 3 " , CVAR_ARCHIVE } , //1 = sounds, 2 = sounds & effects, 3 = sounds, effects & marks, 4 = always
{ & cg_saberEntMarks , " cg_saberEntMarks " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_draw2D , " cg_draw2D " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_drawStatus , " cg_drawStatus " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_drawHUD , " cg_drawHUD " , " 1 " , 0 } ,
{ & cg_drawTimer , " cg_drawTimer " , " 0 " , CVAR_ARCHIVE } ,
{ & cg_drawFPS , " cg_drawFPS " , " 0 " , CVAR_ARCHIVE } ,
{ & cg_drawSnapshot , " cg_drawSnapshot " , " 0 " , CVAR_ARCHIVE } ,
{ & cg_drawAmmoWarning , " cg_drawAmmoWarning " , " 1 " , CVAR_ARCHIVE } ,
2022-09-24 19:08:43 +00:00
{ & cg_drawCrosshair , " cg_drawCrosshair " , " 0 " , CVAR_ARCHIVE } ,
2022-09-18 15:37:21 +00:00
{ & cg_dynamicCrosshair , " cg_dynamicCrosshair " , " 1 " , CVAR_ARCHIVE } ,
// NOTE : I also create this in UI_Init()
{ & cg_crosshairIdentifyTarget , " cg_crosshairIdentifyTarget " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_crosshairForceHint , " cg_crosshairForceHint " , " 1 " , CVAR_ARCHIVE | CVAR_SAVEGAME | CVAR_NORESTART } ,
{ & cg_endcredits , " cg_endcredits " , " 0 " , 0 } ,
{ & cg_updatedDataPadForcePower1 , " cg_updatedDataPadForcePower1 " , " 0 " , 0 } ,
{ & cg_updatedDataPadForcePower2 , " cg_updatedDataPadForcePower2 " , " 0 " , 0 } ,
{ & cg_updatedDataPadForcePower3 , " cg_updatedDataPadForcePower3 " , " 0 " , 0 } ,
{ & cg_updatedDataPadObjective , " cg_updatedDataPadObjective " , " 0 " , 0 } ,
{ & cg_crosshairSize , " cg_crosshairSize " , " 24 " , CVAR_ARCHIVE } ,
{ & cg_crosshairX , " cg_crosshairX " , " 0 " , CVAR_ARCHIVE } ,
{ & cg_crosshairY , " cg_crosshairY " , " 0 " , CVAR_ARCHIVE } ,
{ & cg_simpleItems , " cg_simpleItems " , " 0 " , CVAR_ARCHIVE } ,
// NOTE : I also create this in UI_Init()
{ & cg_addMarks , " cg_marks " , " 1 " , CVAR_ARCHIVE } ,
// NOTE : I also create these weapon sway cvars in UI_Init()
{ & cg_runpitch , " cg_runpitch " , " 0.002 " , CVAR_ARCHIVE } ,
{ & cg_runroll , " cg_runroll " , " 0.005 " , CVAR_ARCHIVE } ,
{ & cg_bobup , " cg_bobup " , " 0.005 " , CVAR_ARCHIVE } ,
{ & cg_bobpitch , " cg_bobpitch " , " 0.002 " , CVAR_ARCHIVE } ,
{ & cg_bobroll , " cg_bobroll " , " 0.002 " , CVAR_ARCHIVE } ,
{ & cg_debugAnim , " cg_debuganim " , " 0 " , CVAR_CHEAT } ,
# ifndef FINAL_BUILD
{ & cg_gun_frame , " gun_frame " , " 0 " , CVAR_CHEAT } ,
{ & cg_debugAnimTarget , " cg_debugAnimTarget " , " 0 " , CVAR_CHEAT } ,
# endif
{ & cg_gun_x , " cg_gunX " , " 0 " , CVAR_ARCHIVE } ,
{ & cg_gun_y , " cg_gunY " , " 0 " , CVAR_ARCHIVE } ,
{ & cg_gun_z , " cg_gunZ " , " 0 " , CVAR_ARCHIVE } ,
{ & cg_debugSaber , " cg_debugsaber " , " 0 " , CVAR_CHEAT } ,
{ & cg_debugEvents , " cg_debugevents " , " 0 " , CVAR_CHEAT } ,
{ & cg_errorDecay , " cg_errordecay " , " 100 " , 0 } ,
{ & cg_drawBreath , " cg_drawBreath " , " 0 " , CVAR_ARCHIVE } , // Added 11/07/02
{ & cg_roffdebug , " cg_roffdebug " , " 0 " } ,
# ifndef FINAL_BUILD
{ & cg_roffval1 , " cg_roffval1 " , " 0 " } ,
{ & cg_roffval2 , " cg_roffval2 " , " 0 " } ,
{ & cg_roffval3 , " cg_roffval3 " , " 0 " } ,
{ & cg_roffval4 , " cg_roffval4 " , " 0 " } ,
# endif
{ & cg_thirdPerson , " cg_thirdPerson " , " 1 " , CVAR_SAVEGAME } ,
{ & cg_thirdPersonRange , " cg_thirdPersonRange " , " 80 " , CVAR_ARCHIVE } ,
{ & cg_thirdPersonMaxRange , " cg_thirdPersonMaxRange " , " 150 " , 0 } ,
{ & cg_thirdPersonAngle , " cg_thirdPersonAngle " , " 0 " , 0 } ,
{ & cg_thirdPersonPitchOffset , " cg_thirdPersonPitchOffset " , " 0 " , 0 } ,
{ & cg_thirdPersonVertOffset , " cg_thirdPersonVertOffset " , " 16 " , 0 } ,
{ & cg_thirdPersonCameraDamp , " cg_thirdPersonCameraDamp " , " 0.3 " , 0 } ,
{ & cg_thirdPersonTargetDamp , " cg_thirdPersonTargetDamp " , " 0.5 " , 0 } ,
{ & cg_thirdPersonHorzOffset , " cg_thirdPersonHorzOffset " , " 0 " , 0 } ,
{ & cg_thirdPersonAlpha , " cg_thirdPersonAlpha " , " 1.0 " , CVAR_ARCHIVE } ,
{ & cg_thirdPersonAutoAlpha , " cg_thirdPersonAutoAlpha " , " 0 " , 0 } ,
// NOTE: also declare this in UI_Init
{ & cg_gunAutoFirst , " cg_gunAutoFirst " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_pano , " pano " , " 0 " , 0 } ,
{ & cg_panoNumShots , " panoNumShots " , " 10 " , 0 } ,
{ & fx_freeze , " fx_freeze " , " 0 " , 0 } ,
{ & fx_debug , " fx_debug " , " 0 " , 0 } ,
// the following variables are created in other parts of the system,
// but we also reference them here
{ & cg_paused , " cl_paused " , " 0 " , CVAR_ROM } ,
{ & cg_developer , " developer " , " " , 0 } ,
{ & cg_timescale , " timescale " , " 1 " , 0 } ,
{ & cg_skippingcin , " skippingCinematic " , " 0 " , CVAR_ROM } ,
{ & cg_missionInfoFlashTime , " cg_missionInfoFlashTime " , " 10000 " , 0 } ,
{ & cg_hudFiles , " cg_hudFiles " , " ui/jahud.txt " , CVAR_ARCHIVE } ,
{ & cg_VariantSoundCap , " cg_VariantSoundCap " , " 0 " , 0 } ,
{ & cg_turnAnims , " cg_turnAnims " , " 0 " , 0 } ,
{ & cg_motionBoneComp , " cg_motionBoneComp " , " 2 " , 0 } ,
{ & cg_distributeMBCorrection , " cg_distributeMBCorrection " , " 1 " , 0 } ,
{ & cg_reliableAnimEvents , " cg_reliableAnimEvents " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_smoothPlayerPos , " cg_smoothPlayerPos " , " 0.5 " , 0 } ,
{ & cg_smoothPlayerPlat , " cg_smoothPlayerPlat " , " 0.75 " , 0 } ,
{ & cg_smoothPlayerPlatAccel , " cg_smoothPlayerPlatAccel " , " 3.25 " , 0 } ,
{ & cg_g2Marks , " cg_g2Marks " , " 1 " , CVAR_ARCHIVE } ,
{ & fx_expensivePhysics , " fx_expensivePhysics " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_debugHealthBars , " cg_debugHealthBars " , " 0 " , CVAR_CHEAT } ,
{ & cg_smoothCamera , " cg_smoothCamera " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_speedTrail , " cg_speedTrail " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_fovViewmodel , " cg_fovViewmodel " , " 0 " , CVAR_ARCHIVE } ,
{ & cg_fovViewmodelAdjust , " cg_fovViewmodelAdjust " , " 1 " , CVAR_ARCHIVE } ,
{ & cg_scaleVehicleSensitivity , " cg_scaleVehicleSensitivity " , " 1 " , CVAR_ARCHIVE } ,
} ;
static const size_t cvarTableSize = ARRAY_LEN ( cvarTable ) ;
/*
= = = = = = = = = = = = = = = = =
CG_RegisterCvars
= = = = = = = = = = = = = = = = =
*/
void CG_RegisterCvars ( void ) {
size_t i ;
cvarTable_t * cv ;
for ( i = 0 , cv = cvarTable ; i < cvarTableSize ; i + + , cv + + ) {
cgi_Cvar_Register ( cv - > vmCvar , cv - > cvarName , cv - > defaultString , cv - > cvarFlags ) ;
}
}
/*
= = = = = = = = = = = = = = = = =
CG_UpdateCvars
= = = = = = = = = = = = = = = = =
*/
void CG_UpdateCvars ( void ) {
size_t i ;
cvarTable_t * cv ;
for ( i = 0 , cv = cvarTable ; i < cvarTableSize ; i + + , cv + + ) {
if ( cv - > vmCvar ) {
cgi_Cvar_Update ( cv - > vmCvar ) ;
}
}
}
int CG_CrosshairPlayer ( void )
{
if ( cg . time > ( cg . crosshairClientTime + 1000 ) )
{
return - 1 ;
}
return cg . crosshairClientNum ;
}
int CG_GetCameraPos ( vec3_t camerapos ) {
if ( in_camera ) {
VectorCopy ( client_camera . origin , camerapos ) ;
return 1 ;
}
else if ( cg_entities [ 0 ] . gent & & cg_entities [ 0 ] . gent - > client & & cg_entities [ 0 ] . gent - > client - > ps . viewEntity > 0 & & cg_entities [ 0 ] . gent - > client - > ps . viewEntity < ENTITYNUM_WORLD )
//else if ( cg.snap && cg.snap->ps.viewEntity > 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD )
{ //in an entity camera view
if ( g_entities [ cg_entities [ 0 ] . gent - > client - > ps . viewEntity ] . client & & cg . renderingThirdPerson )
{
VectorCopy ( g_entities [ cg_entities [ 0 ] . gent - > client - > ps . viewEntity ] . client - > renderInfo . eyePoint , camerapos ) ;
}
else
{
VectorCopy ( g_entities [ cg_entities [ 0 ] . gent - > client - > ps . viewEntity ] . currentOrigin , camerapos ) ;
}
//VectorCopy( cg_entities[cg_entities[0].gent->client->ps.viewEntity].lerpOrigin, camerapos );
/*
if ( g_entities [ cg . snap - > ps . viewEntity ] . client & & cg . renderingThirdPerson )
{
VectorCopy ( g_entities [ cg . snap - > ps . viewEntity ] . client - > renderInfo . eyePoint , camerapos ) ;
}
else
{ //use the g_ent because it may not have gotten over to the client yet...
VectorCopy ( g_entities [ cg . snap - > ps . viewEntity ] . currentOrigin , camerapos ) ;
}
*/
return 1 ;
}
else if ( cg . renderingThirdPerson )
{ //in third person
//FIXME: what about hacks that render in third person regardless of this value?
VectorCopy ( cg . refdef . vieworg , camerapos ) ;
return 1 ;
}
else if ( cg . snap & & ( cg . snap - > ps . weapon = = WP_SABER | | cg . snap - > ps . weapon = = WP_MELEE ) ) //implied: !cg.renderingThirdPerson
{ //first person saber hack
VectorCopy ( cg . refdef . vieworg , camerapos ) ;
return 1 ;
}
return 0 ;
}
int CG_GetCameraAng ( vec3_t cameraang )
{
if ( in_camera )
{
VectorCopy ( client_camera . angles , cameraang ) ;
return 1 ;
}
else
{
VectorCopy ( cg . refdefViewAngles , cameraang ) ;
return 1 ;
}
}
void CG_Printf ( const char * msg , . . . ) {
va_list argptr ;
char text [ 1024 ] ;
va_start ( argptr , msg ) ;
Q_vsnprintf ( text , sizeof ( text ) , msg , argptr ) ;
va_end ( argptr ) ;
cgi_Printf ( text ) ;
}
NORETURN void CG_Error ( const char * msg , . . . ) {
va_list argptr ;
char text [ 1024 ] ;
va_start ( argptr , msg ) ;
Q_vsnprintf ( text , sizeof ( text ) , msg , argptr ) ;
va_end ( argptr ) ;
cgi_Error ( text ) ;
}
/*
= = = = = = = = = = = = = = = =
CG_Argv
= = = = = = = = = = = = = = = =
*/
const char * CG_Argv ( int arg ) {
static char buffer [ MAX_STRING_CHARS ] ;
cgi_Argv ( arg , buffer , sizeof ( buffer ) ) ;
return buffer ;
}
//========================================================================
/*
= = = = = = = = = = = = = = = = =
CG_RegisterItemSounds
The server says this item is used on this level
= = = = = = = = = = = = = = = = =
*/
void CG_RegisterItemSounds ( int itemNum ) {
gitem_t * item ;
char data [ MAX_QPATH ] ;
const char * s , * start ;
int len ;
item = & bg_itemlist [ itemNum ] ;
if ( item - > pickup_sound )
{
cgi_S_RegisterSound ( item - > pickup_sound ) ;
}
// parse the space seperated precache string for other media
s = item - > sounds ;
if ( ! s | | ! s [ 0 ] )
return ;
while ( * s ) {
start = s ;
while ( * s & & * s ! = ' ' ) {
s + + ;
}
len = s - start ;
if ( len > = MAX_QPATH | | len < 5 ) {
CG_Error ( " PrecacheItem: %s has bad precache string " ,
item - > classname ) ;
return ;
}
memcpy ( data , start , len ) ;
data [ len ] = 0 ;
if ( * s ) {
s + + ;
}
if ( ! strcmp ( data + len - 3 , " wav " ) ) {
cgi_S_RegisterSound ( data ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = = =
CG_LoadingString
= = = = = = = = = = = = = = = = = = = = = =
*/
void CG_LoadingString ( const char * s ) {
Q_strncpyz ( cg . infoScreenText , s , sizeof ( cg . infoScreenText ) ) ;
cgi_UpdateScreen ( ) ;
}
static inline void CG_AS_Register ( void )
{
CG_LoadingString ( " ambient sound sets " ) ;
assert ( as_preCacheMap ) ;
//Load the ambient sets
cgi_AS_AddPrecacheEntry ( " #clear " ) ; // ;-)
//FIXME: Don't ask... I had to get around a really nasty MS error in the templates with this...
namePrecache_m : : iterator pi ;
STL_ITERATE ( pi , ( * as_preCacheMap ) )
{
cgi_AS_AddPrecacheEntry ( ( ( * pi ) . first ) . c_str ( ) ) ;
}
cgi_AS_ParseSets ( ) ;
}
/*
= = = = = = = = = = = = = = = = =
CG_RegisterSounds
called during a precache command
= = = = = = = = = = = = = = = = =
*/
static void CG_RegisterSounds ( void ) {
int i ;
char name [ MAX_QPATH ] ;
const char * soundName ;
CG_AS_Register ( ) ;
CG_LoadingString ( " general sounds " ) ;
//FIXME: add to cg.media?
cgi_S_RegisterSound ( " sound/player/fallsplat.wav " ) ;
cgs . media . selectSound = cgi_S_RegisterSound ( " sound/weapons/change.wav " ) ;
cgs . media . selectSound2 = cgi_S_RegisterSound ( " sound/interface/sub_select.wav " ) ;
// cgs.media.useNothingSound = cgi_S_RegisterSound( "sound/items/use_nothing.wav" );
cgs . media . noAmmoSound = cgi_S_RegisterSound ( " sound/weapons/noammo.wav " ) ;
// cgs.media.talkSound = cgi_S_RegisterSound( "sound/interface/communicator.wav" );
cgs . media . landSound = cgi_S_RegisterSound ( " sound/player/land1.wav " ) ;
cgs . media . rollSound = cgi_S_RegisterSound ( " sound/player/roll1.wav " ) ;
theFxScheduler . RegisterEffect ( " env/slide_dust " ) ;
cgs . media . overchargeFastSound = cgi_S_RegisterSound ( " sound/weapons/overchargeFast.wav " ) ;
cgs . media . overchargeSlowSound = cgi_S_RegisterSound ( " sound/weapons/overchargeSlow.wav " ) ;
cgs . media . overchargeLoopSound = cgi_S_RegisterSound ( " sound/weapons/overchargeLoop.wav " ) ;
cgs . media . overchargeEndSound = cgi_S_RegisterSound ( " sound/weapons/overchargeEnd.wav " ) ;
cgs . media . batteryChargeSound = cgi_S_RegisterSound ( " sound/interface/pickup_battery.wav " ) ;
// cgs.media.tedTextSound = cgi_S_RegisterSound( "sound/interface/tedtext.wav" );
cgs . media . messageLitSound = cgi_S_RegisterSound ( " sound/interface/update " ) ;
cgs . media . noforceSound = cgi_S_RegisterSound ( " sound/weapons/force/noforce " ) ;
cgs . media . watrInSound = cgi_S_RegisterSound ( " sound/player/watr_in.wav " ) ;
cgs . media . watrOutSound = cgi_S_RegisterSound ( " sound/player/watr_out.wav " ) ;
cgs . media . watrUnSound = cgi_S_RegisterSound ( " sound/player/watr_un.wav " ) ;
if ( ( gi . totalMapContents ( ) & CONTENTS_LAVA ) )
{
cgs . media . lavaInSound = cgi_S_RegisterSound ( " sound/player/inlava.wav " ) ;
cgs . media . lavaOutSound = cgi_S_RegisterSound ( " sound/player/watr_out.wav " ) ;
cgs . media . lavaUnSound = cgi_S_RegisterSound ( " sound/player/muckexit.wav " ) ;
}
// Zoom
cgs . media . zoomStart = cgi_S_RegisterSound ( " sound/interface/zoomstart.wav " ) ;
cgs . media . zoomLoop = cgi_S_RegisterSound ( " sound/interface/zoomloop.wav " ) ;
cgs . media . zoomEnd = cgi_S_RegisterSound ( " sound/interface/zoomend.wav " ) ;
cgi_S_RegisterSound ( " sound/chars/turret/startup.wav " ) ;
cgi_S_RegisterSound ( " sound/chars/turret/shutdown.wav " ) ;
cgi_S_RegisterSound ( " sound/chars/turret/ping.wav " ) ;
cgi_S_RegisterSound ( " sound/chars/turret/move.wav " ) ;
cgi_S_RegisterSound ( " sound/player/use_sentry " ) ;
cgi_R_RegisterModel ( " models/items/psgun.glm " ) ;
theFxScheduler . RegisterEffect ( " turret/explode " ) ;
theFxScheduler . RegisterEffect ( " sparks/spark_exp_nosnd " ) ;
for ( i = 0 ; i < 4 ; i + + ) {
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/stone_step%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_STONEWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/stone_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_STONERUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/metal_step%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_METALWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/metal_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_METALRUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/pipe_step%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_PIPEWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/pipe_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_PIPERUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/water_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_SPLASH ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/water_walk%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_WADE ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/water_wade_0%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_SWIM ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/snow_step%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_SNOWWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/snow_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_SNOWRUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/sand_walk%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_SANDWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/sand_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_SANDRUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/grass_step%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_GRASSWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/grass_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_GRASSRUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/dirt_step%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_DIRTWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/dirt_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_DIRTRUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/mud_walk%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_MUDWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/mud_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_MUDRUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/gravel_walk%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_GRAVELWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/gravel_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_GRAVELRUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/rug_step%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_RUGWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/rug_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_RUGRUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/wood_walk%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_WOODWALK ] [ i ] = cgi_S_RegisterSound ( name ) ;
Com_sprintf ( name , sizeof ( name ) , " sound/player/footsteps/wood_run%i.wav " , i + 1 ) ;
cgs . media . footsteps [ FOOTSTEP_WOODRUN ] [ i ] = cgi_S_RegisterSound ( name ) ;
}
cg . loadLCARSStage = 1 ;
CG_LoadingString ( " item sounds " ) ;
// only register the items that the server says we need
char items [ MAX_ITEMS + 1 ] ;
//Raz: Fixed buffer overflow
Q_strncpyz ( items , CG_ConfigString ( CS_ITEMS ) , sizeof ( items ) ) ;
for ( i = 1 ; i < bg_numItems ; i + + ) {
if ( items [ i ] = = ' 1 ' ) //even with sound pooling, don't clutter it for low end machines
{
CG_RegisterItemSounds ( i ) ;
}
}
cg . loadLCARSStage = 2 ;
CG_LoadingString ( " preregistered sounds " ) ;
for ( i = 1 ; i < MAX_SOUNDS ; i + + ) {
soundName = CG_ConfigString ( CS_SOUNDS + i ) ;
if ( ! soundName [ 0 ] ) {
break ;
}
if ( soundName [ 0 ] = = ' * ' ) {
continue ; // custom sound
}
if ( ! ( i & 7 ) ) {
CG_LoadingString ( soundName ) ;
}
cgs . sound_precache [ i ] = cgi_S_RegisterSound ( soundName ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
CLIENT INFO
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = = = = = = = = = =
CG_RegisterClientSkin
= = = = = = = = = = = = = = = = = = = = = = = = = =
*/
qboolean CG_RegisterClientSkin ( clientInfo_t * ci ,
const char * headModelName , const char * headSkinName ,
const char * torsoModelName , const char * torsoSkinName ,
const char * legsModelName , const char * legsSkinName )
{
char hfilename [ MAX_QPATH ] ;
char tfilename [ MAX_QPATH ] ;
char lfilename [ MAX_QPATH ] ;
Com_sprintf ( lfilename , sizeof ( lfilename ) , " models/players/%s/lower_%s.skin " , legsModelName , legsSkinName ) ;
ci - > legsSkin = cgi_R_RegisterSkin ( lfilename ) ;
if ( ! ci - > legsSkin )
{
// Com_Printf( "Failed to load skin file: %s : %s\n", legsModelName, legsSkinName );
//return qfalse;
}
if ( torsoModelName & & torsoSkinName & & torsoModelName [ 0 ] & & torsoSkinName [ 0 ] )
{
Com_sprintf ( tfilename , sizeof ( tfilename ) , " models/players/%s/upper_%s.skin " , torsoModelName , torsoSkinName ) ;
ci - > torsoSkin = cgi_R_RegisterSkin ( tfilename ) ;
if ( ! ci - > torsoSkin )
{
Com_Printf ( " Failed to load skin file: %s : %s \n " , torsoModelName , torsoSkinName ) ;
return qfalse ;
}
}
if ( headModelName & & headSkinName & & headModelName [ 0 ] & & headSkinName [ 0 ] )
{
Com_sprintf ( hfilename , sizeof ( hfilename ) , " models/players/%s/head_%s.skin " , headModelName , headSkinName ) ;
ci - > headSkin = cgi_R_RegisterSkin ( hfilename ) ;
if ( ! ci - > headSkin )
{
Com_Printf ( " Failed to load skin file: %s : %s \n " , headModelName , headSkinName ) ;
return qfalse ;
}
}
return qtrue ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = =
CG_RegisterClientModelname
= = = = = = = = = = = = = = = = = = = = = = = = = =
*/
qboolean CG_RegisterClientModelname ( clientInfo_t * ci ,
const char * headModelName , const char * headSkinName ,
const char * torsoModelName , const char * torsoSkinName ,
const char * legsModelName , const char * legsSkinName )
{
/*
Ghoul2 Insert Start
*/
# if 1
char filename [ MAX_QPATH ] ;
if ( ! legsModelName | | ! legsModelName [ 0 ] )
{
return qtrue ;
}
Com_sprintf ( filename , sizeof ( filename ) , " models/players/%s/lower.mdr " , legsModelName ) ;
ci - > legsModel = cgi_R_RegisterModel ( filename ) ;
if ( ! ci - > legsModel )
{ //he's not skeletal, try the old way
Com_sprintf ( filename , sizeof ( filename ) , " models/players/%s/lower.md3 " , legsModelName ) ;
ci - > legsModel = cgi_R_RegisterModel ( filename ) ;
if ( ! ci - > legsModel )
{
Com_Printf ( S_COLOR_RED " Failed to load model file %s \n " , filename ) ;
return qfalse ;
}
}
if ( torsoModelName & & torsoModelName [ 0 ] )
{ //You are trying to set one
Com_sprintf ( filename , sizeof ( filename ) , " models/players/%s/upper.mdr " , torsoModelName ) ;
ci - > torsoModel = cgi_R_RegisterModel ( filename ) ;
if ( ! ci - > torsoModel )
{ //he's not skeletal, try the old way
Com_sprintf ( filename , sizeof ( filename ) , " models/players/%s/upper.md3 " , torsoModelName ) ;
ci - > torsoModel = cgi_R_RegisterModel ( filename ) ;
if ( ! ci - > torsoModel )
{
Com_Printf ( S_COLOR_RED " Failed to load model file %s \n " , filename ) ;
return qfalse ;
}
}
}
else
{
ci - > torsoModel = 0 ;
}
if ( headModelName & & headModelName [ 0 ] )
{ //You are trying to set one
Com_sprintf ( filename , sizeof ( filename ) , " models/players/%s/head.md3 " , headModelName ) ;
ci - > headModel = cgi_R_RegisterModel ( filename ) ;
if ( ! ci - > headModel )
{
Com_Printf ( S_COLOR_RED " Failed to load model file %s \n " , filename ) ;
return qfalse ;
}
}
else
{
ci - > headModel = 0 ;
}
// if any skins failed to load, return failure
if ( ! CG_RegisterClientSkin ( ci , headModelName , headSkinName , torsoModelName , torsoSkinName , legsModelName , legsSkinName ) )
{
//Com_Printf( "Failed to load skin file: %s : %s/%s : %s/%s : %s\n", headModelName, headSkinName, torsoModelName, torsoSkinName, legsModelName, legsSkinName );
return qfalse ;
}
//FIXME: for now, uses the legs model dir for anim cfg, but should we set this in some sort of NPCs.cfg?
// load the animation file set
ci - > animFileIndex = G_ParseAnimFileSet ( legsModelName ) ;
if ( ci - > animFileIndex < 0 )
{
Com_Printf ( S_COLOR_RED " Failed to load animation file set models/players/%s \n " , legsModelName ) ;
return qfalse ;
}
# endif
/*
Ghoul2 Insert End
*/
return qtrue ;
}
void CG_RegisterClientRenderInfo ( clientInfo_t * ci , renderInfo_t * ri )
{
char * slash ;
char headModelName [ MAX_QPATH ] ;
char torsoModelName [ MAX_QPATH ] ;
char legsModelName [ MAX_QPATH ] ;
char headSkinName [ MAX_QPATH ] ;
char torsoSkinName [ MAX_QPATH ] ;
char legsSkinName [ MAX_QPATH ] ;
if ( ! ri - > legsModelName [ 0 ] )
{ //Must have at LEAST a legs model
return ;
}
Q_strncpyz ( legsModelName , ri - > legsModelName , sizeof ( legsModelName ) ) ;
//Legs skin
slash = strchr ( legsModelName , ' / ' ) ;
if ( ! slash )
{
// modelName didn not include a skin name
Q_strncpyz ( legsSkinName , " default " , sizeof ( legsSkinName ) ) ;
}
else
{
Q_strncpyz ( legsSkinName , slash + 1 , sizeof ( legsSkinName ) ) ;
// truncate modelName
* slash = 0 ;
}
if ( ri - > torsoModelName [ 0 ] )
{
Q_strncpyz ( torsoModelName , ri - > torsoModelName , sizeof ( torsoModelName ) ) ;
//Torso skin
slash = strchr ( torsoModelName , ' / ' ) ;
if ( ! slash )
{
// modelName didn't include a skin name
Q_strncpyz ( torsoSkinName , " default " , sizeof ( torsoSkinName ) ) ;
}
else
{
Q_strncpyz ( torsoSkinName , slash + 1 , sizeof ( torsoSkinName ) ) ;
// truncate modelName
* slash = 0 ;
}
}
else
{
torsoModelName [ 0 ] = 0 ;
}
//Head
if ( ri - > headModelName [ 0 ] )
{
Q_strncpyz ( headModelName , ri - > headModelName , sizeof ( headModelName ) ) ;
//Head skin
slash = strchr ( headModelName , ' / ' ) ;
if ( ! slash )
{
// modelName didn not include a skin name
Q_strncpyz ( headSkinName , " default " , sizeof ( headSkinName ) ) ;
}
else
{
Q_strncpyz ( headSkinName , slash + 1 , sizeof ( headSkinName ) ) ;
// truncate modelName
* slash = 0 ;
}
}
else
{
headModelName [ 0 ] = 0 ;
}
if ( ! CG_RegisterClientModelname ( ci , headModelName , headSkinName , torsoModelName , torsoSkinName , legsModelName , legsSkinName ) )
{
if ( ! CG_RegisterClientModelname ( ci , DEFAULT_HEADMODEL , " default " , DEFAULT_TORSOMODEL , " default " , DEFAULT_LEGSMODEL , " default " ) )
{
CG_Error ( " DEFAULT_MODELS failed to register " ) ;
}
}
}
//-------------------------------------
// CG_RegisterEffects
//
// Handles precaching all effect files
// and any shader, model, or sound
// files an effect may use.
//-------------------------------------
extern void CG_InitGlass ( void ) ;
extern void cgi_R_WorldEffectCommand ( const char * command ) ;
extern cvar_t * g_delayedShutdown ;
static void CG_RegisterEffects ( void )
{
char * effectName ;
int i , numFailed = 0 ;
// Register external effects
for ( i = 1 ; i < MAX_FX ; i + + )
{
effectName = ( char * ) CG_ConfigString ( CS_EFFECTS + i ) ;
if ( ! effectName [ 0 ] )
{
break ;
}
if ( ! theFxScheduler . RegisterEffect ( ( const char * ) effectName ) )
{
//assert(0);
numFailed + + ;
}
}
if ( numFailed & & g_delayedShutdown - > integer )
{
//assert(0);
//CG_Error( "CG_RegisterEffects: %i Effects failed to load. Please fix, or ask Aurelio.", numFailed );
}
// Start world effects
for ( i = 1 ; i < MAX_WORLD_FX ; i + + )
{
effectName = ( char * ) CG_ConfigString ( CS_WORLD_FX + i ) ;
if ( ! effectName [ 0 ] )
{
break ;
}
cgi_R_WorldEffectCommand ( effectName ) ;
}
// Set up the glass effects mini-system.
CG_InitGlass ( ) ;
//footstep effects
cgs . effects . footstepMud = theFxScheduler . RegisterEffect ( " materials/mud " ) ;
cgs . effects . footstepSand = theFxScheduler . RegisterEffect ( " materials/sand " ) ;
cgs . effects . footstepSnow = theFxScheduler . RegisterEffect ( " materials/snow " ) ;
cgs . effects . footstepGravel = theFxScheduler . RegisterEffect ( " materials/gravel " ) ;
//landing effects
cgs . effects . landingMud = theFxScheduler . RegisterEffect ( " materials/mud_large " ) ;
cgs . effects . landingSand = theFxScheduler . RegisterEffect ( " materials/sand_large " ) ;
cgs . effects . landingDirt = theFxScheduler . RegisterEffect ( " materials/dirt_large " ) ;
cgs . effects . landingSnow = theFxScheduler . RegisterEffect ( " materials/snow_large " ) ;
cgs . effects . landingGravel = theFxScheduler . RegisterEffect ( " materials/gravel_large " ) ;
//splashes
if ( ( gi . totalMapContents ( ) & CONTENTS_WATER ) )
{
theFxScheduler . RegisterEffect ( " env/water_impact " ) ;
theFxScheduler . RegisterEffect ( " misc/waterbreath " ) ;
}
if ( ( gi . totalMapContents ( ) & CONTENTS_LAVA ) )
{
theFxScheduler . RegisterEffect ( " env/lava_splash " ) ;
}
if ( ( gi . totalMapContents ( ) & CONTENTS_SLIME ) )
{
theFxScheduler . RegisterEffect ( " env/acid_splash " ) ;
}
theFxScheduler . RegisterEffect ( " misc/breath " ) ;
}
/*
void CG_RegisterClientModels ( int entityNum )
Only call if clientInfo - > infoValid is not true
For players and NPCs to register their models
*/
void CG_RegisterClientModels ( int entityNum )
{
gentity_t * ent ;
if ( entityNum < 0 | | entityNum > ENTITYNUM_WORLD )
{
return ;
}
ent = & g_entities [ entityNum ] ;
if ( ! ent - > client )
{
return ;
}
ent - > client - > clientInfo . infoValid = qtrue ;
if ( ent - > playerModel ! = - 1 & & ent - > ghoul2 . size ( ) )
{
return ;
}
CG_RegisterClientRenderInfo ( & ent - > client - > clientInfo , & ent - > client - > renderInfo ) ;
if ( entityNum < MAX_CLIENTS )
{
memcpy ( & cgs . clientinfo [ entityNum ] , & ent - > client - > clientInfo , sizeof ( clientInfo_t ) ) ;
}
}
//===================================================================================
HUDMenuItem_t forceTics [ ] =
{
{ " rightHUD " , " force_tic1 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Top
{ " rightHUD " , " force_tic2 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Top
{ " rightHUD " , " force_tic3 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Top
{ " rightHUD " , " force_tic4 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Top
} ;
HUDMenuItem_t ammoTics [ ] =
{
{ " rightHUD " , " ammo_tic1 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Top
{ " rightHUD " , " ammo_tic2 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Top
{ " rightHUD " , " ammo_tic3 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Top
{ " rightHUD " , " ammo_tic4 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Top
} ;
HUDMenuItem_t armorTics [ ] =
{
{ " leftHUD " , " armor_tic1 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Top
{ " leftHUD " , " armor_tic2 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } ,
{ " leftHUD " , " armor_tic3 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } ,
{ " leftHUD " , " armor_tic4 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } ,
} ;
HUDMenuItem_t healthTics [ ] =
{
{ " leftHUD " , " health_tic1 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Top
{ " leftHUD " , " health_tic2 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , //
{ " leftHUD " , " health_tic3 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , //
{ " leftHUD " , " health_tic4 " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // Bottom
} ;
HUDMenuItem_t otherHUDBits [ ] =
{
{ " lefthud " , " healthamount " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_HEALTHAMOUNT
{ " lefthud " , " armoramount " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_ARMORAMOUNT
{ " righthud " , " forceamount " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_FORCEAMOUNT
{ " righthud " , " ammoamount " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_AMMOAMOUNT
{ " righthud " , " saberstyle_strong " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_SABERSTYLE_STRONG
{ " righthud " , " saberstyle_medium " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_SABERSTYLE_MEDIUM
{ " righthud " , " saberstyle_fast " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_SABERSTYLE_FAST
{ " lefthud " , " scanline " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_SCANLINE_LEFT
{ " righthud " , " scanline " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_SCANLINE_RIGHT
{ " lefthud " , " frame " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_FRAME_LEFT
{ " righthud " , " frame " , 0 , 0 , 0 , 0 , { 0.0f , 0.0f , 0.0f , 0.0f } , NULL_HANDLE } , // OHB_FRAME_RIGHT
} ;
/*const char *HolocronIcons[] = {
" gfx/mp/f_icon_lt_heal " , //FP_HEAL,
" gfx/mp/f_icon_levitation " , //FP_LEVITATION,
" gfx/mp/f_icon_speed " , //FP_SPEED,
" gfx/mp/f_icon_push " , //FP_PUSH,
" gfx/mp/f_icon_pull " , //FP_PULL,
" gfx/mp/f_icon_lt_telepathy " , //FP_TELEPATHY,
" gfx/mp/f_icon_dk_grip " , //FP_GRIP,
" gfx/mp/f_icon_dk_l1 " , //FP_LIGHTNING,
" gfx/mp/f_icon_dk_rage " , //FP_RAGE,
" gfx/mp/f_icon_lt_protect " , //FP_PROTECT,
" gfx/mp/f_icon_lt_absorb " , //FP_ABSORB,
" gfx/mp/f_icon_lt_healother " , //FP_TEAM_HEAL,
" gfx/mp/f_icon_dk_forceother " , //FP_TEAM_FORCE,
" gfx/mp/f_icon_dk_drain " , //FP_DRAIN,
" gfx/mp/f_icon_sight " , //FP_SEE,
" gfx/mp/f_icon_saber_attack " , //FP_SABERATTACK,
" gfx/mp/f_icon_saber_defend " , //FP_SABERDEFEND,
" gfx/mp/f_icon_saber_throw " //FP_SABERTHROW
} ;
*/
extern void CG_NPC_Precache ( gentity_t * spawner ) ;
qboolean NPCsPrecached = qfalse ;
/*
= = = = = = = = = = = = = = = = =
CG_PrepRefresh
Call before entering a new level , or after changing renderers
This function may execute for a couple of minutes with a slow disk .
= = = = = = = = = = = = = = = = =
*/
void CG_CreateMiscEnts ( void ) ;
static void CG_RegisterGraphics ( void ) {
int i ;
char items [ MAX_ITEMS + 1 ] ;
int breakPoint = 0 ;
const char * sb_nums [ 11 ] = {
" gfx/2d/numbers/zero " ,
" gfx/2d/numbers/one " ,
" gfx/2d/numbers/two " ,
" gfx/2d/numbers/three " ,
" gfx/2d/numbers/four " ,
" gfx/2d/numbers/five " ,
" gfx/2d/numbers/six " ,
" gfx/2d/numbers/seven " ,
" gfx/2d/numbers/eight " ,
" gfx/2d/numbers/nine " ,
" gfx/2d/numbers/minus " ,
} ;
const char * sb_t_nums [ 11 ] = {
" gfx/2d/numbers/t_zero " ,
" gfx/2d/numbers/t_one " ,
" gfx/2d/numbers/t_two " ,
" gfx/2d/numbers/t_three " ,
" gfx/2d/numbers/t_four " ,
" gfx/2d/numbers/t_five " ,
" gfx/2d/numbers/t_six " ,
" gfx/2d/numbers/t_seven " ,
" gfx/2d/numbers/t_eight " ,
" gfx/2d/numbers/t_nine " ,
" gfx/2d/numbers/t_minus " ,
} ;
const char * sb_c_nums [ 11 ] = {
" gfx/2d/numbers/c_zero " ,
" gfx/2d/numbers/c_one " ,
" gfx/2d/numbers/c_two " ,
" gfx/2d/numbers/c_three " ,
" gfx/2d/numbers/c_four " ,
" gfx/2d/numbers/c_five " ,
" gfx/2d/numbers/c_six " ,
" gfx/2d/numbers/c_seven " ,
" gfx/2d/numbers/c_eight " ,
" gfx/2d/numbers/c_nine " ,
" gfx/2d/numbers/t_minus " , //?????
} ;
// Clean, then register...rinse...repeat...
CG_LoadingString ( " effects " ) ;
FX_Init ( ) ;
CG_RegisterEffects ( ) ;
// clear any references to old media
memset ( & cg . refdef , 0 , sizeof ( cg . refdef ) ) ;
cgi_R_ClearScene ( ) ;
cg . loadLCARSStage = 3 ;
CG_LoadingString ( cgs . mapname ) ;
cgi_R_LoadWorldMap ( cgs . mapname ) ;
cg . loadLCARSStage = 4 ;
CG_LoadingString ( " game media shaders " ) ;
for ( i = 0 ; i < 11 ; i + + )
{
cgs . media . numberShaders [ i ] = cgi_R_RegisterShaderNoMip ( sb_nums [ i ] ) ;
cgs . media . smallnumberShaders [ i ] = cgi_R_RegisterShaderNoMip ( sb_t_nums [ i ] ) ;
cgs . media . chunkyNumberShaders [ i ] = cgi_R_RegisterShaderNoMip ( sb_c_nums [ i ] ) ;
}
// FIXME: conditionally do this?? Something must be wrong with inventory item caching..?
cgi_R_RegisterModel ( " models/items/remote.md3 " ) ;
cgs . media . explosionModel = cgi_R_RegisterModel ( " models/weaphits/explosion.md3 " ) ;
cgs . media . surfaceExplosionShader = cgi_R_RegisterShader ( " surfaceExplosion " ) ;
cgs . media . halfShieldModel = cgi_R_RegisterModel ( " models/weaphits/testboom.md3 " ) ;
cgs . media . solidWhiteShader = cgi_R_RegisterShader ( " gfx/effects/solidWhite " ) ;
cgs . media . refractShader = cgi_R_RegisterShader ( " effects/refraction " ) ;
//on players
cgs . media . personalShieldShader = cgi_R_RegisterShader ( " gfx/misc/personalshield " ) ;
cgs . media . cloakedShader = cgi_R_RegisterShader ( " gfx/effects/cloakedShader " ) ;
cgi_R_RegisterShader ( " gfx/misc/ion_shield " ) ;
cgs . media . boltShader = cgi_R_RegisterShader ( " gfx/misc/blueLine " ) ;
// FIXME: do these conditionally
cgi_R_RegisterShader ( " gfx/2d/workingCamera " ) ;
cgi_R_RegisterShader ( " gfx/2d/brokenCamera " ) ;
//cgi_R_RegisterShader( "gfx/effects/irid_shield" ); // for galak, but he doesn't have his own weapon so I can't register the shader there.
//interface
for ( i = 0 ; i < NUM_CROSSHAIRS ; i + + ) {
cgs . media . crosshairShader [ i ] = cgi_R_RegisterShaderNoMip ( va ( " gfx/2d/crosshair%c " , ' a ' + i ) ) ;
}
cgs . media . backTileShader = cgi_R_RegisterShader ( " gfx/2d/backtile " ) ;
// cgs.media.noammoShader = cgi_R_RegisterShaderNoMip( "gfx/hud/noammo");
cgs . media . weaponIconBackground = cgi_R_RegisterShaderNoMip ( " gfx/hud/background " ) ;
cgs . media . forceIconBackground = cgi_R_RegisterShaderNoMip ( " gfx/hud/background_f " ) ;
cgs . media . inventoryIconBackground = cgi_R_RegisterShaderNoMip ( " gfx/hud/background_i " ) ;
cgs . media . dataPadFrame = cgi_R_RegisterShaderNoMip ( " gfx/menus/datapad " ) ;
//gore decal shaders -rww
cgs . media . bdecal_burnmark1 = cgi_R_RegisterShader ( " gfx/damage/burnmark1 " ) ;
cgs . media . bdecal_saberglowmark = cgi_R_RegisterShader ( " gfx/damage/saberglowmark " ) ;
cg . loadLCARSStage = 5 ;
CG_LoadingString ( " game media models " ) ;
// Chunk models
//FIXME: jfm:? bother to conditionally load these if an ent has this material type?
for ( i = 0 ; i < NUM_CHUNK_MODELS ; i + + )
{
cgs . media . chunkModels [ CHUNK_METAL2 ] [ i ] = cgi_R_RegisterModel ( va ( " models/chunks/metal/metal1_%i.md3 " , i + 1 ) ) ; //_ /switched\ _
cgs . media . chunkModels [ CHUNK_METAL1 ] [ i ] = cgi_R_RegisterModel ( va ( " models/chunks/metal/metal2_%i.md3 " , i + 1 ) ) ; // \switched/
cgs . media . chunkModels [ CHUNK_ROCK1 ] [ i ] = cgi_R_RegisterModel ( va ( " models/chunks/rock/rock1_%i.md3 " , i + 1 ) ) ;
cgs . media . chunkModels [ CHUNK_ROCK2 ] [ i ] = cgi_R_RegisterModel ( va ( " models/chunks/rock/rock2_%i.md3 " , i + 1 ) ) ;
cgs . media . chunkModels [ CHUNK_ROCK3 ] [ i ] = cgi_R_RegisterModel ( va ( " models/chunks/rock/rock3_%i.md3 " , i + 1 ) ) ;
cgs . media . chunkModels [ CHUNK_CRATE1 ] [ i ] = cgi_R_RegisterModel ( va ( " models/chunks/crate/crate1_%i.md3 " , i + 1 ) ) ;
cgs . media . chunkModels [ CHUNK_CRATE2 ] [ i ] = cgi_R_RegisterModel ( va ( " models/chunks/crate/crate2_%i.md3 " , i + 1 ) ) ;
cgs . media . chunkModels [ CHUNK_WHITE_METAL ] [ i ] = cgi_R_RegisterModel ( va ( " models/chunks/metal/wmetal1_%i.md3 " , i + 1 ) ) ;
}
cgs . media . chunkSound = cgi_S_RegisterSound ( " sound/weapons/explosions/glasslcar " ) ;
cgs . media . grateSound = cgi_S_RegisterSound ( " sound/effects/grate_destroy " ) ;
cgs . media . rockBreakSound = cgi_S_RegisterSound ( " sound/effects/wall_smash " ) ;
cgs . media . rockBounceSound [ 0 ] = cgi_S_RegisterSound ( " sound/effects/stone_bounce " ) ;
cgs . media . rockBounceSound [ 1 ] = cgi_S_RegisterSound ( " sound/effects/stone_bounce2 " ) ;
cgs . media . metalBounceSound [ 0 ] = cgi_S_RegisterSound ( " sound/effects/metal_bounce " ) ;
cgs . media . metalBounceSound [ 1 ] = cgi_S_RegisterSound ( " sound/effects/metal_bounce2 " ) ;
cgs . media . glassChunkSound = cgi_S_RegisterSound ( " sound/weapons/explosions/glassbreak1 " ) ;
cgs . media . crateBreakSound [ 0 ] = cgi_S_RegisterSound ( " sound/weapons/explosions/crateBust1 " ) ;
cgs . media . crateBreakSound [ 1 ] = cgi_S_RegisterSound ( " sound/weapons/explosions/crateBust2 " ) ;
cgs . media . weaponbox = cgi_R_RegisterShaderNoMip ( " gfx/interface/weapon_box " ) ;
//Models & Shaders
cgs . media . damageBlendBlobShader = cgi_R_RegisterShader ( " gfx/misc/borgeyeflare " ) ;
cg . loadLCARSStage = 6 ;
cgs . media . messageLitOn = cgi_R_RegisterShaderNoMip ( " gfx/hud/message_on " ) ;
cgs . media . messageLitOff = cgi_R_RegisterShaderNoMip ( " gfx/hud/message_off " ) ;
cgs . media . messageObjCircle = cgi_R_RegisterShaderNoMip ( " gfx/hud/objective_circle " ) ;
cgs . media . DPForcePowerOverlay = cgi_R_RegisterShader ( " gfx/hud/force_swirl " ) ;
//NOTE: we should only cache this if there is a vehicle or emplaced gun somewhere on the map
cgs . media . emplacedHealthBarShader = cgi_R_RegisterShaderNoMip ( " gfx/hud/health_frame " ) ;
// battery charge shader when using a gonk
cgs . media . batteryChargeShader = cgi_R_RegisterShader ( " gfx/2d/battery " ) ;
cgi_R_RegisterShader ( " gfx/2d/droid_view " ) ;
cgs . media . useableHint = cgi_R_RegisterShader ( " gfx/hud/useableHint " ) ;
// Load up other HUD bits
for ( i = 0 ; i < OHB_MAX ; i + + )
{
cgi_UI_GetMenuItemInfo (
otherHUDBits [ i ] . menuName ,
otherHUDBits [ i ] . itemName ,
& otherHUDBits [ i ] . xPos ,
& otherHUDBits [ i ] . yPos ,
& otherHUDBits [ i ] . width ,
& otherHUDBits [ i ] . height ,
otherHUDBits [ i ] . color ,
& otherHUDBits [ i ] . background ) ;
}
// Get all the info for each HUD piece
for ( i = 0 ; i < MAX_HUD_TICS ; i + + )
{
cgi_UI_GetMenuItemInfo (
healthTics [ i ] . menuName ,
healthTics [ i ] . itemName ,
& healthTics [ i ] . xPos ,
& healthTics [ i ] . yPos ,
& healthTics [ i ] . width ,
& healthTics [ i ] . height ,
healthTics [ i ] . color ,
& healthTics [ i ] . background ) ;
cgi_UI_GetMenuItemInfo (
armorTics [ i ] . menuName ,
armorTics [ i ] . itemName ,
& armorTics [ i ] . xPos ,
& armorTics [ i ] . yPos ,
& armorTics [ i ] . width ,
& armorTics [ i ] . height ,
armorTics [ i ] . color ,
& armorTics [ i ] . background ) ;
cgi_UI_GetMenuItemInfo (
forceTics [ i ] . menuName ,
forceTics [ i ] . itemName ,
& forceTics [ i ] . xPos ,
& forceTics [ i ] . yPos ,
& forceTics [ i ] . width ,
& forceTics [ i ] . height ,
forceTics [ i ] . color ,
& forceTics [ i ] . background ) ;
cgi_UI_GetMenuItemInfo (
ammoTics [ i ] . menuName ,
ammoTics [ i ] . itemName ,
& ammoTics [ i ] . xPos ,
& ammoTics [ i ] . yPos ,
& ammoTics [ i ] . width ,
& ammoTics [ i ] . height ,
ammoTics [ i ] . color ,
& ammoTics [ i ] . background ) ;
}
memset ( cg_items , 0 , sizeof ( cg_items ) ) ;
memset ( cg_weapons , 0 , sizeof ( cg_weapons ) ) ;
// only register the items that the server says we need
Q_strncpyz ( items , CG_ConfigString ( CS_ITEMS ) , sizeof ( items ) ) ;
for ( i = 1 ; i < bg_numItems ; i + + ) {
if ( items [ i ] = = ' 1 ' )
{
if ( bg_itemlist [ i ] . classname )
{
CG_LoadingString ( bg_itemlist [ i ] . classname ) ;
CG_RegisterItemVisuals ( i ) ;
}
}
if ( bg_itemlist [ i ] . giType = = IT_HOLDABLE )
{
if ( bg_itemlist [ i ] . giTag < INV_MAX )
{
inv_icons [ bg_itemlist [ i ] . giTag ] = cgi_R_RegisterShaderNoMip ( bg_itemlist [ i ] . icon ) ;
}
}
}
//precache force power icons here
/* i = 0;
while ( i < NUM_FORCE_POWERS )
{
cgs . media . forcePowerIcons [ i ] = cgi_R_RegisterShaderNoMip ( HolocronIcons [ i ] ) ;
i + + ;
}
*/
cgs . media . rageRecShader = cgi_R_RegisterShaderNoMip ( " gfx/mp/f_icon_ragerec " ) ;
//etc.
cgi_R_RegisterShader ( " gfx/misc/test_crackle " ) ; //CG_DoGlassQuad
// wall marks
cgs . media . scavMarkShader = cgi_R_RegisterShader ( " gfx/damage/burnmark4 " ) ;
cgs . media . rivetMarkShader = cgi_R_RegisterShader ( " gfx/damage/rivetmark " ) ;
// 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
cgs . media . electricBodyShader = cgi_R_RegisterShader ( " gfx/misc/electric " ) ;
cgs . media . electricBody2Shader = cgi_R_RegisterShader ( " gfx/misc/fullbodyelectric2 " ) ;
cgs . media . shadowMarkShader = cgi_R_RegisterShader ( " markShadow " ) ;
cgs . media . wakeMarkShader = cgi_R_RegisterShader ( " wake " ) ;
cgs . media . fsrMarkShader = cgi_R_RegisterShader ( " footstep_r " ) ;
cgs . media . fslMarkShader = cgi_R_RegisterShader ( " footstep_l " ) ;
cgs . media . fshrMarkShader = cgi_R_RegisterShader ( " footstep_heavy_r " ) ;
cgs . media . fshlMarkShader = cgi_R_RegisterShader ( " footstep_heavy_l " ) ;
cgi_S_RegisterSound ( " sound/effects/energy_crackle.wav " ) ;
CG_LoadingString ( " map brushes " ) ;
// register the inline models
breakPoint = cgs . numInlineModels = cgi_CM_NumInlineModels ( ) ;
assert ( ( size_t ) cgs . numInlineModels < sizeof ( cgs . inlineDrawModel ) / sizeof ( cgs . inlineDrawModel [ 0 ] ) ) ;
for ( i = 1 ; i < cgs . numInlineModels ; i + + ) {
char name [ 10 ] ;
vec3_t mins , maxs ;
int j ;
Com_sprintf ( name , sizeof ( name ) , " *%i " , i ) ;
cgs . inlineDrawModel [ i ] = cgi_R_RegisterModel ( name ) ;
if ( ! cgs . inlineDrawModel [ i ] )
{
breakPoint = i ;
break ;
}
cgi_R_ModelBounds ( cgs . inlineDrawModel [ i ] , mins , maxs ) ;
for ( j = 0 ; j < 3 ; j + + ) {
cgs . inlineModelMidpoints [ i ] [ j ] = mins [ j ] + 0.5 * ( maxs [ j ] - mins [ j ] ) ;
}
}
cg . loadLCARSStage = 7 ;
CG_LoadingString ( " map models " ) ;
// register all the server specified models
for ( i = 1 ; i < MAX_MODELS ; i + + ) {
const char * modelName ;
modelName = CG_ConfigString ( CS_MODELS + i ) ;
if ( ! modelName [ 0 ] ) {
break ;
}
cgs . model_draw [ i ] = cgi_R_RegisterModel ( modelName ) ;
// OutputDebugString(va("### CG_RegisterGraphics(): cgs.model_draw[%d] = \"%s\"\n",i,modelName));
}
cg . loadLCARSStage = 8 ;
/*
Ghoul2 Insert Start
*/
CG_LoadingString ( " skins " ) ;
// register all the server specified models
for ( i = 1 ; i < MAX_CHARSKINS ; i + + ) {
const char * modelName ;
modelName = CG_ConfigString ( CS_CHARSKINS + i ) ;
if ( ! modelName [ 0 ] ) {
break ;
}
cgs . skins [ i ] = cgi_R_RegisterSkin ( modelName ) ;
}
/*
Ghoul2 Insert End
*/
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
//feedback( va("client %i", i ) );
CG_NewClientinfo ( i ) ;
}
for ( i = 0 ; i < ENTITYNUM_WORLD ; i + + )
{
if ( & g_entities [ i ] )
{
if ( g_entities [ i ] . client )
{
//if(!g_entities[i].client->clientInfo.infoValid)
//We presume this
{
CG_LoadingString ( va ( " client %s " , g_entities [ i ] . client - > clientInfo . name ) ) ;
CG_RegisterClientModels ( i ) ;
if ( i ! = 0 )
{ //Client weapons already precached
CG_RegisterWeapon ( g_entities [ i ] . client - > ps . weapon ) ;
if ( g_entities [ i ] . client - > ps . saber [ 0 ] . g2MarksShader [ 0 ] )
{
cgi_R_RegisterShader ( g_entities [ i ] . client - > ps . saber [ 0 ] . g2MarksShader ) ;
}
if ( g_entities [ i ] . client - > ps . saber [ 0 ] . g2MarksShader2 [ 0 ] )
{
cgi_R_RegisterShader ( g_entities [ i ] . client - > ps . saber [ 0 ] . g2MarksShader2 ) ;
}
if ( g_entities [ i ] . client - > ps . saber [ 0 ] . g2WeaponMarkShader [ 0 ] )
{
cgi_R_RegisterShader ( g_entities [ i ] . client - > ps . saber [ 0 ] . g2WeaponMarkShader ) ;
}
if ( g_entities [ i ] . client - > ps . saber [ 0 ] . g2WeaponMarkShader2 [ 0 ] )
{
cgi_R_RegisterShader ( g_entities [ i ] . client - > ps . saber [ 0 ] . g2WeaponMarkShader2 ) ;
}
if ( g_entities [ i ] . client - > ps . saber [ 1 ] . g2MarksShader [ 0 ] )
{
cgi_R_RegisterShader ( g_entities [ i ] . client - > ps . saber [ 1 ] . g2MarksShader ) ;
}
if ( g_entities [ i ] . client - > ps . saber [ 1 ] . g2MarksShader2 [ 0 ] )
{
cgi_R_RegisterShader ( g_entities [ i ] . client - > ps . saber [ 1 ] . g2MarksShader2 ) ;
}
if ( g_entities [ i ] . client - > ps . saber [ 1 ] . g2WeaponMarkShader [ 0 ] )
{
cgi_R_RegisterShader ( g_entities [ i ] . client - > ps . saber [ 1 ] . g2WeaponMarkShader ) ;
}
if ( g_entities [ i ] . client - > ps . saber [ 1 ] . g2WeaponMarkShader2 [ 0 ] )
{
cgi_R_RegisterShader ( g_entities [ i ] . client - > ps . saber [ 1 ] . g2WeaponMarkShader2 ) ;
}
CG_RegisterNPCCustomSounds ( & g_entities [ i ] . client - > clientInfo ) ;
//CG_RegisterNPCEffects( g_entities[i].client->playerTeam );
}
}
}
else if ( g_entities [ i ] . svFlags & SVF_NPC_PRECACHE & & g_entities [ i ] . NPC_type & & g_entities [ i ] . NPC_type [ 0 ] )
{ //Precache the NPC_type
//FIXME: make sure we didn't precache this NPC_type already
CG_LoadingString ( va ( " NPC %s " , g_entities [ i ] . NPC_type ) ) ;
/*
if ( g_entities [ i ] . classname & & g_entities [ i ] . classname [ 0 ] & & Q_stricmp ( g_entities [ i ] . classname , " NPC_Vehicle " ) = = 0 )
{
// Get The Index, And Make Sure To Register All The Skins
int iVehIndex = BG_VehicleGetIndex ( g_entities [ i ] . NPC_type ) ;
}
else
*/
{
CG_NPC_Precache ( & g_entities [ i ] ) ;
}
}
}
}
CG_LoadingString ( " static models " ) ;
CG_CreateMiscEnts ( ) ;
cg . loadLCARSStage = 9 ;
NPCsPrecached = qtrue ;
extern cvar_t * com_buildScript ;
if ( com_buildScript - > integer ) {
cgi_R_RegisterShader ( " gfx/misc/nav_cpoint " ) ;
cgi_R_RegisterShader ( " gfx/misc/nav_line " ) ;
cgi_R_RegisterShader ( " gfx/misc/nav_arrow " ) ;
cgi_R_RegisterShader ( " gfx/misc/nav_node " ) ;
}
for ( i = 1 ; i < MAX_SUB_BSP ; i + + )
{
const char * bspName = 0 ;
vec3_t mins , maxs ;
int j = 0 ;
int sub = 0 ;
char temp [ MAX_QPATH ] ;
bspName = CG_ConfigString ( CS_BSP_MODELS + i ) ;
if ( ! bspName [ 0 ] )
{
break ;
}
CG_LoadingString ( " BSP instances " ) ;
cgi_CM_LoadMap ( bspName , qtrue ) ;
cgs . inlineDrawModel [ breakPoint ] = cgi_R_RegisterModel ( bspName ) ;
cgi_R_ModelBounds ( cgs . inlineDrawModel [ breakPoint ] , mins , maxs ) ;
for ( j = 0 ; j < 3 ; j + + )
{
cgs . inlineModelMidpoints [ breakPoint ] [ j ] = mins [ j ] + 0.5 * ( maxs [ j ] - mins [ j ] ) ;
}
breakPoint + + ;
for ( sub = 1 ; sub < MAX_MODELS ; sub + + )
{
Com_sprintf ( temp , MAX_QPATH , " *%d-%d " , i , sub ) ;
cgs . inlineDrawModel [ breakPoint ] = cgi_R_RegisterModel ( temp ) ;
if ( ! cgs . inlineDrawModel [ breakPoint ] )
{
break ;
}
cgi_R_ModelBounds ( cgs . inlineDrawModel [ breakPoint ] , mins , maxs ) ;
for ( j = 0 ; j < 3 ; j + + )
{
cgs . inlineModelMidpoints [ breakPoint ] [ j ] = mins [ j ] + 0.5 * ( maxs [ j ] - mins [ j ] ) ;
}
breakPoint + + ;
}
}
const char * terrainInfo ;
int terrainID ;
for ( i = 1 ; i < MAX_TERRAINS ; i + + )
{
terrainInfo = CG_ConfigString ( CS_TERRAINS + i ) ;
if ( ! terrainInfo [ 0 ] )
{
break ;
}
CG_LoadingString ( " Creating terrain " ) ;
terrainID = cgi_CM_RegisterTerrain ( terrainInfo ) ;
cgi_RMG_Init ( terrainID , terrainInfo ) ;
// Send off the terrainInfo to the renderer
cgi_RE_InitRendererTerrain ( terrainInfo ) ;
}
}
//===========================================================================
/*
= = = = = = = = = = = = = = = = =
CG_ConfigString
= = = = = = = = = = = = = = = = =
*/
const char * CG_ConfigString ( int index ) {
if ( index < 0 | | index > = MAX_CONFIGSTRINGS ) {
CG_Error ( " CG_ConfigString: bad index: %i " , index ) ;
}
return cgs . gameState . stringData + cgs . gameState . stringOffsets [ index ] ;
}
//==================================================================
void CG_LinkCentsToGents ( void )
{
int i ;
for ( i = 0 ; i < MAX_GENTITIES ; i + + )
{
cg_entities [ i ] . gent = & g_entities [ i ] ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = =
CG_StartMusic
= = = = = = = = = = = = = = = = = = = = = =
*/
void CG_StartMusic ( qboolean bForceStart ) {
const char * s ;
char parm1 [ MAX_QPATH ] , parm2 [ MAX_QPATH ] ;
// start the background music
s = ( char * ) CG_ConfigString ( CS_MUSIC ) ;
COM_BeginParseSession ( ) ;
Q_strncpyz ( parm1 , COM_Parse ( & s ) , sizeof ( parm1 ) ) ;
Q_strncpyz ( parm2 , COM_Parse ( & s ) , sizeof ( parm2 ) ) ;
COM_EndParseSession ( ) ;
cgi_S_StartBackgroundTrack ( parm1 , parm2 , ( qboolean ) ! bForceStart ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = =
CG_GameStateReceived
Displays the info screen while loading media
= = = = = = = = = = = = = = = = = = = = = =
*/
int iCGResetCount = 0 ;
qboolean qbVidRestartOccured = qfalse ;
//===================
qboolean gbUseTheseValuesFromLoadSave = qfalse ; // MUST default to this
int gi_cg_forcepowerSelect ;
int gi_cg_inventorySelect ;
//===================
static void CG_GameStateReceived ( void ) {
// clear everything
extern void CG_ClearAnimEvtCache ( void ) ;
CG_ClearAnimEvtCache ( ) ; // else sound handles wrong after vid_restart
qbVidRestartOccured = qtrue ;
iCGResetCount + + ;
if ( iCGResetCount = = 1 ) // this will only equal 1 first time, after each vid_restart it just gets higher.
{ // This non-clear is so the user can vid_restart during scrolling text without losing it.
qbVidRestartOccured = qfalse ;
}
if ( ! qbVidRestartOccured )
{
CG_Init_CG ( ) ;
cg . weaponSelect = WP_NONE ;
cg . forcepowerSelect = FP_HEAL ;
}
memset ( cg_weapons , 0 , sizeof ( cg_weapons ) ) ;
memset ( cg_items , 0 , sizeof ( cg_items ) ) ;
CG_LinkCentsToGents ( ) ;
if ( gbUseTheseValuesFromLoadSave )
{
gbUseTheseValuesFromLoadSave = qfalse ; // ack
cg . forcepowerSelect = gi_cg_forcepowerSelect ;
cg . inventorySelect = gi_cg_inventorySelect ;
}
// get the rendering configuration from the client system
cgi_GetGlconfig ( & cgs . glconfig ) ;
/* cgs.charScale = cgs.glconfig.vidHeight * (1.0/480.0);
if ( cgs . glconfig . vidWidth * 480 > cgs . glconfig . vidHeight * 640 ) {
// wide screen
cgs . bias = 0.5 * ( cgs . glconfig . vidWidth - ( cgs . glconfig . vidHeight * ( 640.0 / 480.0 ) ) ) ;
}
else {
// no wide screen
cgs . bias = 0 ;
}
*/
// get the gamestate from the client system
cgi_GetGameState ( & cgs . gameState ) ;
CG_ParseServerinfo ( ) ;
// load the new map
cgs . media . levelLoad = cgi_R_RegisterShaderNoMip ( " gfx/hud/mp_levelload " ) ;
CG_LoadingString ( " collision map " ) ;
cgi_CM_LoadMap ( cgs . mapname , qfalse ) ;
CG_RegisterSounds ( ) ;
CG_RegisterGraphics ( ) ;
//jfm: moved down to preinit
// CG_InitLocalEntities();
// CG_InitMarkPolys();
CG_LoadingString ( " music " ) ;
CG_StartMusic ( qfalse ) ;
// remove the last loading update
cg . infoScreenText [ 0 ] = 0 ;
CGCam_Init ( ) ;
CG_ClearLightStyles ( ) ;
// Okay so this doesn't exactly belong here
cg . messageLitActive = qfalse ;
cg . forceHUDActive = qtrue ;
cg . forceHUDTotalFlashTime = 0 ;
cg . forceHUDNextFlashTime = 0 ;
}
void CG_WriteTheEvilCGHackStuff ( )
{
ojk : : SavedGameHelper saved_game (
: : gi . saved_game ) ;
saved_game . write_chunk < int32_t > (
INT_ID ( ' F ' , ' P ' , ' S ' , ' L ' ) ,
: : cg . forcepowerSelect ) ;
saved_game . write_chunk < int32_t > (
INT_ID ( ' I ' , ' V ' , ' S ' , ' L ' ) ,
: : cg . inventorySelect ) ;
}
void CG_ReadTheEvilCGHackStuff ( )
{
ojk : : SavedGameHelper saved_game (
: : gi . saved_game ) ;
saved_game . read_chunk < int32_t > (
INT_ID ( ' F ' , ' P ' , ' S ' , ' L ' ) ,
: : gi_cg_forcepowerSelect ) ;
saved_game . read_chunk < int32_t > (
INT_ID ( ' I ' , ' V ' , ' S ' , ' L ' ) ,
: : gi_cg_inventorySelect ) ;
gbUseTheseValuesFromLoadSave = qtrue ;
}
/*
Ghoul2 Insert Start
*/
// initialise the cg_entities structure
void CG_Init_CG ( void )
{
memset ( & cg , 0 , sizeof ( cg ) ) ;
}
# define MAX_MISC_ENTS 2000
typedef struct cgMiscEntData_s
{
char model [ MAX_QPATH ] ;
qhandle_t hModel ;
vec3_t origin ;
vec3_t angles ;
vec3_t scale ;
float radius ;
float zOffset ; //some models need a z offset for culling, because of stupid wrong model origins
} cgMiscEntData_t ;
static cgMiscEntData_t MiscEnts [ MAX_MISC_ENTS ] ; //statically allocated for now.
static int NumMiscEnts = 0 ;
void CG_CreateMiscEntFromGent ( gentity_t * ent , const vec3_t scale , float zOff )
{ //store the model data
if ( NumMiscEnts = = MAX_MISC_ENTS )
{
Com_Error ( ERR_DROP , " Maximum misc_model_static reached (%d) \n " , MAX_MISC_ENTS ) ;
return ;
}
if ( ! ent | | ! ent - > model | | ! ent - > model [ 0 ] )
{
Com_Error ( ERR_DROP , " misc_model_static with no model. " ) ;
return ;
}
const size_t len = strlen ( ent - > model ) ;
if ( len < 4 | | Q_stricmp ( & ent - > model [ len - 4 ] , " .md3 " ) ! = 0 )
{
Com_Error ( ERR_DROP , " misc_model_static model(%s) is not an md3. " , ent - > model ) ;
return ;
}
cgMiscEntData_t * MiscEnt = & MiscEnts [ NumMiscEnts + + ] ;
memset ( MiscEnt , 0 , sizeof ( * MiscEnt ) ) ;
strcpy ( MiscEnt - > model , ent - > model ) ;
VectorCopy ( ent - > s . angles , MiscEnt - > angles ) ;
VectorCopy ( scale , MiscEnt - > scale ) ;
VectorCopy ( ent - > s . origin , MiscEnt - > origin ) ;
MiscEnt - > zOffset = zOff ;
}
# define VectorScaleVector(a,b,c) (((c)[0]=(a)[0]*(b)[0]),((c)[1]=(a)[1]*(b)[1]),((c)[2]=(a)[2]*(b)[2]))
//call on standard model load to spawn the queued stuff
void CG_CreateMiscEnts ( void )
{
vec3_t mins , maxs ;
int i ;
for ( i = 0 ; i < NumMiscEnts ; i + + )
{
cgMiscEntData_t * MiscEnt = & MiscEnts [ i ] ;
MiscEnt - > hModel = cgi_R_RegisterModel ( MiscEnt - > model ) ;
if ( MiscEnt - > hModel = = 0 )
{
Com_Error ( ERR_DROP , " misc_model_static failed to load model '%s' " , MiscEnt - > model ) ;
continue ;
}
cgi_R_ModelBounds ( MiscEnt - > hModel , mins , maxs ) ;
VectorScaleVector ( mins , MiscEnt - > scale , mins ) ;
VectorScaleVector ( maxs , MiscEnt - > scale , maxs ) ;
MiscEnt - > radius = DistanceSquared ( mins , maxs ) ;
}
}
void CG_DrawMiscEnts ( void )
{
int i ;
cgMiscEntData_t * MiscEnt = MiscEnts ;
refEntity_t refEnt ;
vec3_t difference ;
vec3_t cullOrigin ;
memset ( & refEnt , 0 , sizeof ( refEnt ) ) ;
refEnt . reType = RT_MODEL ;
refEnt . frame = 0 ;
refEnt . renderfx = RF_LIGHTING_ORIGIN ;
for ( i = 0 ; i < NumMiscEnts ; i + + )
{
VectorCopy ( MiscEnt - > origin , cullOrigin ) ;
cullOrigin [ 2 ] + = MiscEnt - > zOffset + 1.0f ;
if ( gi . inPVS ( cg . refdef . vieworg , cullOrigin ) )
{
VectorSubtract ( MiscEnt - > origin , cg . refdef . vieworg , difference ) ;
if ( VectorLengthSquared ( difference ) - ( MiscEnt - > radius ) < = 8192 * 8192 /*RMG_distancecull.value*/ )
{ //fixme: need access to the real cull dist here
refEnt . hModel = MiscEnt - > hModel ;
AnglesToAxis ( MiscEnt - > angles , refEnt . axis ) ;
VectorCopy ( MiscEnt - > scale , refEnt . modelScale ) ;
VectorCopy ( MiscEnt - > origin , refEnt . origin ) ;
VectorCopy ( cullOrigin , refEnt . lightingOrigin ) ;
ScaleModelAxis ( & refEnt ) ;
cgi_R_AddRefEntityToScene ( & refEnt ) ;
}
}
MiscEnt + + ;
}
}
void CG_TransitionPermanent ( void )
{
centity_t * cent = cg_entities ;
int i ;
cg_numpermanents = 0 ;
for ( i = 0 ; i < MAX_GENTITIES ; i + + , cent + + )
{
if ( cgi_GetDefaultState ( i , & cent - > currentState ) )
{
cent - > nextState = & cent - > currentState ;
VectorCopy ( cent - > currentState . origin , cent - > lerpOrigin ) ;
VectorCopy ( cent - > currentState . angles , cent - > lerpAngles ) ;
cent - > currentValid = qtrue ;
cg_permanents [ cg_numpermanents + + ] = cent ;
}
}
}
/*
Ghoul2 Insert End
*/
/*
= = = = = = = = = = = = = = = = =
CG_PreInit
Called when DLL loads ( after subsystem restart , but before gamestate is received )
= = = = = = = = = = = = = = = = =
*/
void CG_PreInit ( ) {
CG_Init_CG ( ) ;
memset ( & cgs , 0 , sizeof ( cgs ) ) ;
iCGResetCount = 0 ;
CG_RegisterCvars ( ) ;
//moved from CG_GameStateReceived because it's loaded sooner now
CG_InitLocalEntities ( ) ;
CG_InitMarkPolys ( ) ;
}
/*
= = = = = = = = = = = = = = = = =
CG_Init
Called after every level change or subsystem restart
= = = = = = = = = = = = = = = = =
*/
void CG_Init ( int serverCommandSequence ) {
cgs . serverCommandSequence = serverCommandSequence ;
cgi_Cvar_Set ( " cg_drawHUD " , " 1 " ) ;
// fonts...
//
cgs . media . charsetShader = cgi_R_RegisterShaderNoMip ( " gfx/2d/charsgrid_med " ) ;
cgs . media . qhFontSmall = cgi_R_RegisterFont ( " ocr_a " ) ;
cgs . media . qhFontMedium = cgi_R_RegisterFont ( " ergoec " ) ;
cgs . media . whiteShader = cgi_R_RegisterShader ( " white " ) ;
cgs . media . loadTick = cgi_R_RegisterShaderNoMip ( " gfx/hud/load_tick " ) ;
cgs . media . loadTickCap = cgi_R_RegisterShaderNoMip ( " gfx/hud/load_tick_cap " ) ;
const char * force_icon_files [ NUM_FORCE_POWERS ] =
{ //icons matching enums forcePowers_t
" gfx/mp/f_icon_lt_heal " , //FP_HEAL,
" gfx/mp/f_icon_levitation " , //FP_LEVITATION,
" gfx/mp/f_icon_speed " , //FP_SPEED,
" gfx/mp/f_icon_push " , //FP_PUSH,
" gfx/mp/f_icon_pull " , //FP_PULL,
" gfx/mp/f_icon_lt_telepathy " , //FP_TELEPATHY,
" gfx/mp/f_icon_dk_grip " , //FP_GRIP,
" gfx/mp/f_icon_dk_l1 " , //FP_LIGHTNING,
" gfx/mp/f_icon_saber_throw " , //FP_SABERTHROW
" gfx/mp/f_icon_saber_defend " , //FP_SABERDEFEND,
" gfx/mp/f_icon_saber_attack " , //FP_SABERATTACK,
" gfx/mp/f_icon_dk_rage " , //FP_RAGE,
" gfx/mp/f_icon_lt_protect " , //FP_PROTECT,
" gfx/mp/f_icon_lt_absorb " , //FP_ABSORB,
" gfx/mp/f_icon_dk_drain " , //FP_DRAIN,
" gfx/mp/f_icon_sight " , //FP_SEE,
} ;
// Precache inventory icons
for ( int i = 0 ; i < NUM_FORCE_POWERS ; i + + )
{
if ( force_icon_files [ i ] )
{
force_icons [ i ] = cgi_R_RegisterShaderNoMip ( force_icon_files [ i ] ) ;
}
}
CG_LoadHudMenu ( ) ; // load new hud stuff
cgi_UI_Menu_OpenByName ( " loadscreen " ) ;
//rww - Moved from CG_GameStateReceived (we don't want to clear perm ents)
memset ( cg_entities , 0 , sizeof ( cg_entities ) ) ;
CG_TransitionPermanent ( ) ;
cg . loadLCARSStage = 0 ;
CG_GameStateReceived ( ) ;
CG_InitConsoleCommands ( ) ;
cg . weaponPickupTextTime = 0 ;
cg . missionInfoFlashTime = 0 ;
cg . missionStatusShow = qfalse ;
cg . missionFailedScreen = qfalse ; // Screen hasn't been opened.
cgi_UI_MenuCloseAll ( ) ; // So the loadscreen menu will turn off just after the opening snapshot
}
/*
= = = = = = = = = = = = = = = = =
CG_Shutdown
Called before every level change or subsystem restart
= = = = = = = = = = = = = = = = =
*/
void CG_Shutdown ( void )
{
in_camera = false ;
FX_Free ( ) ;
}
//// DEBUG STUFF
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
CG_DrawNode
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
void CG_DrawNode ( vec3_t origin , int type )
{
localEntity_t * ex ;
ex = CG_AllocLocalEntity ( ) ;
ex - > leType = LE_SPRITE ;
ex - > startTime = cg . time ;
ex - > endTime = ex - > startTime + 51 ;
VectorCopy ( origin , ex - > refEntity . origin ) ;
ex - > refEntity . customShader = cgi_R_RegisterShader ( " gfx/misc/nav_node " ) ;
float scale = 16.0f ;
switch ( type )
{
case NODE_NORMAL :
ex - > color [ 0 ] = 255 ;
ex - > color [ 1 ] = 255 ;
ex - > color [ 2 ] = 0 ;
break ;
case NODE_FLOATING :
ex - > color [ 0 ] = 0 ;
ex - > color [ 1 ] = 255 ;
ex - > color [ 2 ] = 255 ;
scale + = 16.0f ;
break ;
case NODE_GOAL :
ex - > color [ 0 ] = 255 ;
ex - > color [ 1 ] = 0 ;
ex - > color [ 2 ] = 0 ;
scale + = 16.0f ;
break ;
case NODE_NAVGOAL :
ex - > color [ 0 ] = 0 ;
ex - > color [ 1 ] = 255 ;
ex - > color [ 2 ] = 0 ;
break ;
}
ex - > radius = scale ;
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
CG_DrawRadius
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
void CG_DrawRadius ( vec3_t origin , unsigned int radius , int type )
{
localEntity_t * ex ;
ex = CG_AllocLocalEntity ( ) ;
ex - > leType = LE_QUAD ;
ex - > radius = radius ;
ex - > startTime = cg . time ;
ex - > endTime = ex - > startTime + 51 ;
VectorCopy ( origin , ex - > refEntity . origin ) ;
ex - > refEntity . customShader = cgi_R_RegisterShader ( " gfx/misc/nav_radius " ) ;
switch ( type )
{
case NODE_NORMAL :
ex - > color [ 0 ] = 255 ;
ex - > color [ 1 ] = 255 ;
ex - > color [ 2 ] = 0 ;
break ;
case NODE_FLOATING :
ex - > color [ 0 ] = 0 ;
ex - > color [ 1 ] = 255 ;
ex - > color [ 2 ] = 255 ;
break ;
case NODE_GOAL :
ex - > color [ 0 ] = 255 ;
ex - > color [ 1 ] = 0 ;
ex - > color [ 2 ] = 0 ;
break ;
case NODE_NAVGOAL :
ex - > color [ 0 ] = 0 ;
ex - > color [ 1 ] = 255 ;
ex - > color [ 2 ] = 0 ;
break ;
}
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
CG_DrawEdge
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
void CG_DrawEdge ( vec3_t start , vec3_t end , int type )
{
switch ( type )
{
// NAVIGATION EDGES BETWEEN POINTS
//=====================================
case EDGE_NORMAL :
{
FX_AddLine ( start , end , 8.0f , 4.0f , 0.0f , 0.5f , 0.5f , 51 , cgi_R_RegisterShader ( " gfx/misc/nav_line " ) , 0 ) ;
}
break ;
case EDGE_LARGE :
{
FX_AddLine ( start , end , 8.0f , 15.0f , 0.0f , 0.5f , 0.5f , 51 , cgi_R_RegisterShader ( " gfx/misc/nav_line " ) , 0 ) ;
}
break ;
case EDGE_BLOCKED :
{
vec3_t color = { 255 , 0 , 0 } ; // RED
FX_AddLine ( start , end , 8.0f , 4.0f , 0.0f , 0.5f , 0.5f , color , color , 51 , cgi_R_RegisterShader ( " gfx/misc/nav_line " ) , 0 ) ;
}
break ;
case EDGE_FLY :
{
vec3_t color = { 0 , 255 , 255 } ; // GREEN
FX_AddLine ( start , end , 8.0f , 4.0f , 0.0f , 0.5f , 0.5f , color , color , 51 , cgi_R_RegisterShader ( " gfx/misc/nav_line " ) , 0 ) ;
}
break ;
case EDGE_JUMP :
{
vec3_t color = { 0 , 0 , 255 } ; // BLUE
FX_AddLine ( start , end , 8.0f , 4.0f , 0.0f , 0.5f , 0.5f , color , color , 51 , cgi_R_RegisterShader ( " gfx/misc/nav_line " ) , 0 ) ;
}
break ;
// EDGE NODES
//=====================================
case EDGE_NODE_NORMAL :
{
vec3_t color = { 155 , 155 , 155 } ;
FX_AddLine ( start , end , 2.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
case EDGE_NODE_FLOATING :
{
vec3_t color = { 155 , 155 , 0 } ;
FX_AddLine ( start , end , 2.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
case EDGE_NODE_GOAL :
{
vec3_t color = { 0 , 0 , 155 } ;
FX_AddLine ( start , end , 2.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
case EDGE_NODE_COMBAT :
{
vec3_t color = { 155 , 0 , 0 } ;
FX_AddLine ( start , end , 2.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
// NEAREST NAV
//=====================================
case EDGE_NEARESTVALID :
{
vec3_t color = { 155 , 155 , 155 } ; // WHITE
FX_AddLine ( - 1 , start , end , 1.0f , 1.0f , 0 , 1.0f , 1.0f , FX_ALPHA_LINEAR , color , color , 0 , 51 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 , 0 ) ;
}
break ;
case EDGE_NEARESTINVALID :
{
vec3_t color = { 155 , 0 , 0 } ; // WHITE
FX_AddLine ( - 1 , start , end , 1.0f , 1.0f , 0 , 1.0f , 1.0f , FX_ALPHA_LINEAR , color , color , 0 , 51 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 , 0 ) ;
}
break ;
// NEAREST NAV CELLS
//=====================================
case EDGE_CELL :
{
vec3_t color = { 155 , 155 , 155 } ; // WHITE
FX_AddLine ( - 1 , start , end , 1.0f , 1.0f , 0 , 1.0f , 1.0f , FX_ALPHA_LINEAR , color , color , 0 , 51 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 , 0 ) ;
}
break ;
case EDGE_CELL_EMPTY :
{
vec3_t color = { 255 , 0 , 0 } ; // RED
FX_AddLine ( - 1 , start , end , 1.0f , 1.0f , 0 , 1.0f , 1.0f , FX_ALPHA_LINEAR , color , color , 0 , 51 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 , 0 ) ;
}
break ;
// ACTOR PATHS
//=============
case EDGE_PATH :
{
vec3_t color = { 0 , 0 , 155 } ; // WHITE
FX_AddLine ( start , end , 5.0f , 5.0f , 0.0f , 0.5f , 0.5f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/nav_arrow_new " ) , 0 ) ;
}
break ;
case EDGE_PATHBLOCKED :
{
vec3_t color = { 255 , 0 , 0 } ; // RED
FX_AddLine ( start , end , 5.0f , 5.0f , 0.0f , 0.5f , 0.5f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/nav_arrow_new " ) , 0 ) ;
break ;
}
case EDGE_FOLLOWPOS :
{
vec3_t color = { 0 , 255 , 0 } ; // GREEN
FX_AddLine ( start , end , 5.0f , 5.0f , 0.0f , 0.5f , 0.5f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/nav_arrow_new " ) , 0 ) ;
break ;
}
// STEERING
//=====================================
case EDGE_IMPACT_SAFE :
{
vec3_t color = { 155 , 155 , 155 } ; // WHITE
FX_AddLine ( start , end , 2.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
case EDGE_IMPACT_POSSIBLE :
{
vec3_t color = { 255 , 0 , 0 } ; // RED
FX_AddLine ( start , end , 2.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
case EDGE_VELOCITY :
{
vec3_t color = { 0 , 255 , 0 } ; // GREEN
FX_AddLine ( start , end , 4.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
case EDGE_THRUST :
{
vec3_t color = { 0 , 0 , 255 } ; // BLUE
FX_AddLine ( start , end , 3.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 151 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
// MISC Colored Lines
//=====================================
case EDGE_WHITE_ONESECOND :
{
vec3_t color = { 155 , 155 , 155 } ; // WHITE
FX_AddLine ( start , end , 3.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 1051 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
case EDGE_WHITE_TWOSECOND :
{
vec3_t color = { 155 , 155 , 155 } ; // WHITE
FX_AddLine ( start , end , 3.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 1051 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
case EDGE_RED_ONESECOND :
{
vec3_t color = { 255 , 0 , 0 } ; // RED
FX_AddLine ( start , end , 3.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 2051 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
case EDGE_RED_TWOSECOND :
{
vec3_t color = { 255 , 0 , 0 } ; // RED
FX_AddLine ( start , end , 3.0f , 1.0f , 0.0f , 1.0f , 1.0f , color , color , 2051 , cgi_R_RegisterShader ( " gfx/misc/whiteline2 " ) , 0 ) ;
}
break ;
default :
break ;
}
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
CG_DrawCombatPoint
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
void CG_DrawCombatPoint ( vec3_t origin , int type )
{
localEntity_t * ex ;
ex = CG_AllocLocalEntity ( ) ;
ex - > leType = LE_SPRITE ;
ex - > startTime = cg . time ;
ex - > radius = 8 ;
ex - > endTime = ex - > startTime + 51 ;
VectorCopy ( origin , ex - > refEntity . origin ) ;
ex - > refEntity . customShader = cgi_R_RegisterShader ( " gfx/misc/nav_cpoint " ) ;
ex - > color [ 0 ] = 255 ;
ex - > color [ 1 ] = 0 ;
ex - > color [ 2 ] = 255 ;
/*
switch ( type )
{
case 0 : //FIXME: To shut up the compiler warning (more will be added here later of course)
default :
FX_AddSprite ( origin , NULL , NULL , 8.0f , 0.0f , 1.0f , 1.0f , color , color , 0.0f , 0.0f , 51 , cgi_R_RegisterShader ( " gfx/misc/nav_cpoint " ) ) ;
break ;
}
*/
}
/*
- - - - - - - - - - - - - - - - - - - - - - - - -
CG_DrawAlert
- - - - - - - - - - - - - - - - - - - - - - - - -
*/
void CG_DrawAlert ( vec3_t origin , float rating )
{
vec3_t drawPos ;
VectorCopy ( origin , drawPos ) ;
drawPos [ 2 ] + = 48 ;
vec3_t startRGB ;
//Fades from green at 0, to red at 1
startRGB [ 0 ] = rating ;
startRGB [ 1 ] = 1 - rating ;
startRGB [ 2 ] = 0 ;
FX_AddSprite ( drawPos , NULL , NULL , 16 , 0.0f , 1.0f , 1.0f , startRGB , startRGB , 0 , 0 , 50 , cgs . media . whiteShader ) ;
}
# define MAX_MENUDEFFILE 4096
//
// ==============================
// new hud stuff ( mission pack )
// ==============================
//
qboolean CG_Asset_Parse ( const char * * p )
{
const char * token ;
const char * tempStr ;
int pointSize ;
token = COM_ParseExt ( p , qtrue ) ;
if ( ! token )
{
return qfalse ;
}
if ( Q_stricmp ( token , " { " ) ! = 0 )
{
return qfalse ;
}
while ( 1 )
{
token = COM_ParseExt ( p , qtrue ) ;
if ( ! token )
{
return qfalse ;
}
if ( Q_stricmp ( token , " } " ) = = 0 )
{
return qtrue ;
}
// font
if ( Q_stricmp ( token , " font " ) = = 0 )
{
/*
int pointSize ;
cgi_UI_Parse_String ( tempStr ) ;
cgi_UI_Parse_Int ( & pointSize ) ;
if ( ! tempStr | | ! pointSize )
{
return qfalse ;
}
*/
// cgDC.registerFont(tempStr, pointSize, &cgDC.Assets.textFont);
continue ;
}
// smallFont
if ( Q_stricmp ( token , " smallFont " ) = = 0 )
{
if ( ! COM_ParseString ( p , & tempStr ) | | ! COM_ParseInt ( p , & pointSize ) )
{
return qfalse ;
}
// cgDC.registerFont(tempStr, pointSize, &cgDC.Assets.smallFont);
continue ;
}
// smallFont - because the HUD file needs it for MP.
if ( Q_stricmp ( token , " small2Font " ) = = 0 )
{
if ( ! COM_ParseString ( p , & tempStr ) | | ! COM_ParseInt ( p , & pointSize ) )
{
return qfalse ;
}
// cgDC.registerFont(tempStr, pointSize, &cgDC.Assets.smallFont);
continue ;
}
// font
if ( Q_stricmp ( token , " bigfont " ) = = 0 )
{
int pointSize ;
if ( ! COM_ParseString ( p , & tempStr ) | | ! COM_ParseInt ( p , & pointSize ) )
{
return qfalse ;
}
// cgDC.registerFont(tempStr, pointSize, &cgDC.Assets.bigFont);
continue ;
}
// gradientbar
if ( Q_stricmp ( token , " gradientbar " ) = = 0 )
{
if ( ! COM_ParseString ( p , & tempStr ) )
{
return qfalse ;
}
// cgDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(tempStr);
continue ;
}
// enterMenuSound
if ( Q_stricmp ( token , " menuEnterSound " ) = = 0 )
{
if ( ! COM_ParseString ( p , & tempStr ) )
{
return qfalse ;
}
// cgDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr );
continue ;
}
// exitMenuSound
if ( Q_stricmp ( token , " menuExitSound " ) = = 0 )
{
if ( ! COM_ParseString ( p , & tempStr ) )
{
return qfalse ;
}
// cgDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr );
continue ;
}
// itemFocusSound
if ( Q_stricmp ( token , " itemFocusSound " ) = = 0 )
{
if ( ! COM_ParseString ( p , & tempStr ) )
{
return qfalse ;
}
// cgDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr );
continue ;
}
// menuBuzzSound
if ( Q_stricmp ( token , " menuBuzzSound " ) = = 0 )
{
if ( ! COM_ParseString ( p , & tempStr ) )
{
return qfalse ;
}
// cgDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr );
continue ;
}
if ( Q_stricmp ( token , " cursor " ) = = 0 )
{
// if (!COM_ParseString(p, &cgDC.Assets.cursorStr))
// {
// return qfalse;
// }
// cgDC.Assets.cursor = trap_R_RegisterShaderNoMip( cgDC.Assets.cursorStr);
continue ;
}
if ( Q_stricmp ( token , " fadeClamp " ) = = 0 )
{
// if (!COM_ParseFloat(p, &cgDC.Assets.fadeClamp))
// {
// return qfalse;
// }
continue ;
}
if ( Q_stricmp ( token , " fadeCycle " ) = = 0 )
{
// if (!COM_ParseInt(p, &cgDC.Assets.fadeCycle))
// {
// return qfalse;
// }
continue ;
}
if ( Q_stricmp ( token , " fadeAmount " ) = = 0 )
{
// if (!COM_ParseFloat(p, &cgDC.Assets.fadeAmount))
// {
// return qfalse;
// }
continue ;
}
if ( Q_stricmp ( token , " shadowX " ) = = 0 )
{
// if (!COM_ParseFloat(p, &cgDC.Assets.shadowX))
// {
// return qfalse;
// }
continue ;
}
if ( Q_stricmp ( token , " shadowY " ) = = 0 )
{
// if (!COM_ParseFloat(p, &cgDC.Assets.shadowY))
// {
// return qfalse;
// }
continue ;
}
if ( Q_stricmp ( token , " shadowColor " ) = = 0 )
{
/*
if ( ! PC_Color_Parse ( handle , & cgDC . Assets . shadowColor ) )
{
return qfalse ;
}
cgDC . Assets . shadowFadeClamp = cgDC . Assets . shadowColor [ 3 ] ;
*/
continue ;
}
}
return qfalse ; // bk001204 - why not?
}
void cgi_UI_EndParseSession ( char * buf ) ;
/*
= = = = = = = = = = = = = = = = =
CG_ParseMenu ( ) ;
= = = = = = = = = = = = = = = = =
*/
void CG_ParseMenu ( const char * menuFile )
{
char * token ;
int result ;
char * buf , * p ;
//Com_Printf("Parsing menu file:%s\n", menuFile);
result = cgi_UI_StartParseSession ( ( char * ) menuFile , & buf ) ;
if ( ! result )
{
Com_Printf ( " Unable to load hud menu file:%s. Using default ui/testhud.menu. \n " , menuFile ) ;
result = cgi_UI_StartParseSession ( " ui/testhud.menu " , & buf ) ;
if ( ! result )
{
Com_Printf ( " Unable to load default ui/testhud.menu. \n " ) ;
cgi_UI_EndParseSession ( buf ) ;
return ;
}
}
p = buf ;
while ( 1 )
{
cgi_UI_ParseExt ( & token ) ;
if ( ! * token ) // All done?
{
break ;
}
//if ( Q_stricmp( token, "{" ) ) {
// Com_Printf( "Missing { in menu file\n" );
// break;
//}
//if ( menuCount == MAX_MENUS ) {
// Com_Printf( "Too many menus!\n" );
// break;
//}
// if ( *token == '}' )
// {
// break;
// }
if ( Q_stricmp ( token , " assetGlobalDef " ) = = 0 )
{
/*
if ( CG_Asset_Parse ( handle ) )
{
continue ;
}
else
{
break ;
}
*/
}
if ( Q_stricmp ( token , " menudef " ) = = 0 )
{
// start a new menu
cgi_UI_Menu_New ( p ) ;
}
}
cgi_UI_EndParseSession ( buf ) ;
}
/*
= = = = = = = = = = = = = = = = =
CG_Load_Menu ( ) ;
= = = = = = = = = = = = = = = = =
*/
qboolean CG_Load_Menu ( const char * * p )
{
const char * token ;
token = COM_ParseExt ( p , qtrue ) ;
if ( token [ 0 ] ! = ' { ' )
{
return qfalse ;
}
while ( 1 )
{
token = COM_ParseExt ( p , qtrue ) ;
if ( Q_stricmp ( token , " } " ) = = 0 )
{
return qtrue ;
}
if ( ! token | | token [ 0 ] = = 0 )
{
return qfalse ;
}
CG_ParseMenu ( token ) ;
}
return qfalse ;
}
/*
= = = = = = = = = = = = = = = = =
CG_LoadMenus ( ) ;
= = = = = = = = = = = = = = = = =
*/
void CG_LoadMenus ( const char * menuFile )
{
const char * token ;
const char * p ;
int len /*, start*/ ;
fileHandle_t f ;
char buf [ MAX_MENUDEFFILE ] ;
//start = cgi_Milliseconds();
len = cgi_FS_FOpenFile ( menuFile , & f , FS_READ ) ;
if ( ! f )
{
if ( Q_isanumber ( menuFile ) ) // cg_hudFiles 1
CG_Printf ( S_COLOR_GREEN " hud menu file skipped, using default \n " ) ;
else
CG_Printf ( S_COLOR_YELLOW " hud menu file not found: %s, using default \n " , menuFile ) ;
len = cgi_FS_FOpenFile ( " ui/jahud.txt " , & f , FS_READ ) ;
if ( ! f )
{
cgi_Error ( S_COLOR_RED " default menu file not found: ui/hud.txt, unable to continue! \n " ) ;
}
}
if ( len > = MAX_MENUDEFFILE )
{
cgi_FS_FCloseFile ( f ) ;
cgi_Error ( va ( S_COLOR_RED " menu file too large: %s is %i, max allowed is %i " , menuFile , len , MAX_MENUDEFFILE ) ) ;
return ;
}
cgi_FS_Read ( buf , len , f ) ;
buf [ len ] = 0 ;
cgi_FS_FCloseFile ( f ) ;
// COM_Compress(buf);
// cgi_UI_Menu_Reset();
p = buf ;
COM_BeginParseSession ( ) ;
while ( 1 )
{
token = COM_ParseExt ( & p , qtrue ) ;
if ( ! token | | token [ 0 ] = = 0 | | token [ 0 ] = = ' } ' )
{
break ;
}
if ( Q_stricmp ( token , " } " ) = = 0 )
{
break ;
}
if ( Q_stricmp ( token , " loadmenu " ) = = 0 )
{
if ( CG_Load_Menu ( & p ) )
{
continue ;
}
else
{
break ;
}
}
}
COM_EndParseSession ( ) ;
//Com_Printf("UI menu load time = %d milli seconds\n", cgi_Milliseconds() - start);
}
/*
= = = = = = = = = = = = = = = = =
CG_LoadHudMenu ( ) ;
= = = = = = = = = = = = = = = = =
*/
void CG_LoadHudMenu ( void )
{
const char * hudSet ;
/*
cgDC . registerShaderNoMip = & trap_R_RegisterShaderNoMip ;
cgDC . setColor = & trap_R_SetColor ;
cgDC . drawHandlePic = & CG_DrawPic ;
cgDC . drawStretchPic = & trap_R_DrawStretchPic ;
cgDC . drawText = & CG_Text_Paint ;
cgDC . textWidth = & CG_Text_Width ;
cgDC . textHeight = & CG_Text_Height ;
cgDC . registerModel = & trap_R_RegisterModel ;
cgDC . modelBounds = & trap_R_ModelBounds ;
cgDC . fillRect = & CG_FillRect ;
cgDC . drawRect = & CG_DrawRect ;
cgDC . drawSides = & CG_DrawSides ;
cgDC . drawTopBottom = & CG_DrawTopBottom ;
cgDC . clearScene = & trap_R_ClearScene ;
cgDC . addRefEntityToScene = & trap_R_AddRefEntityToScene ;
cgDC . renderScene = & trap_R_RenderScene ;
cgDC . registerFont = & trap_R_RegisterFont ;
cgDC . ownerDrawItem = & CG_OwnerDraw ;
cgDC . getValue = & CG_GetValue ;
cgDC . ownerDrawVisible = & CG_OwnerDrawVisible ;
cgDC . runScript = & CG_RunMenuScript ;
cgDC . getTeamColor = & CG_GetTeamColor ;
cgDC . setCVar = trap_Cvar_Set ;
cgDC . getCVarString = trap_Cvar_VariableStringBuffer ;
cgDC . getCVarValue = CG_Cvar_Get ;
cgDC . drawTextWithCursor = & CG_Text_PaintWithCursor ;
cgDC . startLocalSound = & trap_S_StartLocalSound ;
cgDC . ownerDrawHandleKey = & CG_OwnerDrawHandleKey ;
cgDC . feederCount = & CG_FeederCount ;
cgDC . feederItemImage = & CG_FeederItemImage ;
cgDC . feederItemText = & CG_FeederItemText ;
cgDC . feederSelection = & CG_FeederSelection ;
cgDC . Error = & Com_Error ;
cgDC . Print = & Com_Printf ;
cgDC . ownerDrawWidth = & CG_OwnerDrawWidth ;
cgDC . registerSound = & trap_S_RegisterSound ;
cgDC . startBackgroundTrack = & trap_S_StartBackgroundTrack ;
cgDC . stopBackgroundTrack = & trap_S_StopBackgroundTrack ;
cgDC . playCinematic = & CG_PlayCinematic ;
cgDC . stopCinematic = & CG_StopCinematic ;
cgDC . drawCinematic = & CG_DrawCinematic ;
cgDC . runCinematicFrame = & CG_RunCinematicFrame ;
*/
// Init_Display(&cgDC);
// cgi_UI_String_Init();
// cgi_UI_Menu_Reset();
hudSet = cg_hudFiles . string ;
if ( hudSet [ 0 ] = = ' \0 ' )
{
hudSet = " ui/jahud.txt " ;
}
CG_LoadMenus ( hudSet ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
INVENTORY SELECTION
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = =
CG_InventorySelectable
= = = = = = = = = = = = = = =
*/
static inline qboolean CG_InventorySelectable ( int index )
{
if ( cg . snap - > ps . inventory [ index ] ) // Is there any in the inventory?
{
return qtrue ;
}
return qfalse ;
}
/*
= = = = = = = = = = = = = = =
SetInventoryTime
= = = = = = = = = = = = = = =
*/
static inline void SetInventoryTime ( void )
{
if ( ( ( cg . weaponSelectTime + WEAPON_SELECT_TIME ) > cg . time ) | | // The Weapon HUD was currently active to just swap it out with Force HUD
( ( cg . forcepowerSelectTime + WEAPON_SELECT_TIME ) > cg . time ) ) // The Force HUD was currently active to just swap it out with Force HUD
{
cg . weaponSelectTime = 0 ;
cg . forcepowerSelectTime = 0 ;
cg . inventorySelectTime = cg . time + 130.0f ;
}
else
{
cg . inventorySelectTime = cg . time ;
}
}
/*
= = = = = = = = = = = = = = =
CG_DPPrevInventory_f
= = = = = = = = = = = = = = =
*/
void CG_DPPrevInventory_f ( void )
{
int i ;
if ( ! cg . snap )
{
return ;
}
const int original = cg . DataPadInventorySelect ;
for ( i = 0 ; i < INV_MAX ; i + + )
{
cg . DataPadInventorySelect - - ;
if ( ( cg . DataPadInventorySelect < INV_ELECTROBINOCULARS ) | | ( cg . DataPadInventorySelect > = INV_MAX ) )
{
cg . DataPadInventorySelect = ( INV_MAX - 1 ) ;
}
if ( CG_InventorySelectable ( cg . DataPadInventorySelect ) )
{
return ;
}
}
cg . DataPadInventorySelect = original ;
}
/*
= = = = = = = = = = = = = = =
CG_DPNextInventory_f
= = = = = = = = = = = = = = =
*/
void CG_DPNextInventory_f ( void )
{
int i ;
if ( ! cg . snap )
{
return ;
}
const int original = cg . DataPadInventorySelect ;
for ( i = 0 ; i < INV_MAX ; i + + )
{
cg . DataPadInventorySelect + + ;
if ( ( cg . DataPadInventorySelect < INV_ELECTROBINOCULARS ) | | ( cg . DataPadInventorySelect > = INV_MAX ) )
{
cg . DataPadInventorySelect = INV_ELECTROBINOCULARS ;
}
if ( CG_InventorySelectable ( cg . DataPadInventorySelect ) & & ( inv_icons [ cg . DataPadInventorySelect ] ) )
{
return ;
}
}
cg . DataPadInventorySelect = original ;
}
/*
= = = = = = = = = = = = = = =
CG_NextInventory_f
= = = = = = = = = = = = = = =
*/
void CG_NextInventory_f ( void )
{
int i ;
float * color ;
if ( ! cg . snap )
{
return ;
}
// The first time it's been hit so just show inventory but don't advance in inventory.
color = CG_FadeColor ( cg . inventorySelectTime , WEAPON_SELECT_TIME ) ;
if ( ! color )
{
SetInventoryTime ( ) ;
return ;
}
const int original = cg . inventorySelect ;
for ( i = 0 ; i < INV_MAX ; i + + )
{
cg . inventorySelect + + ;
if ( ( cg . inventorySelect < INV_ELECTROBINOCULARS ) | | ( cg . inventorySelect > = INV_MAX ) )
{
cg . inventorySelect = INV_ELECTROBINOCULARS ;
}
if ( CG_InventorySelectable ( cg . inventorySelect ) & & ( inv_icons [ cg . inventorySelect ] ) )
{
cgi_S_StartSound ( NULL , 0 , CHAN_AUTO , cgs . media . selectSound2 ) ;
SetInventoryTime ( ) ;
return ;
}
}
cg . inventorySelect = original ;
}
/*
= = = = = = = = = = = = = = =
CG_UseInventory_f
= = = = = = = = = = = = = = =
*/
/*
this func was moved to Cmd_UseInventory_f in g_cmds . cpp
*/
/*
= = = = = = = = = = = = = = =
CG_PrevInventory_f
= = = = = = = = = = = = = = =
*/
void CG_PrevInventory_f ( void )
{
int i ;
float * color ;
if ( ! cg . snap )
{
return ;
}
// The first time it's been hit so just show inventory but don't advance in inventory.
color = CG_FadeColor ( cg . inventorySelectTime , WEAPON_SELECT_TIME ) ;
if ( ! color )
{
SetInventoryTime ( ) ;
return ;
}
const int original = cg . inventorySelect ;
for ( i = 0 ; i < INV_MAX ; i + + )
{
cg . inventorySelect - - ;
if ( ( cg . inventorySelect < INV_ELECTROBINOCULARS ) | | ( cg . inventorySelect > = INV_MAX ) )
{
cg . inventorySelect = ( INV_MAX - 1 ) ;
}
if ( CG_InventorySelectable ( cg . inventorySelect ) & & ( inv_icons [ cg . inventorySelect ] ) )
{
cgi_S_StartSound ( NULL , 0 , CHAN_AUTO , cgs . media . selectSound2 ) ;
SetInventoryTime ( ) ;
return ;
}
}
cg . inventorySelect = original ;
}
/*
= = = = = = = = = = = = = = = = = = =
FindInventoryItemTag
= = = = = = = = = = = = = = = = = = =
*/
gitem_t * FindInventoryItemTag ( int tag )
{
int i ;
for ( i = 1 ; i < bg_numItems ; i + + )
{
if ( bg_itemlist [ i ] . giTag = = tag & & bg_itemlist [ i ] . giType = = IT_HOLDABLE ) // I guess giTag's aren't unique amongst items..must also make sure it's a holdable
{
return & bg_itemlist [ i ] ;
}
}
return ( 0 ) ;
}
/*
= = = = = = = = = = = = = = = = = = =
CG_DrawInventorySelect
= = = = = = = = = = = = = = = = = = =
*/
void CG_DrawInventorySelect ( void )
{
int i ;
int holdCount , iconCnt ;
int sideLeftIconCnt , sideRightIconCnt ;
int count ;
int holdX ;
//int height;
// int tag;
float addX ;
vec4_t textColor = { .312f , .75f , .621f , 1.0f } ;
char text [ 1024 ] = { 0 } ;
// don't display if dead
if ( cg . predicted_player_state . stats [ STAT_HEALTH ] < = 0 | | ( cg . snap - > ps . viewEntity > 0 & & cg . snap - > ps . viewEntity < ENTITYNUM_WORLD ) )
{
return ;
}
if ( ( cg . inventorySelectTime + WEAPON_SELECT_TIME ) < cg . time ) // Time is up for the HUD to display
{
return ;
}
int x2 , y2 , w2 , h2 ;
if ( ! cgi_UI_GetMenuInfo ( " inventoryselecthud " , & x2 , & y2 , & w2 , & h2 ) )
{
return ;
}
cg . iconSelectTime = cg . inventorySelectTime ;
// showing weapon select clears pickup item display, but not the blend blob
cg . itemPickupTime = 0 ;
// count the number of items owned
count = 0 ;
for ( i = 0 ; i < INV_MAX ; i + + )
{
if ( CG_InventorySelectable ( i ) & & inv_icons [ i ] )
{
count + + ;
}
}
if ( ! count )
{
cgi_SP_GetStringTextString ( " SP_INGAME_EMPTY_INV " , text , sizeof ( text ) ) ;
int w = cgi_R_Font_StrLenPixels ( text , cgs . media . qhFontSmall , 1.0f ) ;
int x = ( SCREEN_WIDTH - w ) / 2 ;
CG_DrawProportionalString ( x , y2 + 22 , text , CG_CENTER | CG_SMALLFONT , colorTable [ CT_ICON_BLUE ] ) ;
return ;
}
const int sideMax = 3 ; // Max number of icons on the side
// Calculate how many icons will appear to either side of the center one
holdCount = count - 1 ; // -1 for the center icon
if ( holdCount = = 0 ) // No icons to either side
{
sideLeftIconCnt = 0 ;
sideRightIconCnt = 0 ;
}
else if ( count > ( 2 * sideMax ) ) // Go to the max on each side
{
sideLeftIconCnt = sideMax ;
sideRightIconCnt = sideMax ;
}
else // Less than max, so do the calc
{
sideLeftIconCnt = holdCount / 2 ;
sideRightIconCnt = holdCount - sideLeftIconCnt ;
}
i = cg . inventorySelect - 1 ;
if ( i < 0 )
{
i = INV_MAX - 1 ;
}
const int smallIconSize = 40 ;
const int bigIconSize = 80 ;
const int pad = 16 ;
const int x = 320 ;
const int y = 410 ;
// Left side ICONS
// Work backwards from current icon
holdX = x - ( ( bigIconSize / 2 ) + pad + smallIconSize ) ;
//height = smallIconSize * cg.iconHUDPercent;
addX = ( float ) smallIconSize * .75 ;
for ( iconCnt = 0 ; iconCnt < sideLeftIconCnt ; i - - )
{
if ( i < 0 )
{
i = INV_MAX - 1 ;
}
if ( ( ! CG_InventorySelectable ( i ) ) | | ( ! inv_icons [ i ] ) )
{
continue ;
}
+ + iconCnt ; // Good icon
if ( inv_icons [ i ] )
{
cgi_R_SetColor ( NULL ) ;
CG_DrawPic ( holdX , y + 10 , smallIconSize , smallIconSize , inv_icons [ i ] ) ;
cgi_R_SetColor ( colorTable [ CT_ICON_BLUE ] ) ;
CG_DrawNumField ( holdX + addX , y + smallIconSize , 2 , cg . snap - > ps . inventory [ i ] , 6 , 12 ,
NUM_FONT_SMALL , qfalse ) ;
holdX - = ( smallIconSize + pad ) ;
}
}
// Current Center Icon
//height = bigIconSize * cg.iconHUDPercent;
if ( inv_icons [ cg . inventorySelect ] )
{
cgi_R_SetColor ( NULL ) ;
CG_DrawPic ( x - ( bigIconSize / 2 ) , ( y - ( ( bigIconSize - smallIconSize ) / 2 ) ) + 10 , bigIconSize , bigIconSize , inv_icons [ cg . inventorySelect ] ) ;
addX = ( float ) bigIconSize * .75 ;
cgi_R_SetColor ( colorTable [ CT_ICON_BLUE ] ) ;
CG_DrawNumField ( ( x - ( bigIconSize / 2 ) ) + addX , y , 2 , cg . snap - > ps . inventory [ cg . inventorySelect ] , 6 , 12 ,
NUM_FONT_SMALL , qfalse ) ;
if ( inv_names [ cg . inventorySelect ] )
{
// FIXME: This is ONLY a temp solution, the icon stuff, etc, should all just use items.dat for everything
gitem_t * item = FindInventoryItemTag ( cg . inventorySelect ) ;
if ( item & & item - > classname & & item - > classname [ 0 ] )
{
char itemName [ 256 ] , data [ 1024 ] ; // FIXME: do these really need to be this large?? does it matter?
Com_sprintf ( itemName , sizeof ( itemName ) , " SP_INGAME_%s " , item - > classname ) ;
if ( cgi_SP_GetStringTextString ( itemName , data , sizeof ( data ) ) )
{
int w = cgi_R_Font_StrLenPixels ( data , cgs . media . qhFontSmall , 1.0f ) ;
int x = ( SCREEN_WIDTH - w ) / 2 ;
cgi_R_Font_DrawString ( x , ( SCREEN_HEIGHT - 24 ) , data , textColor , cgs . media . qhFontSmall , - 1 , 1.0f ) ;
}
}
}
}
i = cg . inventorySelect + 1 ;
if ( i > INV_MAX - 1 )
{
i = 0 ;
}
// Right side ICONS
// Work forwards from current icon
holdX = x + ( bigIconSize / 2 ) + pad ;
//height = smallIconSize * cg.iconHUDPercent;
addX = ( float ) smallIconSize * .75 ;
for ( iconCnt = 0 ; iconCnt < sideRightIconCnt ; i + + )
{
if ( i > INV_MAX - 1 )
{
i = 0 ;
}
if ( ( ! CG_InventorySelectable ( i ) ) | | ( ! inv_icons [ i ] ) )
{
continue ;
}
+ + iconCnt ; // Good icon
if ( inv_icons [ i ] )
{
cgi_R_SetColor ( NULL ) ;
CG_DrawPic ( holdX , y + 10 , smallIconSize , smallIconSize , inv_icons [ i ] ) ;
cgi_R_SetColor ( colorTable [ CT_ICON_BLUE ] ) ;
CG_DrawNumField ( holdX + addX , y + smallIconSize , 2 , cg . snap - > ps . inventory [ i ] , 6 , 12 ,
NUM_FONT_SMALL , qfalse ) ;
holdX + = ( smallIconSize + pad ) ;
}
}
}
int cgi_UI_GetItemText ( char * menuFile , char * itemName , char * text ) ;
const char * inventoryDesc [ 15 ] =
{
" NEURO_SAAV_DESC " ,
" BACTA_DESC " ,
" INQUISITOR_DESC " ,
" LA_GOGGLES_DESC " ,
" PORTABLE_SENTRY_DESC " ,
" GOODIE_KEY_DESC " ,
" SECURITY_KEY_DP_DESC " ,
} ;
/*
= = = = = = = = = = = = = = = = = = =
CG_DrawDataPadInventorySelect
= = = = = = = = = = = = = = = = = = =
*/
void CG_DrawDataPadInventorySelect ( void )
{
int i ;
int holdCount , iconCnt ;
int sideLeftIconCnt , sideRightIconCnt ;
int count ;
int holdX ;
//int height;
float addX ;
char text [ 1024 ] = { 0 } ;
vec4_t textColor = { .312f , .75f , .621f , 1.0f } ;
// count the number of items owned
count = 0 ;
for ( i = 0 ; i < INV_MAX ; i + + )
{
if ( CG_InventorySelectable ( i ) & & inv_icons [ i ] )
{
count + + ;
}
}
if ( ! count )
{
cgi_SP_GetStringTextString ( " SP_INGAME_EMPTY_INV " , text , sizeof ( text ) ) ;
int w = cgi_R_Font_StrLenPixels ( text , cgs . media . qhFontSmall , 1.0f ) ;
int x = ( SCREEN_WIDTH - w ) / 2 ;
CG_DrawProportionalString ( x , 300 + 22 , text , CG_CENTER | CG_SMALLFONT , colorTable [ CT_ICON_BLUE ] ) ;
return ;
}
const int sideMax = 3 ; // Max number of icons on the side
// Calculate how many icons will appear to either side of the center one
holdCount = count - 1 ; // -1 for the center icon
if ( holdCount = = 0 ) // No icons to either side
{
sideLeftIconCnt = 0 ;
sideRightIconCnt = 0 ;
}
else if ( count > ( 2 * sideMax ) ) // Go to the max on each side
{
sideLeftIconCnt = sideMax ;
sideRightIconCnt = sideMax ;
}
else // Less than max, so do the calc
{
sideLeftIconCnt = holdCount / 2 ;
sideRightIconCnt = holdCount - sideLeftIconCnt ;
}
i = cg . DataPadInventorySelect - 1 ;
if ( i < 0 )
{
i = INV_MAX - 1 ;
}
const int smallIconSize = 40 ;
const int bigIconSize = 80 ;
const int bigPad = 64 ;
const int pad = 32 ;
const int centerXPos = 320 ;
const int graphicYPos = 340 ;
// Left side ICONS
// Work backwards from current icon
holdX = centerXPos - ( ( bigIconSize / 2 ) + bigPad + smallIconSize ) ;
//height = smallIconSize * cg.iconHUDPercent;
addX = ( float ) smallIconSize * .75 ;
for ( iconCnt = 0 ; iconCnt < sideLeftIconCnt ; i - - )
{
if ( i < 0 )
{
i = INV_MAX - 1 ;
}
if ( ( ! CG_InventorySelectable ( i ) ) | | ( ! inv_icons [ i ] ) )
{
continue ;
}
+ + iconCnt ; // Good icon
if ( inv_icons [ i ] )
{
cgi_R_SetColor ( colorTable [ CT_WHITE ] ) ;
CG_DrawPic ( holdX , graphicYPos + 10 , smallIconSize , smallIconSize , inv_icons [ i ] ) ;
cgi_R_SetColor ( colorTable [ CT_ICON_BLUE ] ) ;
CG_DrawNumField ( holdX + addX , graphicYPos + smallIconSize , 2 , cg . snap - > ps . inventory [ i ] , 6 , 12 ,
NUM_FONT_SMALL , qfalse ) ;
holdX - = ( smallIconSize + pad ) ;
}
}
// Current Center Icon
//height = bigIconSize * cg.iconHUDPercent;
if ( inv_icons [ cg . DataPadInventorySelect ] )
{
cgi_R_SetColor ( colorTable [ CT_WHITE ] ) ;
CG_DrawPic ( centerXPos - ( bigIconSize / 2 ) , ( graphicYPos - ( ( bigIconSize - smallIconSize ) / 2 ) ) + 10 , bigIconSize , bigIconSize , inv_icons [ cg . DataPadInventorySelect ] ) ;
addX = ( float ) bigIconSize * .75 ;
cgi_R_SetColor ( colorTable [ CT_ICON_BLUE ] ) ;
CG_DrawNumField ( ( centerXPos - ( bigIconSize / 2 ) ) + addX , graphicYPos , 2 , cg . snap - > ps . inventory [ cg . DataPadInventorySelect ] , 6 , 12 ,
NUM_FONT_SMALL , qfalse ) ;
}
i = cg . DataPadInventorySelect + 1 ;
if ( i > INV_MAX - 1 )
{
i = 0 ;
}
// Right side ICONS
// Work forwards from current icon
holdX = centerXPos + ( bigIconSize / 2 ) + bigPad ;
//height = smallIconSize * cg.iconHUDPercent;
addX = ( float ) smallIconSize * .75 ;
for ( iconCnt = 0 ; iconCnt < sideRightIconCnt ; i + + )
{
if ( i > INV_MAX - 1 )
{
i = 0 ;
}
if ( ( ! CG_InventorySelectable ( i ) ) | | ( ! inv_icons [ i ] ) )
{
continue ;
}
+ + iconCnt ; // Good icon
if ( inv_icons [ i ] )
{
cgi_R_SetColor ( colorTable [ CT_WHITE ] ) ;
CG_DrawPic ( holdX , graphicYPos + 10 , smallIconSize , smallIconSize , inv_icons [ i ] ) ;
cgi_R_SetColor ( colorTable [ CT_ICON_BLUE ] ) ;
CG_DrawNumField ( holdX + addX , graphicYPos + smallIconSize , 2 , cg . snap - > ps . inventory [ i ] , 6 , 12 ,
NUM_FONT_SMALL , qfalse ) ;
holdX + = ( smallIconSize + pad ) ;
}
}
// draw the weapon description
if ( ( cg . DataPadInventorySelect > = 0 ) & & ( cg . DataPadInventorySelect < 13 ) )
{
cgi_SP_GetStringTextString ( va ( " SP_INGAME_%s " , inventoryDesc [ cg . DataPadInventorySelect ] ) , text , sizeof ( text ) ) ;
if ( text [ 0 ] )
{
CG_DisplayBoxedText ( 70 , 50 , 500 , 300 , text ,
cgs . media . qhFontSmall ,
0.7f ,
textColor
) ;
}
}
}
/*
= = = = = = = = = = = = = = =
SetForcePowerTime
= = = = = = = = = = = = = = =
*/
void SetForcePowerTime ( void )
{
if ( ( ( cg . weaponSelectTime + WEAPON_SELECT_TIME ) > cg . time ) | | // The Weapon HUD was currently active to just swap it out with Force HUD
( ( cg . inventorySelectTime + WEAPON_SELECT_TIME ) > cg . time ) ) // The Inventory HUD was currently active to just swap it out with Force HUD
{
cg . weaponSelectTime = 0 ;
cg . inventorySelectTime = 0 ;
cg . forcepowerSelectTime = cg . time + 130.0f ;
}
else
{
cg . forcepowerSelectTime = cg . time ;
}
}
int showPowers [ MAX_SHOWPOWERS ] =
{
FP_ABSORB ,
FP_HEAL ,
FP_PROTECT ,
FP_TELEPATHY ,
FP_SPEED ,
FP_PUSH ,
FP_PULL ,
FP_SEE ,
FP_DRAIN ,
FP_LIGHTNING ,
FP_RAGE ,
FP_GRIP ,
} ;
const char * showPowersName [ MAX_SHOWPOWERS ] =
{
" SP_INGAME_ABSORB2 " ,
" SP_INGAME_HEAL2 " ,
" SP_INGAME_PROTECT2 " ,
" SP_INGAME_MINDTRICK2 " ,
" SP_INGAME_SPEED2 " ,
" SP_INGAME_PUSH2 " ,
" SP_INGAME_PULL2 " ,
" SP_INGAME_SEEING2 " ,
" SP_INGAME_DRAIN2 " ,
" SP_INGAME_LIGHTNING2 " ,
" SP_INGAME_DARK_RAGE2 " ,
" SP_INGAME_GRIP2 " ,
} ;
// Keep these with groups light side, core, and dark side
int showDataPadPowers [ MAX_DPSHOWPOWERS ] =
{
// Light side
FP_ABSORB ,
FP_HEAL ,
FP_PROTECT ,
FP_TELEPATHY ,
// Core Powers
FP_LEVITATION ,
FP_SPEED ,
FP_PUSH ,
FP_PULL ,
FP_SABERTHROW ,
FP_SABER_DEFENSE ,
FP_SABER_OFFENSE ,
FP_SEE ,
//Dark Side
FP_DRAIN ,
FP_LIGHTNING ,
FP_RAGE ,
FP_GRIP ,
} ;
/*
= = = = = = = = = = = = = = =
ForcePower_Valid
= = = = = = = = = = = = = = =
*/
qboolean ForcePower_Valid ( int index )
{
gentity_t * player = & g_entities [ 0 ] ;
assert ( MAX_SHOWPOWERS = = ( sizeof ( showPowers ) / sizeof ( showPowers [ 0 ] ) ) ) ;
assert ( index < MAX_SHOWPOWERS ) ; //is this a valid index?
if ( player - > client - > ps . forcePowersKnown & ( 1 < < showPowers [ index ] ) & &
player - > client - > ps . forcePowerLevel [ showPowers [ index ] ] ) // Does he have the force power?
{
return qtrue ;
}
return qfalse ;
}
/*
= = = = = = = = = = = = = = =
CG_NextForcePower_f
= = = = = = = = = = = = = = =
*/
void CG_NextForcePower_f ( void )
{
int i ;
if ( ! cg . snap | | in_camera )
{
return ;
}
SetForcePowerTime ( ) ;
if ( ( cg . forcepowerSelectTime + WEAPON_SELECT_TIME ) < cg . time )
{
return ;
}
const int original = cg . forcepowerSelect ;
for ( i = 0 ; i < MAX_SHOWPOWERS ; i + + )
{
cg . forcepowerSelect + + ;
if ( cg . forcepowerSelect > = MAX_SHOWPOWERS )
{
cg . forcepowerSelect = 0 ;
}
if ( ForcePower_Valid ( cg . forcepowerSelect ) ) // Does he have the force power?
{
cgi_S_StartSound ( NULL , 0 , CHAN_AUTO , cgs . media . selectSound2 ) ;
return ;
}
}
cg . forcepowerSelect = original ;
}
/*
= = = = = = = = = = = = = = =
CG_PrevForcePower_f
= = = = = = = = = = = = = = =
*/
void CG_PrevForcePower_f ( void )
{
int i ;
if ( ! cg . snap | | in_camera )
{
return ;
}
SetForcePowerTime ( ) ;
if ( ( cg . forcepowerSelectTime + WEAPON_SELECT_TIME ) < cg . time )
{
return ;
}
const int original = cg . forcepowerSelect ;
for ( i = 0 ; i < MAX_SHOWPOWERS ; i + + )
{
cg . forcepowerSelect - - ;
if ( cg . forcepowerSelect < 0 )
{
cg . forcepowerSelect = MAX_SHOWPOWERS - 1 ;
}
if ( ForcePower_Valid ( cg . forcepowerSelect ) ) // Does he have the force power?
{
cgi_S_StartSound ( NULL , 0 , CHAN_AUTO , cgs . media . selectSound2 ) ;
return ;
}
}
cg . forcepowerSelect = original ;
}
/*
= = = = = = = = = = = = = = = = = = =
CG_DrawForceSelect
= = = = = = = = = = = = = = = = = = =
*/
void CG_DrawForceSelect ( void )
{
int i ;
int count ;
int holdX ;
int sideLeftIconCnt , sideRightIconCnt ;
int holdCount , iconCnt ;
char text [ 1024 ] = { 0 } ;
int yOffset = 0 ;
// don't display if dead
if ( cg . predicted_player_state . stats [ STAT_HEALTH ] < = 0 | | ( cg . snap - > ps . viewEntity > 0 & & cg . snap - > ps . viewEntity < ENTITYNUM_WORLD ) )
{
return ;
}
if ( ( cg . forcepowerSelectTime + WEAPON_SELECT_TIME ) < cg . time ) // Time is up for the HUD to display
{
return ;
}
// count the number of powers owned
count = 0 ;
for ( i = 0 ; i < MAX_SHOWPOWERS ; + + i )
{
if ( ForcePower_Valid ( i ) )
{
count + + ;
}
}
if ( count = = 0 ) // If no force powers, don't display
{
return ;
}
/*
int x2 , y2 ;
if ( ! cgi_UI_GetMenuInfo ( " forceselecthud " , & x2 , & y2 , & w2 , & h2 ) )
{
return ;
}
*/
cg . iconSelectTime = cg . forcepowerSelectTime ;
// showing weapon select clears pickup item display, but not the blend blob
cg . itemPickupTime = 0 ;
const int sideMax = 3 ; // Max number of icons on the side
// Calculate how many icons will appear to either side of the center one
holdCount = count - 1 ; // -1 for the center icon
if ( holdCount = = 0 ) // No icons to either side
{
sideLeftIconCnt = 0 ;
sideRightIconCnt = 0 ;
}
else if ( count > ( 2 * sideMax ) ) // Go to the max on each side
{
sideLeftIconCnt = sideMax ;
sideRightIconCnt = sideMax ;
}
else // Less than max, so do the calc
{
sideLeftIconCnt = holdCount / 2 ;
sideRightIconCnt = holdCount - sideLeftIconCnt ;
}
const int smallIconSize = 30 ;
const int bigIconSize = 60 ;
const int pad = 12 ;
const int x = 320 ;
const int y = 425 ;
i = cg . forcepowerSelect - 1 ;
if ( i < 0 )
{
i = MAX_SHOWPOWERS - 1 ;
}
cgi_R_SetColor ( NULL ) ;
// Work backwards from current icon
holdX = x - ( ( bigIconSize / 2 ) + pad + smallIconSize ) ;
for ( iconCnt = 1 ; iconCnt < ( sideLeftIconCnt + 1 ) ; i - - )
{
if ( i < 0 )
{
i = MAX_SHOWPOWERS - 1 ;
}
if ( ! ForcePower_Valid ( i ) ) // Does he have this power?
{
continue ;
}
+ + iconCnt ; // Good icon
if ( force_icons [ showPowers [ i ] ] )
{
CG_DrawPic ( holdX , y + yOffset , smallIconSize , smallIconSize , force_icons [ showPowers [ i ] ] ) ;
holdX - = ( smallIconSize + pad ) ;
}
}
// Current Center Icon
if ( force_icons [ showPowers [ cg . forcepowerSelect ] ] )
{
CG_DrawPic ( x - ( bigIconSize / 2 ) , ( y - ( ( bigIconSize - smallIconSize ) / 2 ) ) + yOffset , bigIconSize , bigIconSize , force_icons [ showPowers [ cg . forcepowerSelect ] ] ) ;
}
i = cg . forcepowerSelect + 1 ;
if ( i > = MAX_SHOWPOWERS )
{
i = 0 ;
}
// Work forwards from current icon
holdX = x + ( bigIconSize / 2 ) + pad ;
for ( iconCnt = 1 ; iconCnt < ( sideRightIconCnt + 1 ) ; i + + )
{
if ( i > = MAX_SHOWPOWERS )
{
i = 0 ;
}
if ( ! ForcePower_Valid ( i ) ) // Does he have this power?
{
continue ;
}
+ + iconCnt ; // Good icon
if ( force_icons [ showPowers [ i ] ] )
{
CG_DrawPic ( holdX , y + yOffset , smallIconSize , smallIconSize , force_icons [ showPowers [ i ] ] ) ;
holdX + = ( smallIconSize + pad ) ;
}
}
// This only a temp solution.
if ( cgi_SP_GetStringTextString ( showPowersName [ cg . forcepowerSelect ] , text , sizeof ( text ) ) )
{
int w = cgi_R_Font_StrLenPixels ( text , cgs . media . qhFontSmall , 1.0f ) ;
int x = ( SCREEN_WIDTH - w ) / 2 ;
cgi_R_Font_DrawString ( x , ( SCREEN_HEIGHT - 24 ) + yOffset , text , colorTable [ CT_ICON_BLUE ] , cgs . media . qhFontSmall , - 1 , 1.0f ) ;
}
}
/*
= = = = = = = = = = = = = = =
ForcePowerDataPad_Valid
= = = = = = = = = = = = = = =
*/
qboolean ForcePowerDataPad_Valid ( int index )
{
gentity_t * player = & g_entities [ 0 ] ;
assert ( index < MAX_DPSHOWPOWERS ) ;
if ( player - > client - > ps . forcePowersKnown & ( 1 < < showDataPadPowers [ index ] ) & &
player - > client - > ps . forcePowerLevel [ showDataPadPowers [ index ] ] ) // Does he have the force power?
{
return qtrue ;
}
return qfalse ;
}
/*
= = = = = = = = = = = = = = =
CG_DPNextForcePower_f
= = = = = = = = = = = = = = =
*/
void CG_DPNextForcePower_f ( void )
{
int i ;
int original ;
if ( ! cg . snap )
{
return ;
}
original = cg . DataPadforcepowerSelect ;
for ( i = 0 ; i < MAX_DPSHOWPOWERS ; i + + )
{
cg . DataPadforcepowerSelect + + ;
if ( cg . DataPadforcepowerSelect > = MAX_DPSHOWPOWERS )
{
cg . DataPadforcepowerSelect = 0 ;
}
if ( ForcePowerDataPad_Valid ( cg . DataPadforcepowerSelect ) ) // Does he have the force power?
{
return ;
}
}
cg . DataPadforcepowerSelect = original ;
}
/*
= = = = = = = = = = = = = = =
CG_DPPrevForcePower_f
= = = = = = = = = = = = = = =
*/
void CG_DPPrevForcePower_f ( void )
{
int i ;
int original ;
if ( ! cg . snap )
{
return ;
}
original = cg . DataPadforcepowerSelect ;
for ( i = 0 ; i < MAX_DPSHOWPOWERS ; i + + )
{
cg . DataPadforcepowerSelect - - ;
if ( cg . DataPadforcepowerSelect < 0 )
{
cg . DataPadforcepowerSelect = MAX_DPSHOWPOWERS - 1 ;
}
if ( ForcePowerDataPad_Valid ( cg . DataPadforcepowerSelect ) ) // Does he have the force power?
{
return ;
}
}
cg . DataPadforcepowerSelect = original ;
}
const char * forcepowerDesc [ NUM_FORCE_POWERS ] =
{
" FORCE_ABSORB_DESC " ,
" FORCE_HEAL_DESC " ,
" FORCE_PROTECT_DESC " ,
" FORCE_MIND_TRICK_DESC " ,
" FORCE_JUMP_DESC " ,
" FORCE_SPEED_DESC " ,
" FORCE_PUSH_DESC " ,
" FORCE_PULL_DESC " ,
" FORCE_SABER_THROW_DESC " ,
" FORCE_SABER_DEFENSE_DESC " ,
" FORCE_SABER_OFFENSE_DESC " ,
" FORCE_SENSE_DESC " ,
" FORCE_DRAIN_DESC " ,
" FORCE_LIGHTNING_DESC " ,
" FORCE_RAGE_DESC " ,
" FORCE_GRIP_DESC " ,
} ;
const char * forcepowerLvl1Desc [ NUM_FORCE_POWERS ] =
{
" FORCE_ABSORB_LVL1_DESC " ,
" FORCE_HEAL_LVL1_DESC " ,
" FORCE_PROTECT_LVL1_DESC " ,
" FORCE_MIND_TRICK_LVL1_DESC " ,
" FORCE_JUMP_LVL1_DESC " ,
" FORCE_SPEED_LVL1_DESC " ,
" FORCE_PUSH_LVL1_DESC " ,
" FORCE_PULL_LVL1_DESC " ,
" FORCE_SABER_THROW_LVL1_DESC " ,
" FORCE_SABER_DEFENSE_LVL1_DESC " ,
" FORCE_SABER_OFFENSE_LVL1_DESC " ,
" FORCE_SENSE_LVL1_DESC " ,
" FORCE_DRAIN_LVL1_DESC " ,
" FORCE_LIGHTNING_LVL1_DESC " ,
" FORCE_RAGE_LVL1_DESC " ,
" FORCE_GRIP_LVL1_DESC " ,
} ;
const char * forcepowerLvl2Desc [ NUM_FORCE_POWERS ] =
{
" FORCE_ABSORB_LVL2_DESC " ,
" FORCE_HEAL_LVL2_DESC " ,
" FORCE_PROTECT_LVL2_DESC " ,
" FORCE_MIND_TRICK_LVL2_DESC " ,
" FORCE_JUMP_LVL2_DESC " ,
" FORCE_SPEED_LVL2_DESC " ,
" FORCE_PUSH_LVL2_DESC " ,
" FORCE_PULL_LVL2_DESC " ,
" FORCE_SABER_THROW_LVL2_DESC " ,
" FORCE_SABER_DEFENSE_LVL2_DESC " ,
" FORCE_SABER_OFFENSE_LVL2_DESC " ,
" FORCE_SENSE_LVL2_DESC " ,
" FORCE_DRAIN_LVL2_DESC " ,
" FORCE_LIGHTNING_LVL2_DESC " ,
" FORCE_RAGE_LVL2_DESC " ,
" FORCE_GRIP_LVL2_DESC " ,
} ;
const char * forcepowerLvl3Desc [ NUM_FORCE_POWERS ] =
{
" FORCE_ABSORB_LVL3_DESC " ,
" FORCE_HEAL_LVL3_DESC " ,
" FORCE_PROTECT_LVL3_DESC " ,
" FORCE_MIND_TRICK_LVL3_DESC " ,
" FORCE_JUMP_LVL3_DESC " ,
" FORCE_SPEED_LVL3_DESC " ,
" FORCE_PUSH_LVL3_DESC " ,
" FORCE_PULL_LVL3_DESC " ,
" FORCE_SABER_THROW_LVL3_DESC " ,
" FORCE_SABER_DEFENSE_LVL3_DESC " ,
" FORCE_SABER_OFFENSE_LVL3_DESC " ,
" FORCE_SENSE_LVL3_DESC " ,
" FORCE_DRAIN_LVL3_DESC " ,
" FORCE_LIGHTNING_LVL3_DESC " ,
" FORCE_RAGE_LVL3_DESC " ,
" FORCE_GRIP_LVL3_DESC " ,
} ;
/*
= = = = = = = = = = = = = = = = = = =
CG_DrawDataPadForceSelect
= = = = = = = = = = = = = = = = = = =
*/
void CG_DrawDataPadForceSelect ( void )
{
int i ;
int count ;
int holdX ;
int sideLeftIconCnt , sideRightIconCnt ;
int holdCount , iconCnt ;
char text [ 1024 ] = { 0 } ;
char text2 [ 1024 ] = { 0 } ;
// count the number of powers known
count = 0 ;
for ( i = 0 ; i < MAX_DPSHOWPOWERS ; i + + )
{
if ( ForcePowerDataPad_Valid ( i ) )
{
count + + ;
}
}
if ( count < 1 ) // If no force powers, don't display
{
return ;
}
// Time to switch new icon colors
// Faded side icon color
// memcpy(fadeColor, colorTable[CT_WHITE], sizeof(vec4_t));
cg . iconSelectTime = cg . forcepowerSelectTime ;
const int sideMax = 3 ; // Max number of icons on the side
// Calculate how many icons will appear to either side of the center one
holdCount = count - 1 ; // -1 for the center icon
if ( holdCount = = 0 ) // No icons to either side
{
sideLeftIconCnt = 0 ;
sideRightIconCnt = 0 ;
}
else if ( count > ( 2 * sideMax ) ) // Go to the max on each side
{
sideLeftIconCnt = sideMax ;
sideRightIconCnt = sideMax ;
}
else // Less than max, so do the calc
{
sideLeftIconCnt = holdCount / 2 ;
sideRightIconCnt = holdCount - sideLeftIconCnt ;
}
const int smallIconSize = 40 ;
const int bigIconSize = 70 ;
const int bigPad = 64 ;
const int pad = 32 ;
const int centerXPos = 320 ;
const int graphicYPos = 340 ;
i = cg . DataPadforcepowerSelect - 1 ;
if ( i < 0 )
{
i = MAX_DPSHOWPOWERS - 1 ;
}
// Print icons to the left of the center
cgi_R_SetColor ( colorTable [ CT_WHITE ] ) ;
// Work backwards from current icon
holdX = centerXPos - ( ( bigIconSize / 2 ) + bigPad + smallIconSize ) ;
for ( iconCnt = 1 ; iconCnt < ( sideLeftIconCnt + 1 ) ; i - - )
{
if ( i < 0 )
{
i = MAX_DPSHOWPOWERS - 1 ;
}
if ( ! ForcePowerDataPad_Valid ( i ) ) // Does he have this power?
{
continue ;
}
+ + iconCnt ; // Good icon
if ( force_icons [ showDataPadPowers [ i ] ] )
{
CG_DrawPic ( holdX , graphicYPos , smallIconSize , smallIconSize , force_icons [ showDataPadPowers [ i ] ] ) ;
}
// A new force power
if ( ( ( cg_updatedDataPadForcePower1 . integer - 1 ) = = showDataPadPowers [ i ] ) | |
( ( cg_updatedDataPadForcePower2 . integer - 1 ) = = showDataPadPowers [ i ] ) | |
( ( cg_updatedDataPadForcePower3 . integer - 1 ) = = showDataPadPowers [ i ] ) )
{
CG_DrawPic ( holdX , graphicYPos , smallIconSize , smallIconSize , cgs . media . DPForcePowerOverlay ) ;
}
if ( force_icons [ showDataPadPowers [ i ] ] )
{
holdX - = ( smallIconSize + pad ) ;
}
}
// Current Center Icon
if ( force_icons [ showDataPadPowers [ cg . DataPadforcepowerSelect ] ] )
{
cgi_R_SetColor ( colorTable [ CT_WHITE ] ) ;
CG_DrawPic ( centerXPos - ( bigIconSize / 2 ) , ( graphicYPos - ( ( bigIconSize - smallIconSize ) / 2 ) ) , bigIconSize , bigIconSize , force_icons [ showDataPadPowers [ cg . DataPadforcepowerSelect ] ] ) ;
// New force power
if ( ( ( cg_updatedDataPadForcePower1 . integer - 1 ) = = showDataPadPowers [ cg . DataPadforcepowerSelect ] ) | |
( ( cg_updatedDataPadForcePower2 . integer - 1 ) = = showDataPadPowers [ cg . DataPadforcepowerSelect ] ) | |
( ( cg_updatedDataPadForcePower3 . integer - 1 ) = = showDataPadPowers [ cg . DataPadforcepowerSelect ] ) )
{
CG_DrawPic ( centerXPos - ( bigIconSize / 2 ) , ( graphicYPos - ( ( bigIconSize - smallIconSize ) / 2 ) ) , bigIconSize , bigIconSize , cgs . media . DPForcePowerOverlay ) ;
}
}
i = cg . DataPadforcepowerSelect + 1 ;
if ( i > = MAX_DPSHOWPOWERS )
{
i = 0 ;
}
cgi_R_SetColor ( colorTable [ CT_WHITE ] ) ;
// Work forwards from current icon
holdX = centerXPos + ( bigIconSize / 2 ) + bigPad ;
for ( iconCnt = 1 ; iconCnt < ( sideRightIconCnt + 1 ) ; i + + )
{
if ( i > = MAX_DPSHOWPOWERS )
{
i = 0 ;
}
if ( ! ForcePowerDataPad_Valid ( i ) ) // Does he have this power?
{
continue ;
}
+ + iconCnt ; // Good icon
if ( force_icons [ showDataPadPowers [ i ] ] )
{
CG_DrawPic ( holdX , graphicYPos , smallIconSize , smallIconSize , force_icons [ showDataPadPowers [ i ] ] ) ;
}
// A new force power
if ( ( ( cg_updatedDataPadForcePower1 . integer - 1 ) = = showDataPadPowers [ i ] ) | |
( ( cg_updatedDataPadForcePower2 . integer - 1 ) = = showDataPadPowers [ i ] ) | |
( ( cg_updatedDataPadForcePower3 . integer - 1 ) = = showDataPadPowers [ i ] ) )
{
CG_DrawPic ( holdX , graphicYPos , smallIconSize , smallIconSize , cgs . media . DPForcePowerOverlay ) ;
}
if ( force_icons [ showDataPadPowers [ i ] ] )
{
holdX + = ( smallIconSize + pad ) ;
}
}
cgi_SP_GetStringTextString ( va ( " SP_INGAME_%s " , forcepowerDesc [ cg . DataPadforcepowerSelect ] ) , text , sizeof ( text ) ) ;
if ( player - > client - > ps . forcePowerLevel [ showDataPadPowers [ cg . DataPadforcepowerSelect ] ] = = 1 )
{
cgi_SP_GetStringTextString ( va ( " SP_INGAME_%s " , forcepowerLvl1Desc [ cg . DataPadforcepowerSelect ] ) , text2 , sizeof ( text2 ) ) ;
}
else if ( player - > client - > ps . forcePowerLevel [ showDataPadPowers [ cg . DataPadforcepowerSelect ] ] = = 2 )
{
cgi_SP_GetStringTextString ( va ( " SP_INGAME_%s " , forcepowerLvl2Desc [ cg . DataPadforcepowerSelect ] ) , text2 , sizeof ( text2 ) ) ;
}
else
{
cgi_SP_GetStringTextString ( va ( " SP_INGAME_%s " , forcepowerLvl3Desc [ cg . DataPadforcepowerSelect ] ) , text2 , sizeof ( text2 ) ) ;
}
if ( text [ 0 ] )
{
const short textboxXPos = 40 ;
const short textboxYPos = 60 ;
const int textboxWidth = 560 ;
const int textboxHeight = 300 ;
const float textScale = 1.0f ;
CG_DisplayBoxedText ( textboxXPos , textboxYPos , textboxWidth , textboxHeight , va ( " %s%s " , text , text2 ) ,
4 ,
textScale ,
colorTable [ CT_WHITE ]
) ;
}
}
// actually, these are pretty pointless so far in CHC, since in TA codebase they were used only so init some HUD
// function ptrs to allow cinematics in onscreen displays. So far, we don't use those, but here they are anyway...
//
/* These stupid pragmas don't work, they still give the warning. Forget it, REM the lot.
# pragma warning ( disable : 4505) // unreferenced local function has been removed
static int CG_PlayCinematic ( const char * name , float x , float y , float w , float h ) {
return trap_CIN_PlayCinematic ( name , x , y , w , h , CIN_loop ) ;
}
static void CG_StopCinematic ( int handle ) {
trap_CIN_StopCinematic ( handle ) ;
}
static void CG_DrawCinematic ( int handle , float x , float y , float w , float h ) {
trap_CIN_SetExtents ( handle , x , y , w , h ) ;
trap_CIN_DrawCinematic ( handle ) ;
}
static void CG_RunCinematicFrame ( int handle ) {
trap_CIN_RunCinematic ( handle ) ;
}
# pragma warning ( default : 4505)
*/