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.
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
*/
// client.h
-typedef struct
+#ifndef CLIENT_H
+#define CLIENT_H
+
+#include "matrixlib.h"
+
+// LordHavoc: 256 dynamic lights
+#define MAX_DLIGHTS 256
+
+// flags for rtlight rendering
+#define LIGHTFLAG_NORMALMODE 1
+#define LIGHTFLAG_REALTIMEMODE 2
+
+typedef struct effect_s
+{
+ int active;
+ vec3_t origin;
+ float starttime;
+ float framerate;
+ int modelindex;
+ int startframe;
+ int endframe;
+ // these are for interpolation
+ int frame;
+ double frame1time;
+ double frame2time;
+}
+cl_effect_t;
+
+typedef struct beam_s
+{
+ int entity;
+ // draw this as lightning polygons, or a model?
+ int lightning;
+ struct model_s *model;
+ float endtime;
+ vec3_t start, end;
+ // if this beam is owned by an entity, this is the beam start relative to
+ // that entity's matrix for per frame start updates
+ vec3_t relativestart;
+ vec3_t relativeend;
+ // indicates whether relativestart is valid
+ int relativestartvalid;
+}
+beam_t;
+
+typedef struct rtlight_s
+{
+ // shadow volumes are done entirely in model space, so there are no matrices for dealing with them... they just use the origin
+
+ // note that the world to light matrices are inversely scaled (divided) by lightradius
+
+ // core properties
+ // matrix for transforming world coordinates to light filter coordinates
+ matrix4x4_t matrix_worldtolight;
+ // typically 1 1 1, can be lower (dim) or higher (overbright)
+ vec3_t color;
+ // size of the light (remove?)
+ vec_t radius;
+ // light filter
+ char cubemapname[64];
+ // light style to monitor for brightness
+ int style;
+ // whether light should render shadows
+ int shadow;
+ // intensity of corona to render
+ vec_t corona;
+ // radius scale of corona to render (1.0 means same as light radius)
+ vec_t coronasizescale;
+ // ambient intensity to render
+ vec_t ambientscale;
+ // diffuse intensity to render
+ vec_t diffusescale;
+ // specular intensity to render
+ vec_t specularscale;
+ // LIGHTFLAG_* flags
+ int flags;
+
+ // generated properties
+ // used only for shadow volumes
+ vec3_t shadoworigin;
+ // culling
+ vec3_t cullmins;
+ vec3_t cullmaxs;
+ // culling
+ //vec_t cullradius;
+ // squared cullradius
+ //vec_t cullradius2;
+
+ // rendering properties, updated each time a light is rendered
+ // this is rtlight->color * d_lightstylevalue
+ vec3_t currentcolor;
+ // this is R_Shadow_Cubemap(rtlight->cubemapname)
+ rtexture_t *currentcubemap;
+
+ // static light info
+ // true if this light should be compiled as a static light
+ int isstatic;
+ // true if this is a compiled world light, cleared if the light changes
+ int compiled;
+ // premade shadow volumes to render for world entity
+ shadowmesh_t *static_meshchain_shadow;
+ // used for visibility testing (more exact than bbox)
+ int static_numleafs;
+ int static_numleafpvsbytes;
+ int *static_leaflist;
+ unsigned char *static_leafpvs;
+ // surfaces seen by light
+ int static_numsurfaces;
+ int *static_surfacelist;
+}
+rtlight_t;
+
+typedef struct dlight_s
+{
+ // destroy light after this time
+ // (dlight only)
+ vec_t die;
+ // the entity that owns this light (can be NULL)
+ // (dlight only)
+ struct entity_render_s *ent;
+ // location
+ // (worldlight: saved to .rtlights file)
+ vec3_t origin;
+ // worldlight orientation
+ // (worldlight only)
+ // (worldlight: saved to .rtlights file)
+ vec3_t angles;
+ // dlight orientation/scaling/location
+ // (dlight only)
+ matrix4x4_t matrix;
+ // color of light
+ // (worldlight: saved to .rtlights file)
+ vec3_t color;
+ // cubemap number to use on this light
+ // (dlight only)
+ int cubemapnum;
+ // cubemap name to use on this light
+ // (worldlight only)
+ // (worldlight: saved to .rtlights file)
+ char cubemapname[64];
+ // make light flash while selected
+ // (worldlight only)
+ int selected;
+ // brightness (not really radius anymore)
+ // (worldlight: saved to .rtlights file)
+ vec_t radius;
+ // drop radius this much each second
+ // (dlight only)
+ vec_t decay;
+ // light style which controls intensity of this light
+ // (worldlight: saved to .rtlights file)
+ int style;
+ // cast shadows
+ // (worldlight: saved to .rtlights file)
+ int shadow;
+ // corona intensity
+ // (worldlight: saved to .rtlights file)
+ vec_t corona;
+ // radius scale of corona to render (1.0 means same as light radius)
+ // (worldlight: saved to .rtlights file)
+ vec_t coronasizescale;
+ // ambient intensity to render
+ // (worldlight: saved to .rtlights file)
+ vec_t ambientscale;
+ // diffuse intensity to render
+ // (worldlight: saved to .rtlights file)
+ vec_t diffusescale;
+ // specular intensity to render
+ // (worldlight: saved to .rtlights file)
+ vec_t specularscale;
+ // LIGHTFLAG_* flags
+ // (worldlight: saved to .rtlights file)
+ int flags;
+ // linked list of world lights
+ // (worldlight only)
+ struct dlight_s *next;
+ // embedded rtlight struct for renderer
+ // (renderer only)
+ rtlight_t rtlight;
+}
+dlight_t;
+
+typedef struct frameblend_s
+{
+ int frame;
+ float lerp;
+}
+frameblend_t;
+
+// LordHavoc: this struct is intended for the renderer but some fields are
+// used by the client.
+typedef struct entity_render_s
+{
+ // location
+ vec3_t origin;
+ // orientation
+ vec3_t angles;
+ // transform matrix for model to world
+ matrix4x4_t matrix;
+ // transform matrix for world to model
+ matrix4x4_t inversematrix;
+ // opacity (alpha) of the model
+ float alpha;
+ // size the model is shown
+ float scale;
+
+ // NULL = no model
+ model_t *model;
+ // current uninterpolated animation frame (for things which do not use interpolation)
+ int frame;
+ // entity shirt and pants colors (-1 if not colormapped)
+ int colormap;
+ // literal colors for renderer
+ vec3_t colormap_pantscolor;
+ vec3_t colormap_shirtcolor;
+ // light, particles, etc
+ int effects;
+ // for Alias models
+ int skinnum;
+ // render flags
+ int flags;
+
+ // colormod tinting of models
+ float colormod[3];
+
+ // interpolated animation
+
+ // frame that the model is interpolating from
+ int frame1;
+ // frame that the model is interpolating to
+ int frame2;
+ // interpolation factor, usually computed from frame2time
+ float framelerp;
+ // time frame1 began playing (for framegroup animations)
+ double frame1time;
+ // time frame2 began playing (for framegroup animations)
+ double frame2time;
+
+ // calculated by the renderer (but not persistent)
+
+ // if visframe == r_framecount, it is visible
+ int visframe;
+ // calculated during R_AddModelEntities
+ vec3_t mins, maxs;
+ // 4 frame numbers (-1 if not used) and their blending scalers (0-1), if interpolation is not desired, use frame instead
+ frameblend_t frameblend[4];
+
+ // current lighting from map
+ vec3_t modellight_ambient;
+ vec3_t modellight_diffuse; // q3bsp
+ vec3_t modellight_lightdir; // q3bsp
+}
+entity_render_t;
+
+typedef struct entity_persistent_s
+{
+ int linkframe;
+
+ vec3_t trail_origin;
+
+ // particle trail
+ float trail_time;
+
+ // muzzleflash fading
+ float muzzleflash;
+
+ // interpolated movement
+
+ // start time of move
+ float lerpstarttime;
+ // time difference from start to end of move
+ float lerpdeltatime;
+ // the move itself, start and end
+ float oldorigin[3];
+ float oldangles[3];
+ float neworigin[3];
+ float newangles[3];
+}
+entity_persistent_t;
+
+typedef struct entity_s
+{
+ qboolean csqc;
+ // baseline state (default values)
+ entity_state_t state_baseline;
+ // previous state (interpolating from this)
+ entity_state_t state_previous;
+ // current state (interpolating to this)
+ entity_state_t state_current;
+
+ // used for regenerating parts of render
+ entity_persistent_t persistent;
+
+ // the only data the renderer should know about
+ entity_render_t render;
+}
+entity_t;
+
+typedef struct usercmd_s
{
vec3_t viewangles;
float forwardmove;
float sidemove;
float upmove;
+
+ vec3_t cursor_screen;
+ vec3_t cursor_start;
+ vec3_t cursor_end;
+ vec3_t cursor_impact;
+ vec3_t cursor_normal;
+ vec_t cursor_fraction;
+ int cursor_entitynumber;
+
+ double time;
+ double receivetime;
+ int buttons;
+ int impulse;
+ int sequence;
+ qboolean applied; // if false we're still accumulating a move
} usercmd_t;
-typedef struct
+typedef struct lightstyle_s
{
int length;
char map[MAX_STYLESTRING];
} lightstyle_t;
-typedef struct
+typedef struct scoreboard_s
{
char name[MAX_SCOREBOARDNAME];
- float entertime;
int frags;
int colors; // two 4 bit fields
+ // QW fields:
+ int qw_userid;
+ char qw_userinfo[MAX_USERINFO_STRING];
+ float qw_entertime;
+ int qw_ping;
+ int qw_packetloss;
+ int qw_spectator;
+ char qw_team[8];
+ char qw_skin[MAX_QPATH];
} scoreboard_t;
-typedef struct
+typedef struct cshift_s
{
- int destcolor[3];
- int percent; // 0-256
+ float destcolor[3];
+ float percent; // 0-256
} cshift_t;
#define CSHIFT_CONTENTS 0
#define CSHIFT_DAMAGE 1
#define CSHIFT_BONUS 2
#define CSHIFT_POWERUP 3
-#define NUM_CSHIFTS 4
+#define CSHIFT_VCSHIFT 4
+#define NUM_CSHIFTS 5
#define NAME_LENGTH 64
#define SIGNONS 4 // signon messages to receive before connected
-#include "r_light.h"
-
-#define MAX_BEAMS 24
-typedef struct
-{
- int entity;
- struct model_s *model;
- float endtime;
- vec3_t start, end;
-}
-beam_t;
-
-#define MAX_MAPSTRING 2048
#define MAX_DEMOS 8
#define MAX_DEMONAME 16
-typedef enum
+typedef enum cactive_e
{
ca_dedicated, // a dedicated server with no ability to start a client
ca_disconnected, // full screen console with no connection
}
cactive_t;
+typedef enum qw_downloadtype_e
+{
+ dl_none,
+ dl_single,
+ dl_skin,
+ dl_model,
+ dl_sound
+}
+qw_downloadtype_t;
+
+typedef enum capturevideoformat_e
+{
+ CAPTUREVIDEOFORMAT_TARGA,
+ CAPTUREVIDEOFORMAT_JPEG,
+ CAPTUREVIDEOFORMAT_RAWRGB,
+ CAPTUREVIDEOFORMAT_RAWYV12
+}
+capturevideoformat_t;
+
//
-// the client_static_t structure is persistant through an arbitrary number
+// the client_static_t structure is persistent through an arbitrary number
// of server connections
//
-typedef struct
+typedef struct client_static_s
{
- cactive_t state;
+ cactive_t state;
-// personalization data sent to server
- char mapstring[MAX_QPATH];
- char spawnparms[MAX_MAPSTRING]; // to restart a level
+ // all client memory allocations go in these pools
+ mempool_t *levelmempool;
+ mempool_t *permanentmempool;
// demo loop control
- int demonum; // -1 = don't play demos
- char demos[MAX_DEMOS][MAX_DEMONAME]; // when not playing
+ // -1 = don't play demos
+ int demonum;
+ // list of demos in loop
+ char demos[MAX_DEMOS][MAX_DEMONAME];
+ // the actively playing demo (set by CL_PlayDemo_f)
+ char demoname[64];
// demo recording info must be here, because record is started before
// entering a map (and clearing client_state_t)
- qboolean demorecording;
- qboolean demoplayback;
- qboolean timedemo;
- int forcetrack; // -1 = use normal cd track
- FILE *demofile;
- int td_lastframe; // to meter out one message a frame
- int td_startframe; // host_framecount at start
- double td_starttime; // realtime at second frame of timedemo (LordHavoc: changed to double)
- qboolean demopaused; // LordHavoc: pausedemo
-
+ qboolean demorecording;
+ qboolean demoplayback;
+ qboolean timedemo;
+ // -1 = use normal cd track
+ int forcetrack;
+ qfile_t *demofile;
+ // to meter out one message a frame
+ int td_lastframe;
+ // host_framecount at start
+ int td_startframe;
+ // realtime at second frame of timedemo (LordHavoc: changed to double)
+ double td_starttime;
+ // LordHavoc: for measuring maxfps
+ double td_minframetime;
+ // LordHavoc: for measuring minfps
+ double td_maxframetime;
+ // LordHavoc: pausedemo
+ qboolean demopaused;
+
+ qboolean connect_trying;
+ int connect_remainingtries;
+ double connect_nextsendtime;
+ lhnetsocket_t *connect_mysocket;
+ lhnetaddress_t connect_address;
+ // protocol version of the server we're connected to
+ // (kept outside client_state_t because it's used between levels)
+ protocolversion_t protocol;
// connection information
- int signon; // 0 to SIGNONS
- struct qsocket_s *netcon;
- sizebuf_t message; // writing buffer to send to server
+ // 0 to SIGNONS
+ int signon;
+ // network connection
+ netconn_t *netcon;
+
+ // quakeworld stuff below
+
+ // value of "qport" cvar at time of connection
+ int qw_qport;
+
+ // current file download buffer (only saved when file is completed)
+ char qw_downloadname[MAX_QPATH];
+ unsigned char *qw_downloadmemory;
+ int qw_downloadmemorycursize;
+ int qw_downloadmemorymaxsize;
+ int qw_downloadnumber;
+ int qw_downloadpercent;
+ qw_downloadtype_t qw_downloadtype;
+
+ // current file upload buffer (for uploading screenshots to server)
+ unsigned char *qw_uploaddata;
+ int qw_uploadsize;
+ int qw_uploadpos;
+
+ // user infostring
+ // this normally contains the following keys in quakeworld:
+ // password spectator name team skin topcolor bottomcolor rate noaim msg *ver *ip
+ char userinfo[MAX_USERINFO_STRING];
+
+ // video capture stuff
+ qboolean capturevideo_active;
+ capturevideoformat_t capturevideo_format;
+ double capturevideo_starttime;
+ double capturevideo_framerate;
+ int capturevideo_soundrate;
+ int capturevideo_frame;
+ unsigned char *capturevideo_buffer;
+ qfile_t *capturevideo_videofile;
+ qfile_t *capturevideo_soundfile;
+ short capturevideo_rgbtoyuvscaletable[3][3][256];
+ unsigned char capturevideo_yuvnormalizetable[3][256];
}
client_static_t;
extern client_static_t cls;
-//
-// the client_state_t structure is wiped completely at every
-// server signon
-//
+typedef struct client_movementqueue_s
+{
+ double time;
+ float frametime;
+ int sequence;
+ float viewangles[3];
+ float move[3];
+ qboolean jump;
+ qboolean crouch;
+}
+client_movementqueue_t;
+
+//[515]: csqc
typedef struct
{
- int movemessages; // since connecting to this server
- // throw out the first couple, so the player
- // doesn't accidentally do something the
- // first frame
- usercmd_t cmd; // last command sent to the server
+ qboolean drawworld;
+ qboolean drawenginesbar;
+ qboolean drawcrosshair;
+}csqc_vidvars_t;
-// information for local display
- int stats[MAX_CL_STATS]; // health, etc
- int items; // inventory bit flags
- float item_gettime[32]; // cl.time of acquiring item, for blinking
- float faceanimtime; // use anim frame if cl.time < this
+typedef struct qw_usercmd_s
+{
+ vec3_t angles;
+ short forwardmove, sidemove, upmove;
+ unsigned char padding1[2];
+ unsigned char msec;
+ unsigned char buttons;
+ unsigned char impulse;
+ unsigned char padding2;
+}
+qw_usercmd_t;
- cshift_t cshifts[NUM_CSHIFTS]; // color shifts for damage, powerups
- cshift_t prev_cshifts[NUM_CSHIFTS]; // and content types
+typedef enum
+{
+ PARTICLE_BILLBOARD = 0,
+ PARTICLE_SPARK = 1,
+ PARTICLE_ORIENTED_DOUBLESIDED = 2,
+ PARTICLE_BEAM = 3
+}
+porientation_t;
-// the client maintains its own idea of view angles, which are
-// sent to the server each frame. The server sets punchangle when
-// the view is temporarliy offset, and an angle reset commands at the start
-// of each level and after teleporting.
- vec3_t mviewangles[2]; // during demo playback viewangles is lerped
- // between these
- vec3_t viewangles;
-
- vec3_t mvelocity[2]; // update by server, used for lean+bob
- // (0 is newest)
- vec3_t velocity; // lerped between mvelocity[0] and [1]
+typedef enum
+{
+ PBLEND_ALPHA = 0,
+ PBLEND_ADD = 1,
+ PBLEND_MOD = 2
+}
+pblend_t;
- vec3_t punchangle; // temporary offset
- vec3_t punchvector; // LordHavoc: origin view kick
+typedef struct particletype_s
+{
+ pblend_t blendmode;
+ porientation_t orientation;
+ qboolean lighting;
+}
+particletype_t;
-// pitch drifting vars
- float idealpitch;
- float pitchvel;
- qboolean nodrift;
- float driftmove;
- double laststop;
+typedef enum
+{
+ pt_alphastatic, pt_static, pt_spark, pt_beam, pt_rain, pt_raindecal, pt_snow, pt_bubble, pt_blood, pt_smoke, pt_decal, pt_entityparticle, pt_total
+}
+ptype_t;
- float viewheight;
- float crouch; // local amount for smoothing stepups
+typedef struct particle_s
+{
+ particletype_t *type;
+ int texnum;
+ vec3_t org;
+ vec3_t vel; // velocity of particle, or orientation of decal, or end point of beam
+ float size;
+ float sizeincrease; // rate of size change per second
+ float alpha; // 0-255
+ float alphafade; // how much alpha reduces per second
+ float time2; // used for snow fluttering and decal fade
+ float bounce; // how much bounce-back from a surface the particle hits (0 = no physics, 1 = stop and slide, 2 = keep bouncing forever, 1.5 is typical)
+ float gravity; // how much gravity affects this particle (1.0 = normal gravity, 0.0 = none)
+ float airfriction; // how much air friction affects this object (objects with a low mass/size ratio tend to get more air friction)
+ float liquidfriction; // how much liquid friction affects this object (objects with a low mass/size ratio tend to get more liquid friction)
+ unsigned char color[4];
+ unsigned short owner; // decal stuck to this entity
+ model_t *ownermodel; // model the decal is stuck to (used to make sure the entity is still alive)
+ vec3_t relativeorigin; // decal at this location in entity's coordinate space
+ vec3_t relativedirection; // decal oriented this way relative to entity's coordinate space
+}
+particle_t;
- qboolean paused; // send over by server
- qboolean onground;
- qboolean inwater;
+//
+// the client_state_t structure is wiped completely at every
+// server signon
+//
+typedef struct client_state_s
+{
+ // true if playing in a local game and no one else is connected
+ int islocalgame;
- int intermission; // don't change view angle, full screen, etc
- int completed_time; // latched at intermission start
+ // when connecting to the server throw out the first couple move messages
+ // so the player doesn't accidentally do something the first frame
+ int movemessages;
- double mtime[2]; // the timestamp of last two messages
- double time; // clients view of time, should be between
- // servertime and oldservertime to generate
- // a lerp point for other data
- double oldtime; // previous cl.time, time-oldtime is used
- // to decay light values and smooth step ups
+ // send a clc_nop periodically until connected
+ float sendnoptime;
- double frametime;
+ // current input to send to the server
+ usercmd_t cmd;
+// information for local display
+ // health, etc
+ int stats[MAX_CL_STATS];
+ // last known inventory bit flags, for blinking
+ int olditems;
+ // cl.time of acquiring item, for blinking
+ float item_gettime[32];
+ // last known STAT_ACTIVEWEAPON
+ int activeweapon;
+ // cl.time of changing STAT_ACTIVEWEAPON
+ float weapontime;
+ // use pain anim frame if cl.time < this
+ float faceanimtime;
+
+ // color shifts for damage, powerups
+ cshift_t cshifts[NUM_CSHIFTS];
+ // and content types
+ cshift_t prev_cshifts[NUM_CSHIFTS];
- float last_received_message; // (realtime) for net trouble icon
+// the client maintains its own idea of view angles, which are
+// sent to the server each frame. The server sets punchangle when
+// the view is temporarily offset, and an angle reset commands at the start
+// of each level and after teleporting.
-//
-// information that is static for the entire time connected to a server
-//
- struct model_s *model_precache[MAX_MODELS];
- struct sfx_s *sound_precache[MAX_SOUNDS];
+ // mviewangles is read from demo
+ // viewangles is either client controlled or lerped from mviewangles
+ vec3_t mviewangles[2], viewangles;
+ // update by server, used by qc to do weapon recoil
+ vec3_t mpunchangle[2], punchangle;
+ // update by server, can be used by mods to kick view around
+ vec3_t mpunchvector[2], punchvector;
+ // update by server, used for lean+bob (0 is newest)
+ vec3_t mvelocity[2], velocity;
+ // update by server, can be used by mods for zooming
+ vec_t mviewzoom[2], viewzoom;
+ // if true interpolation the mviewangles and other interpolation of the
+ // player is disabled until the next network packet
+ // this is used primarily by teleporters, and when spectating players
+ // special checking of the old fixangle[1] is used to differentiate
+ // between teleporting and spectating
+ qboolean fixangle[2];
+
+ // client movement simulation
+ // these fields are only updated by CL_ClientMovement (called by CL_SendMove after parsing each network packet)
+ qboolean movement;
+ // this is set true by svc_time parsing and causes a new movement to be
+ // queued for prediction purposes
+ qboolean movement_needupdate;
+ // indicates the queue has been updated and should be replayed
+ qboolean movement_replay;
+ // timestamps of latest two predicted moves for interpolation
+ double movement_time[2];
+ // simulated data (this is valid even if cl.movement is false)
+ vec3_t movement_origin;
+ vec3_t movement_oldorigin;
+ vec3_t movement_velocity;
+ // queue of proposed moves
+ int movement_numqueue;
+ client_movementqueue_t movement_queue[64];
+ int movesequence;
+ int servermovesequence;
- char levelname[40]; // for display on solo scoreboard
- int viewentity; // cl_entitites[cl.viewentity] = player
- int maxclients;
- int gametype;
+// pitch drifting vars
+ float idealpitch;
+ float pitchvel;
+ qboolean nodrift;
+ float driftmove;
+ double laststop;
+
+//[515]: added for csqc purposes
+ float sensitivityscale;
+ csqc_vidvars_t csqc_vidvars; //[515]: these parms must be set to true by default
+ qboolean csqc_wantsmousemove;
+ struct model_s *csqc_model_precache[MAX_MODELS];
+
+ // local amount for smoothing stepups
+ //float crouch;
+
+ // sent by server
+ qboolean paused;
+ qboolean onground;
+ qboolean inwater;
+
+ // used by bob
+ qboolean oldonground;
+ double lastongroundtime;
+ double hitgroundtime;
+
+ // don't change view angle, full screen, etc
+ int intermission;
+ // latched at intermission start
+ double completed_time;
+
+ // the timestamp of the last two messages
+ double mtime[2];
+
+ // clients view of time, time should be between mtime[0] and mtime[1] to
+ // generate a lerp point for other data, oldtime is the previous frame's
+ // value of time, frametime is the difference between time and oldtime
+ double time, oldtime;
+ // how long it has been since the previous client frame in real time
+ // (not game time, for that use cl.time - cl.oldtime)
+ double realframetime;
+
+ // copy of realtime from last recieved message, for net trouble icon
+ float last_received_message;
+
+// information that is static for the entire time connected to a server
+ struct model_s *model_precache[MAX_MODELS];
+ struct sfx_s *sound_precache[MAX_SOUNDS];
+
+ // FIXME: this is a lot of memory to be keeping around, this really should be dynamically allocated and freed somehow
+ char model_name[MAX_MODELS][MAX_QPATH];
+ char sound_name[MAX_SOUNDS][MAX_QPATH];
+
+ // for display on solo scoreboard
+ char levelname[40];
+ // cl_entitites[cl.viewentity] = player
+ int viewentity;
+ // the real player entity (normally same as viewentity,
+ // different than viewentity if mod uses chasecam or other tricks)
+ int playerentity;
+ // max players that can be in this game
+ int maxclients;
+ // type of game (deathmatch, coop, singleplayer)
+ int gametype;
+
+ // models and sounds used by engine code (particularly cl_parse.c)
+ model_t *model_bolt;
+ model_t *model_bolt2;
+ model_t *model_bolt3;
+ model_t *model_beam;
+ sfx_t *sfx_wizhit;
+ sfx_t *sfx_knighthit;
+ sfx_t *sfx_tink1;
+ sfx_t *sfx_ric1;
+ sfx_t *sfx_ric2;
+ sfx_t *sfx_ric3;
+ sfx_t *sfx_r_exp3;
// refresh related state
- struct model_s *worldmodel; // cl_entitites[0].model
-// int num_entities; // held in cl_entities array
- int num_statics; // held in cl_staticentities array
- entity_t viewent; // the gun model
- int cdtrack, looptrack; // cd audio
+ // cl_entitites[0].model
+ struct model_s *worldmodel;
+
+ // the gun model
+ entity_t viewent;
+
+ // cd audio
+ int cdtrack, looptrack;
// frag scoreboard
- scoreboard_t *scores; // [cl.maxclients]
+
+ // [cl.maxclients]
+ scoreboard_t *scores;
+
+ // entity database stuff
+ // latest received entity frame numbers
+#define LATESTFRAMENUMS 3
+ int latestframenums[LATESTFRAMENUMS];
+ entityframe_database_t *entitydatabase;
+ entityframe4_database_t *entitydatabase4;
+ entityframeqw_database_t *entitydatabaseqw;
+
+ // keep track of quake entities because they need to be killed if they get stale
+ int lastquakeentity;
+ unsigned char isquakeentity[MAX_EDICTS];
+
+ // bounding boxes for clientside movement
+ vec3_t playerstandmins;
+ vec3_t playerstandmaxs;
+ vec3_t playercrouchmins;
+ vec3_t playercrouchmaxs;
+
+ int max_entities;
+ int max_csqcentities;
+ int max_static_entities;
+ int max_temp_entities;
+ int max_effects;
+ int max_beams;
+ int max_dlights;
+ int max_lightstyle;
+ int max_brushmodel_entities;
+ int max_particles;
+
+ entity_t *entities;
+ entity_t *csqcentities; //[515]: csqc
+ unsigned char *entities_active;
+ unsigned char *csqcentities_active; //[515]: csqc
+ entity_t *static_entities;
+ entity_t *temp_entities;
+ cl_effect_t *effects;
+ beam_t *beams;
+ dlight_t *dlights;
+ lightstyle_t *lightstyle;
+ int *brushmodel_entities;
+ particle_t *particles;
+
+ int num_entities;
+ int num_csqcentities; //[515]: csqc
+ int num_static_entities;
+ int num_temp_entities;
+ int num_brushmodel_entities;
+ int num_effects;
+ int num_beams;
+ int num_dlights;
+ int num_particles;
+
+ int free_particle;
+
+ // quakeworld stuff
+
+ // local copy of the server infostring
+ char qw_serverinfo[MAX_SERVERINFO_STRING];
+
+ // time of last qw "pings" command sent to server while showing scores
+ double last_ping_request;
+
+ // used during connect
+ int qw_servercount;
+
+ // updated from serverinfo
+ int qw_teamplay;
+
+ // indicates whether the player is spectating
+ qboolean qw_spectator;
+
+ // movement parameters for client prediction
+ float qw_movevars_gravity;
+ float qw_movevars_stopspeed;
+ float qw_movevars_maxspeed; // can change during play
+ float qw_movevars_spectatormaxspeed;
+ float qw_movevars_accelerate;
+ float qw_movevars_airaccelerate;
+ float qw_movevars_wateraccelerate;
+ float qw_movevars_friction;
+ float qw_movevars_waterfriction;
+ float qw_movevars_entgravity; // can change during play
+
+ // models used by qw protocol
+ int qw_modelindex_spike;
+ int qw_modelindex_player;
+ int qw_modelindex_flag;
+ int qw_modelindex_s_explod;
+
+ vec3_t qw_intermission_origin;
+ vec3_t qw_intermission_angles;
+
+ // 255 is the most nails the QW protocol could send
+ int qw_num_nails;
+ vec_t qw_nails[255][6];
+
+ float qw_weaponkick;
+
+ int qw_validsequence;
+
+ qw_usercmd_t qw_moves[QW_UPDATE_BACKUP];
+
+ int qw_deltasequence[QW_UPDATE_BACKUP];
}
client_state_t;
-
//
// cvars
//
extern cvar_t cl_name;
extern cvar_t cl_color;
+extern cvar_t cl_rate;
extern cvar_t cl_pmodel;
+extern cvar_t cl_playermodel;
+extern cvar_t cl_playerskin;
+
+extern cvar_t rcon_password;
+extern cvar_t rcon_address;
extern cvar_t cl_upspeed;
extern cvar_t cl_forwardspeed;
extern cvar_t cl_autofire;
+extern cvar_t csqc_progname; //[515]: csqc crc check and right csprogs name according to progs.dat
+extern cvar_t csqc_progcrc;
+
extern cvar_t cl_shownet;
extern cvar_t cl_nolerp;
extern cvar_t m_forward;
extern cvar_t m_side;
+extern cvar_t cl_autodemo;
+extern cvar_t cl_autodemo_nameformat;
+
+extern cvar_t r_draweffects;
-// LordHavoc: raised these from 64 and 128 to 512 and 256
-#define MAX_TEMP_ENTITIES 512 // lightning bolts, effects, etc
-#define MAX_STATIC_ENTITIES 256 // torches, etc
+extern cvar_t cl_explosions_alpha_start;
+extern cvar_t cl_explosions_alpha_end;
+extern cvar_t cl_explosions_size_start;
+extern cvar_t cl_explosions_size_end;
+extern cvar_t cl_explosions_lifetime;
+extern cvar_t cl_stainmaps;
+extern cvar_t cl_stainmaps_clearonload;
+
+extern cvar_t cl_prydoncursor;
extern client_state_t cl;
-// FIXME, allocate dynamically
-extern entity_t cl_entities[MAX_EDICTS];
-extern entity_t cl_static_entities[MAX_STATIC_ENTITIES];
-extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
-extern dlight_t cl_dlights[MAX_DLIGHTS];
-extern entity_t cl_temp_entities[MAX_TEMP_ENTITIES];
-extern beam_t cl_beams[MAX_BEAMS];
+extern void CL_AllocDlight (entity_render_t *ent, matrix4x4_t *matrix, float radius, float red, float green, float blue, float decay, float lifetime, int cubemapnum, int style, int shadowenable, vec_t corona, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags);
//=============================================================================
//
// cl_main
//
-extern void CL_AllocDlight (entity_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime);
-extern void CL_DecayLights (void);
-extern void CL_Init (void);
+void CL_Shutdown (void);
+void CL_Init (void);
+
+void CL_EstablishConnection(const char *host);
-extern void CL_EstablishConnection (char *host);
-extern void CL_Signon1 (void);
-extern void CL_Signon2 (void);
-extern void CL_Signon3 (void);
-extern void CL_Signon4 (void);
+void CL_Disconnect (void);
+void CL_Disconnect_f (void);
-extern void CL_Disconnect (void);
-extern void CL_Disconnect_f (void);
-extern void CL_NextDemo (void);
+void CL_BoundingBoxForEntity(entity_render_t *ent);
-// LordHavoc: raised this from 256 to the maximum possible number of entities visible
-#define MAX_VISEDICTS (MAX_EDICTS + MAX_STATIC_ENTITIES + MAX_TEMP_ENTITIES)
-extern int cl_numvisedicts;
-extern entity_t *cl_visedicts[MAX_VISEDICTS];
+extern cvar_t cl_beams_polygons;
+extern cvar_t cl_beams_relative;
+extern cvar_t cl_beams_lightatend;
//
// cl_input
//
-typedef struct
+typedef struct kbutton_s
{
int down[2]; // key nums holding it down
int state; // low bit is down state
extern kbutton_t in_strafe;
extern kbutton_t in_speed;
-extern void CL_InitInput (void);
-extern void CL_SendCmd (void);
-extern void CL_SendMove (usercmd_t *cmd);
+void CL_InitInput (void);
+void CL_SendMove (void);
-extern void CL_ParseTEnt (void);
-extern void CL_UpdateTEnts (void);
-extern void CL_DoEffects (void);
+void CL_ValidateState(entity_state_t *s);
+void CL_MoveLerpEntityStates(entity_t *ent);
+void CL_LerpUpdate(entity_t *e);
+void CL_ParseTEnt (void);
+void CL_RelinkBeams (void);
-extern entity_t *CL_NewTempEntity (void);
+void CL_ClearTempEntities (void);
+entity_t *CL_NewTempEntity (void);
-extern void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate);
+void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate);
-extern void CL_ClearState (void);
+void CL_ClearState (void);
+void CL_ExpandEntities(int num);
+void CL_SetInfo(const char *key, const char *value, qboolean send, qboolean allowstarkey, qboolean allowmodel, qboolean quiet);
-extern int CL_ReadFromServer (void);
-extern void CL_WriteToServer (usercmd_t *cmd);
-extern void CL_BaseMove (usercmd_t *cmd);
+int CL_ReadFromServer (void);
+void CL_WriteToServer (void);
+void CL_Move (void);
+extern qboolean cl_ignoremousemove;
-extern float CL_KeyState (kbutton_t *key);
-extern char *Key_KeynumToString (int keynum);
+float CL_KeyState (kbutton_t *key);
+const char *Key_KeynumToString (int keynum);
+int Key_StringToKeynum (const char *str);
//
// cl_demo.c
//
-extern void CL_StopPlayback (void);
-extern int CL_GetMessage (void);
+void CL_StopPlayback(void);
+void CL_ReadDemoMessage(void);
+void CL_WriteDemoMessage(void);
-extern void CL_Stop_f (void);
-extern void CL_Record_f (void);
-extern void CL_PlayDemo_f (void);
-extern void CL_TimeDemo_f (void);
+void CL_NextDemo(void);
+void CL_Stop_f(void);
+void CL_Record_f(void);
+void CL_PlayDemo_f(void);
+void CL_TimeDemo_f(void);
//
// cl_parse.c
//
-extern void CL_Parse_Init(void);
-extern void CL_ParseServerMessage(void);
-extern void CL_BitProfile_f(void);
+void CL_Parse_Init(void);
+void CL_Parse_Shutdown(void);
+void CL_ParseServerMessage(void);
+void CL_Parse_DumpPacket(void);
+void CL_Parse_ErrorCleanUp(void);
+void QW_CL_StartUpload(unsigned char *data, int size);
+extern cvar_t qport;
//
// view
//
-extern void V_StartPitchDrift (void);
-extern void V_StopPitchDrift (void);
-
-extern void V_RenderView (void);
-extern void V_UpdateBlends (void);
-extern void V_Register (void);
-extern void V_ParseDamage (void);
-extern void V_SetContentsColor (int contents);
+void V_StartPitchDrift (void);
+void V_StopPitchDrift (void);
+void V_Init (void);
+float V_CalcRoll (vec3_t angles, vec3_t velocity);
+void V_UpdateBlends (void);
+void V_ParseDamage (void);
//
-// cl_tent
+// cl_part
//
-extern void CL_InitTEnts (void);
-extern void CL_SignonReply (void);
+
+extern cvar_t cl_particles;
+extern cvar_t cl_particles_quality;
+extern cvar_t cl_particles_size;
+extern cvar_t cl_particles_quake;
+extern cvar_t cl_particles_blood;
+extern cvar_t cl_particles_blood_alpha;
+extern cvar_t cl_particles_blood_bloodhack;
+extern cvar_t cl_particles_bulletimpacts;
+extern cvar_t cl_particles_explosions_bubbles;
+extern cvar_t cl_particles_explosions_smoke;
+extern cvar_t cl_particles_explosions_sparks;
+extern cvar_t cl_particles_explosions_shell;
+extern cvar_t cl_particles_smoke;
+extern cvar_t cl_particles_smoke_alpha;
+extern cvar_t cl_particles_smoke_alphafade;
+extern cvar_t cl_particles_sparks;
+extern cvar_t cl_particles_bubbles;
+extern cvar_t cl_decals;
+extern cvar_t cl_decals_time;
+extern cvar_t cl_decals_fadetime;
+
+void CL_Particles_Clear(void);
+void CL_Particles_Init(void);
+void CL_Particles_Shutdown(void);
+
+typedef enum effectnameindex_s
+{
+ EFFECT_NONE,
+ EFFECT_TE_GUNSHOT,
+ EFFECT_TE_GUNSHOTQUAD,
+ EFFECT_TE_SPIKE,
+ EFFECT_TE_SPIKEQUAD,
+ EFFECT_TE_SUPERSPIKE,
+ EFFECT_TE_SUPERSPIKEQUAD,
+ EFFECT_TE_WIZSPIKE,
+ EFFECT_TE_KNIGHTSPIKE,
+ EFFECT_TE_VORESPIKE,
+ EFFECT_TE_EXPLOSION,
+ EFFECT_TE_EXPLOSIONQUAD,
+ EFFECT_TE_TAREXPLOSION,
+ EFFECT_TE_TELEPORT,
+ EFFECT_TE_LAVASPLASH,
+ EFFECT_TE_SMALLFLASH,
+ EFFECT_TE_FLAMEJET,
+ EFFECT_EF_FLAME,
+ EFFECT_TE_BLOOD,
+ EFFECT_TE_SPARK,
+ EFFECT_TE_PLASMABURN,
+ EFFECT_TE_TEI_G3,
+ EFFECT_TE_TEI_SMOKE,
+ EFFECT_TE_TEI_BIGEXPLOSION,
+ EFFECT_TE_TEI_PLASMAHIT,
+ EFFECT_EF_STARDUST,
+ EFFECT_TR_ROCKET,
+ EFFECT_TR_GRENADE,
+ EFFECT_TR_BLOOD,
+ EFFECT_TR_WIZSPIKE,
+ EFFECT_TR_SLIGHTBLOOD,
+ EFFECT_TR_KNIGHTSPIKE,
+ EFFECT_TR_VORESPIKE,
+ EFFECT_TR_NEHAHRASMOKE,
+ EFFECT_TR_NEXUIZPLASMA,
+ EFFECT_TR_GLOWTRAIL,
+ EFFECT_SVC_PARTICLE,
+ EFFECT_TOTAL
+}
+effectnameindex_t;
+
+int CL_ParticleEffectIndexForName(const char *name);
+const char *CL_ParticleEffectNameForIndex(int i);
+void CL_ParticleEffect(int effectindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor);
+void CL_ParseParticleEffect (void);
+void CL_ParticleCube (const vec3_t mins, const vec3_t maxs, const vec3_t dir, int count, int colorbase, vec_t gravity, vec_t randomvel);
+void CL_ParticleRain (const vec3_t mins, const vec3_t maxs, const vec3_t dir, int count, int colorbase, int type);
+void CL_EntityParticles (const entity_t *ent);
+void CL_ParticleExplosion (const vec3_t org);
+void CL_ParticleExplosion2 (const vec3_t org, int colorStart, int colorLength);
+void CL_MoveParticles(void);
+void R_MoveExplosions(void);
+void R_NewExplosion(const vec3_t org);
+
+#include "cl_screen.h"
+
+#define NUMCROSSHAIRS 32
+extern cachepic_t *r_crosshairs[NUMCROSSHAIRS+1];
+
+typedef struct refdef_s
+{
+ // area to render in
+ int x, y, width, height;
+ float frustum_x, frustum_y;
+
+ // these are set for water warping before
+ // frustum_x/frustum_y are calculated
+ float frustumscale_x, frustumscale_y;
+
+ // view transform
+ matrix4x4_t viewentitymatrix;
+
+ // which color components to allow (for anaglyph glasses)
+ int colormask[4];
+
+ // fullscreen color blend
+ float viewblend[4];
+
+ // whether to call S_ExtraUpdate during render to reduce sound chop
+ qboolean extraupdate;
+
+ // client gameworld time for rendering time based effects
+ double time;
+
+ // the world
+ entity_render_t *worldentity;
+
+ // same as worldentity->model
+ model_t *worldmodel;
+
+ // renderable entities (excluding world)
+ entity_render_t **entities;
+ int numentities;
+ int maxentities;
+
+ // renderable dynamic lights
+ dlight_t *lights[MAX_DLIGHTS];
+ int numlights;
+
+ // 8.8bit fixed point intensities for light styles
+ // controls intensity of dynamic lights and lightmap layers
+ unsigned short lightstylevalue[256]; // 8.8 fraction of base light value
+
+ qboolean draw2dstage;
+}
+refdef_t;
+
+extern refdef_t r_refdef;
+
+#endif
+