//======================================================================= // Copyright XashXT Group 2009 © // client.h -- primary header for client //======================================================================= #ifndef CLIENT_H #define CLIENT_H #include "mathlib.h" #include "cdll_int.h" #include "gameui_api.h" #include "cl_entity.h" #include "com_model.h" #include "cm_local.h" #include "pm_defs.h" #include "pm_movevars.h" #include "protocol.h" #include "netchan.h" #include "world.h" #define MAX_DEMOS 32 #define MAX_MOVIES 8 #define NUM_FOR_EDICT(e) ((int)((cl_entity_t *)(e) - clgame.entities)) #define EDICT_NUM( num ) CL_EDICT_NUM( num, __FILE__, __LINE__ ) #define cl_time() ( cl.time ) #define sv_time() ( cl.mtime[0] ) //============================================================================= typedef struct frame_s { // received from server double receivedtime; // time message was received, or -1 double latency; double time; // server timestamp clientdata_t clientdata; // message received that reflects performing weapon_data_t weapondata[32]; packet_entities_t entities; bool valid; // cleared if delta parsing was invalid } frame_t; #define CMD_BACKUP MULTIPLAYER_BACKUP // allow a lot of command backups for very fast systems #define CMD_MASK (CMD_BACKUP - 1) #define CL_UPDATE_MASK (CL_UPDATE_BACKUP - 1) extern int CL_UPDATE_BACKUP; // the client_t structure is wiped completely at every // server map change typedef struct { int timeoutcount; int servercount; // server identification for prespawns int validsequence; // this is the sequence number of the last good // world snapshot/update we got. If this is 0, we can't // render a frame yet int parsecount; // server message counter int parsecountmod; // modulo with network window double parsecounttime; // timestamp of parse bool video_prepped; // false if on new level or new ref dll bool audio_prepped; // false if on new level or new snd dll bool force_refdef; // vid has changed, so we can't use a paused refdef int delta_sequence; // acknowledged sequence number double mtime[2]; // the timestamp of the last two messages int last_incoming_sequence; bool force_send_usercmd; frame_t frame; // received from server int surpressCount; // number of messages rate supressed frame_t frames[MULTIPLAYER_BACKUP]; // alloced on svc_serverdata usercmd_t cmds[MULTIPLAYER_BACKUP]; // each mesage will send several old cmds double time; // this is the time value that the client // is rendering at. always <= cls.realtime // a lerp point for other data double oldtime; // previous cl.time, time-oldtime is used // to decay light values and smooth step ups int render_flags; // clearing at end of frame float lerpFrac; // interpolation value ref_params_t refdef; // shared refdef char serverinfo[MAX_INFO_STRING]; player_info_t players[MAX_CLIENTS]; event_state_t events; // predicting stuff uint random_seed; // for predictable random values vec3_t predicted_origins[CMD_BACKUP]; // for debug comparing against server vec3_t predicted_origin; // generated by CL_PredictMovement vec3_t predicted_viewofs; vec3_t predicted_angles; vec3_t predicted_velocity; vec3_t prediction_error; // server state information int playernum; int maxclients; int movemessages; char configstrings[MAX_CONFIGSTRINGS][CS_SIZE]; model_t *worldmodel; // pointer to world // locally derived information from server state model_t models[MAX_MODELS]; sound_t sound_precache[MAX_SOUNDS]; shader_t decal_shaders[MAX_DECALNAMES]; } client_t; /* ================================================================== the client_static_t structure is persistant through an arbitrary number of server connections ================================================================== */ typedef enum { ca_uninitialized = 0, ca_disconnected, // not talking to a server ca_connecting, // sending request packets to the server ca_connected, // netchan_t established, waiting for svc_serverdata ca_active, // game views should be displayed ca_cinematic, // playing a cinematic, not connected to a server } connstate_t; typedef enum { key_console = 0, key_game, key_menu } keydest_t; typedef enum { dl_none, dl_model, dl_sound, dl_generic, } dltype_t; // download type typedef enum { scrshot_inactive, scrshot_plaque, // levelshot scrshot_savegame, // saveshot scrshot_demoshot, // for demos preview scrshot_envshot, // cubemap view scrshot_skyshot // skybox view } scrshot_t; // client screen state typedef enum { CL_LOADING = 1, // draw loading progress-bar CL_ACTIVE, // draw normal hud CL_PAUSED, // pause when active CL_CHANGELEVEL, // draw 'loading' during changelevel } scrstate_t; typedef struct { char name[32]; int number; // svc_ number int size; // if size == -1, size come from first byte after svcnum pfnUserMsgHook func; // user-defined function } cl_user_message_t; typedef struct { char name[CS_SIZE]; word index; // event index pfnEventHook func; // user-defined function } user_event_t; typedef struct { HSPRITE hFontTexture; // handle to texture shader wrect_t fontRc[256]; // rectangles bool valid; // rectangles are valid } cl_font_t; typedef struct { // temp handle HSPRITE hSprite; // scissor test int scissor_x; int scissor_y; int scissor_width; int scissor_height; bool scissor_test; // holds text color rgba_t textColor; // crosshair members HSPRITE hCrosshair; wrect_t rcCrosshair; rgba_t rgbaCrosshair; byte gammaTable[256]; } draw_stuff_t; typedef struct { // centerprint stuff int lines; int y, time; char message[2048]; int totalWidth; int totalHeight; } center_print_t; typedef struct { void *hInstance; // pointer to client.dll HUD_FUNCTIONS dllFuncs; // dll exported funcs byte *mempool; // client edicts pool string mapname; // map name string maptitle; // display map title string itemspath; // path to items description for auto-complete func cl_entity_t *entities; // dynamically allocated entity array int numEntities; // actual ents count int maxEntities; // movement values from server movevars_t movevars; movevars_t oldmovevars; playermove_t *pmove; // pmove state int trace_hull; // used by PM_SetTraceHull int oldcount; // used by PM_Push\Pop state vec3_t player_mins[4]; // 4 hulls allowed vec3_t player_maxs[4]; // 4 hulls allowed cl_user_message_t msg[MAX_USER_MESSAGES]; // keep static to avoid fragment memory user_event_t *events[MAX_EVENTS]; draw_stuff_t ds; // draw2d stuff (hud, weaponmenu etc) center_print_t centerPrint; // centerprint variables SCREENINFO scrInfo; // actual screen info rgb_t palette[256]; // Quake1 palette used for particle colors client_textmessage_t *titles; // title messages, not network messages int numTitles; cl_entity_t viewent; // viewmodel } clgame_static_t; typedef struct { void *hInstance; // pointer to client.dll UI_FUNCTIONS dllFuncs; // dll exported funcs byte *mempool; // client edicts pool cl_entity_t playermodel; // uiPlayerSetup drawing model draw_stuff_t ds; // draw2d stuff (hud, weaponmenu etc) GAMEINFO gameInfo; // current gameInfo GAMEINFO *modsInfo[MAX_MODS]; // simplified gameInfo for GameUI ui_globalvars_t *globals; bool drawLogo; // set to TRUE if logo.avi missed or corrupted long logo_xres; long logo_yres; } gameui_static_t; typedef struct { connstate_t state; bool initialized; bool changelevel; // during changelevel keydest_t key_dest; byte *mempool; // client premamnent pool: edicts etc int framecount; int quakePort; // a 16 bit value that allows quake servers // to work around address translating routers // connection information string servername; // name of server from original connect int connect_time; // for connection retransmits netchan_t netchan; int serverProtocol; // in case we are doing some kind of version hack int challenge; // from the server to use for connecting float packet_loss; double packet_loss_recalc_time; float nextcmdtime; // when can we send the next command packet? int lastoutgoingcommand; // sequence number of last outgoing command // internal shaders shader_t fillShader; // used for emulate FillRGBA to avoid wrong draw-sort shader_t pauseIcon; // draw 'paused' when game in-pause shader_t loadingBar; // 'loading' progress bar cl_font_t creditsFont; // shared creditsfont file_t *download; // file transfer from server string downloadname; string downloadtempname; int downloadnumber; dltype_t downloadtype; scrshot_t scrshot_request; // request for screen shot scrshot_t scrshot_action; // in-action const float *envshot_vieworg; // envshot position string shotname; // demo loop control int demonum; // -1 = don't play demos string demos[MAX_DEMOS]; // when not playing // movie playlist int movienum; string movies[MAX_MOVIES]; // demo recording info must be here, so it isn't clearing on level change bool demorecording; bool demoplayback; bool demowaiting; // don't record until a non-delta message is received string demoname; // for demo looping file_t *demofile; } client_static_t; extern client_t cl; extern client_static_t cls; extern clgame_static_t clgame; extern gameui_static_t gameui; extern render_exp_t *re; // // cvars // extern cvar_t *cl_predict; extern cvar_t *cl_smooth; extern cvar_t *cl_showfps; extern cvar_t *cl_envshot_size; extern cvar_t *cl_nodelta; extern cvar_t *cl_crosshair; extern cvar_t *cl_showmiss; extern cvar_t *cl_testlights; extern cvar_t *cl_solid_players; extern cvar_t *cl_idealpitchscale; extern cvar_t *cl_allow_levelshots; extern cvar_t *cl_levelshot_name; extern cvar_t *scr_centertime; extern cvar_t *scr_download; extern cvar_t *scr_loading; extern cvar_t *userinfo; //============================================================================= bool CL_CheckOrDownloadFile( const char *filename ); void CL_ParseConfigString( sizebuf_t *msg ); void CL_SetLightstyle( int i ); void CL_RunLightStyles( void ); void CL_AddEntities( void ); void CL_AddDLights( void ); void CL_AddLightStyles( void ); //================================================= void CL_PrepVideo( void ); void CL_PrepSound( void ); // // cl_cmds.c // void CL_Quit_f( void ); void CL_ScreenShot_f( void ); void CL_EnvShot_f( void ); void CL_SkyShot_f( void ); void CL_SaveShot_f( void ); void CL_DemoShot_f( void ); void CL_LevelShot_f( void ); void CL_SetSky_f( void ); void SCR_Viewpos_f( void ); void SCR_TimeRefresh_f( void ); // // cl_main // void CL_Init( void ); void CL_SendCommand( void ); void CL_Disconnect_f( void ); void CL_GetChallengePacket( void ); void CL_PingServers_f( void ); void CL_RequestNextDownload( void ); void CL_ClearState( void ); // // cl_demo.c // void CL_DrawDemoRecording( void ); void CL_WriteDemoMessage( sizebuf_t *msg, int head_size ); void CL_ReadDemoMessage( void ); void CL_StopPlayback( void ); void CL_StopRecord( void ); void CL_PlayDemo_f( void ); void CL_StartDemos_f( void ); void CL_Demos_f( void ); void CL_DeleteDemo_f( void ); void CL_Record_f( void ); void CL_Stop_f( void ); // // cl_game.c // void CL_UnloadProgs( void ); bool CL_LoadProgs( const char *name ); void CL_ParseUserMessage( sizebuf_t *msg, int svc_num ); void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize ); void CL_DrawHUD( int state ); void CL_InitEdicts( void ); void CL_FreeEdicts( void ); void CL_InitWorld( void ); void CL_InitEntity( cl_entity_t *pEdict ); void CL_FreeEntity( cl_entity_t *pEdict ); void CL_CenterPrint( const char *text, float y ); void CL_SetEventIndex( const char *szEvName, int ev_index ); void CL_TextMessageParse( byte *pMemFile, int fileSize ); int pfnDecalIndexFromName( const char *szDecalName ); void *VGui_GetPanel( void ); void VGui_ViewportPaintBackground( int extents[4] ); _inline cl_entity_t *CL_EDICT_NUM( int n, const char *file, const int line ) { if(( n >= 0 ) && ( n < clgame.maxEntities )) return clgame.entities + n; Host_Error( "CL_EDICT_NUM: bad number %i (called at %s:%i)\n", n, file, line ); return NULL; } // // cl_parse.c // extern const char *svc_strings[256]; void CL_ParseServerMessage( sizebuf_t *msg ); void CL_RunBackgroundTrack( void ); void CL_Download_f( void ); // // cl_scrn.c // void SCR_RegisterShaders( void ); void SCR_MakeScreenShot( void ); void SCR_MakeLevelShot( void ); void SCR_NetSpeeds( void ); void SCR_RSpeeds( void ); void SCR_DrawFPS( void ); // // cl_view.c // void V_Init (void); void V_Shutdown( void ); void V_ClearScene( void ); bool V_PreRender( void ); void V_PostRender( void ); void V_RenderView( void ); // // cl_pmove.c // void CL_SetSolidEntities( void ); void CL_SetSolidPlayers( int playernum ); void CL_InitClientMove( void ); void CL_PredictMovement( void ); void CL_CheckPredictionError( void ); bool CL_IsPredicted( void ); // // cl_frame.c // void CL_ParsePacketEntities( sizebuf_t *msg, bool delta ); void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate ); bool CL_GetEntitySpatialization( int ent, vec3_t origin, vec3_t velocity ); void CL_ClearFrames( void ); // // cl_tent.c // int CL_AddEntity( int entityType, cl_entity_t *pEnt, shader_t customShader ); void CL_WeaponAnim( int iAnim, int body ); void CL_ClearEffects( void ); void CL_TestLights( void ); struct dlight_s *CL_AllocDlight( int key ); struct dlight_s *CL_AllocElight( int key ); void CL_LightForPoint( const vec3_t point, vec3_t ambientLight ); void CL_DecalShoot( HSPRITE hDecal, int entityIndex, int modelIndex, float *pos, int flags ); void CL_PlayerDecal( HSPRITE hDecal, int entityIndex, float *pos, byte *color ); void CL_QueueEvent( int flags, int index, float delay, event_args_t *args ); void CL_PlaybackEvent( int flags, const cl_entity_t *pInvoker, word eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); word CL_PrecacheEvent( const char *name ); void CL_ResetEvent( event_info_t *ei ); void CL_FireEvents( void ); // // console.c // bool Con_Visible( void ); void Con_Init( void ); void Con_VidInit( void ); void Con_ToggleConsole_f( void ); void Con_ClearNotify( void ); void Con_RunConsole( void ); void Con_DrawConsole( void ); void Con_DrawStringLen( const char *pText, int *length, int *height ); int Con_DrawString( int x, int y, const char *string, rgba_t setColor ); void Con_DefaultColor( int r, int g, int b ); void Con_CharEvent( int key ); void Key_Console( int key ); void Con_Close( void ); // // cl_menu.c // void UI_UnloadProgs( void ); bool UI_LoadProgs( const char *name ); void UI_UpdateMenu( float realtime ); void UI_KeyEvent( int key, bool down ); void UI_MouseMove( int x, int y ); void UI_SetActiveMenu( bool fActive ); void UI_AddServerToList( netadr_t adr, const char *info ); void UI_GetCursorPos( int *pos_x, int *pos_y ); void UI_SetCursorPos( int pos_x, int pos_y ); void UI_ShowCursor( bool show ); bool UI_CreditsActive( void ); void UI_CharEvent( int key ); bool UI_MouseInRect( void ); bool UI_IsVisible( void ); // // cl_video.c // void SCR_InitCinematic( void ); void SCR_FreeCinematic( void ); bool SCR_PlayCinematic( const char *name ); bool SCR_DrawCinematic( void ); void SCR_RunCinematic( void ); void SCR_StopCinematic( void ); void CL_PlayVideo_f( void ); // // cl_world.c // extern areanode_t cl_areanodes[]; void CL_ClearWorld( void ); void CL_UnlinkEdict( cl_entity_t *ent ); void CL_LinkEdict( cl_entity_t *ent ); int CL_AreaEdicts( const vec3_t mins, const vec3_t maxs, cl_entity_t **list, int maxcount, int areatype ); int CL_TruePointContents( const vec3_t p ); int CL_PointContents( const vec3_t p ); #endif//CLIENT_H