]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - client.h
reduced client memory usage by 29MB by making cl_max_entities dynamic (starts out...
[xonotic/darkplaces.git] / client.h
index a2fccefb2e17f8b69e260ba4e729658cc5d9dcfd..708c8f69a994e5ee400db507b1f78d0d17350243 100644 (file)
--- a/client.h
+++ b/client.h
@@ -19,6 +19,205 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 // client.h
 
+#ifndef CLIENT_H
+#define CLIENT_H
+
+#include "matrixlib.h"
+
+// LordHavoc: 256 dynamic lights
+#define MAX_DLIGHTS 256
+// LordHavoc: this affects the lighting scale of the whole game
+#define LIGHTOFFSET 1024.0f
+// max lights shining on one entity
+#define MAXENTLIGHTS 128
+
+// flags for rtlight rendering
+#define LIGHTFLAG_NORMALMODE 1
+#define LIGHTFLAG_REALTIMEMODE 2
+
+extern int cl_max_entities;
+extern int cl_max_static_entities;
+extern int cl_max_temp_entities;
+extern int cl_max_effects;
+extern int cl_max_beams;
+
+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
+{
+       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;
+       // based on worldtolight this transforms -1 to +1 to 0 to 1 for purposes
+       // of attenuation texturing in full 3D (Z result often ignored)
+       matrix4x4_t matrix_worldtoattenuationxyz;
+       // this transforms only the Z to S, and T is always 0.5
+       matrix4x4_t matrix_worldtoattenuationz;
+       // 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;
+
+       // lightmap renderer stuff (remove someday!)
+       // the size of the light
+       vec_t lightmap_cullradius;
+       // the size of the light, squared
+       vec_t lightmap_cullradius2;
+       // the brightness of the light
+       vec3_t lightmap_light;
+       // to avoid sudden brightness change at cullradius, subtract this
+       vec_t lightmap_subtract;
+
+       // 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 and lit surfaces to render for world entity
+       shadowmesh_t *static_meshchain_shadow;
+       shadowmesh_t *static_meshchain_light;
+       // used for visibility testing (more exact than bbox)
+       int static_numclusters;
+       int static_numclusterpvsbytes;
+       int *static_clusterlist;
+       qbyte *static_clusterpvs;
+}
+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;
@@ -26,13 +225,18 @@ typedef struct frameblend_s
 }
 frameblend_t;
 
-// LordHavoc: nothing in this structure is persistant, it may be overwritten by the client every frame, for persistant data use entity_lerp_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
@@ -51,14 +255,17 @@ typedef struct entity_render_s
        // render flags
        int flags;
 
-       // these are copied from the persistent data
+       // 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
-       double framelerp;
+       float framelerp;
        // time frame1 began playing (for framegroup animations)
        double frame1time;
        // time frame2 began playing (for framegroup animations)
@@ -72,36 +279,39 @@ typedef struct entity_render_s
        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];
+
+       // caching results of static light traces (this is semi-persistent)
+       double entlightstime;
+       vec3_t entlightsorigin;
+       int entlightsframe;
+       int numentlights;
+       unsigned short entlights[MAXENTLIGHTS];
 }
 entity_render_t;
 
 typedef struct entity_persistent_s
 {
-       // particles
+       int linkframe;
 
-       // trail rendering
        vec3_t trail_origin;
-       float trail_time;
 
-       // effects
+       // particle trail
+       float trail_time;
 
        // muzzleflash fading
        float muzzleflash;
 
-       // interpolated animation
-
-       // lerp resets when model changes
-       int modelindex;
-       // frame that the model is interpolating from
-       int frame1;
-       // frame that the model is interpolating to
-       int frame2;
-       // interpolation factor, usually computed from frame2time
-       double framelerp;
-       // time frame1 began playing (for framegroup animations)
-       double frame1time;
-       // time frame2 began playing (for framegroup animations)
-       double frame2time;
+       // 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;
 
@@ -130,6 +340,14 @@ typedef struct
        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;
 } usercmd_t;
 
 typedef struct
@@ -141,7 +359,6 @@ typedef struct
 typedef struct
 {
        char    name[MAX_SCOREBOARDNAME];
-       float   entertime;
        int             frags;
        int             colors; // two 4 bit fields
 } scoreboard_t;
@@ -156,7 +373,8 @@ typedef struct
 #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
 
@@ -167,17 +385,6 @@ typedef struct
 
 #define        SIGNONS         4                       // signon messages to receive before connected
 
-#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
 
@@ -190,38 +397,55 @@ typedef enum
 cactive_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
 {
-       cactive_t       state;
-
-// personalization data sent to server
-       char            mapstring[MAX_QPATH];
-       char            spawnparms[MAX_MAPSTRING];      // to restart a level
+       cactive_t state;
 
 // 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
-       QFile           *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;
 
 // 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;
+       // writing buffer to send to server
+       sizebuf_t message;
 }
 client_static_t;
 
@@ -233,95 +457,127 @@ extern client_static_t   cls;
 //
 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
-       float           sendnoptime;    // send a clc_nop periodically until connected
-       usercmd_t       cmd;                    // last command sent to the server
+       // true if playing in a local game and no one else is connected
+       int islocalgame;
 
-// 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
+       // 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;
+
+       // send a clc_nop periodically until connected
+       float sendnoptime;
+
+       // current input to send to the server
+       usercmd_t cmd;
 
-       cshift_t        cshifts[NUM_CSHIFTS];   // color shifts for damage, powerups
-       cshift_t        prev_cshifts[NUM_CSHIFTS];      // and content types
+// 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];
 
 // 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
+// the view is temporarily 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]
 
-       vec3_t          punchangle;             // temporary offset
-       vec3_t          punchvector;    // LordHavoc: origin view kick
+       // 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;
 
 // pitch drifting vars
-       float           idealpitch;
-       float           pitchvel;
-       qboolean        nodrift;
-       float           driftmove;
-       double          laststop;
-
-       float           viewheight;
-       float           crouch;                 // local amount for smoothing stepups
+       float idealpitch;
+       float pitchvel;
+       qboolean nodrift;
+       float driftmove;
+       double laststop;
 
-       qboolean        paused;                 // send over by server
-       qboolean        onground;
-       qboolean        inwater;
+       // local amount for smoothing stepups
+       //float crouch;
 
-       int                     intermission;   // don't change view angle, full screen, etc
-       int                     completed_time; // latched at intermission start
+       // sent by server
+       qboolean paused;
+       qboolean onground;
+       qboolean inwater;
 
-       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
+       // don't change view angle, full screen, etc
+       int intermission;
+       // latched at intermission start
+       int completed_time;
 
-       double          frametime;
+       // 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, frametime;
 
-       float           last_received_message;  // (realtime) for net trouble icon
+       // 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];
-
-       char            levelname[40];  // for display on solo scoreboard
-       int                     viewentity;             // cl_entitites[cl.viewentity] = player
-       int                     maxclients;
-       int                     gametype;
+       struct model_s *model_precache[MAX_MODELS];
+       struct sfx_s *sound_precache[MAX_SOUNDS];
+
+       // 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;
 
 // 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]
 
-       vec3_t          viewentorigin;
-       float           viewzoom;                       // LordHavoc: sniping zoom, QC controlled
-       float           viewzoomold, viewzoomnew; // for interpolation
+       // [cl.maxclients]
+       scoreboard_t *scores;
+
+       // protocol version of the server we're connected to
+       int protocol;
 
        // entity database stuff
-       vec3_t          viewentoriginold, viewentoriginnew;
-       entity_database_t entitydatabase;
+       // latest received entity frame numbers
+#define LATESTFRAMENUMS 3
+       int latestframenums[LATESTFRAMENUMS];
+       entityframe_database_t *entitydatabase;
+       entityframe4_database_t *entitydatabase4;
 }
 client_state_t;
 
@@ -332,7 +588,10 @@ extern mempool_t *cl_scores_mempool;
 //
 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 cl_upspeed;
 extern cvar_t cl_forwardspeed;
@@ -363,21 +622,40 @@ extern cvar_t m_yaw;
 extern cvar_t m_forward;
 extern cvar_t m_side;
 
+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 client_state_t cl;
+extern cvar_t cl_prydoncursor;
+
+// these are updated by CL_ClearState
+extern int cl_num_entities;
+extern int cl_num_static_entities;
+extern int cl_num_temp_entities;
+extern int cl_num_brushmodel_entities;
+
+extern mempool_t *cl_entities_mempool;
+extern entity_t *cl_entities;
+extern qbyte *cl_entities_active;
+extern entity_t *cl_static_entities;
+extern entity_t *cl_temp_entities;
+extern entity_render_t **cl_brushmodel_entities;
+extern cl_effect_t *cl_effects;
+extern beam_t *cl_beams;
+extern dlight_t *cl_dlights;
+extern lightstyle_t *cl_lightstyle;
 
-// 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 entity_t                cl_temp_entities[MAX_TEMP_ENTITIES];
-extern beam_t                  cl_beams[MAX_BEAMS];
 
-#include "cl_light.h"
+extern client_state_t cl;
+
+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);
+extern void CL_DecayLights (void);
 
 //=============================================================================
 
@@ -385,13 +663,20 @@ extern    beam_t                  cl_beams[MAX_BEAMS];
 // cl_main
 //
 
+void CL_Shutdown (void);
 void CL_Init (void);
 
-void CL_EstablishConnection (char *host);
+void CL_EstablishConnection(const char *host);
 
 void CL_Disconnect (void);
 void CL_Disconnect_f (void);
 
+void CL_BoundingBoxForEntity(entity_render_t *ent);
+
+extern cvar_t cl_beams_polygons;
+extern cvar_t cl_beams_relative;
+extern cvar_t cl_beams_lightatend;
+
 //
 // cl_input
 //
@@ -408,45 +693,52 @@ extern    kbutton_t       in_speed;
 
 void CL_InitInput (void);
 void CL_SendCmd (void);
-void CL_SendMove (usercmd_t *cmd);
+void CL_SendMove (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_UpdateTEnts (void);
+void CL_RelinkBeams (void);
 
+void CL_ClearTempEntities (void);
 entity_t *CL_NewTempEntity (void);
 
 void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate);
 
 void CL_ClearState (void);
+void CL_ExpandEntities(int num);
 
 
 int  CL_ReadFromServer (void);
-void CL_WriteToServer (usercmd_t *cmd);
-void CL_BaseMove (usercmd_t *cmd);
+void CL_WriteToServer (void);
+void CL_BaseMove (void);
 
 
 float CL_KeyState (kbutton_t *key);
-char *Key_KeynumToString (int keynum);
+const char *Key_KeynumToString (int keynum);
+int Key_StringToKeynum (const char *str);
 
 //
 // cl_demo.c
 //
-void CL_StopPlayback (void);
-int CL_GetMessage (void);
+void CL_StopPlayback(void);
+void CL_ReadDemoMessage(void);
+void CL_WriteDemoMessage(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);
+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
 //
 void CL_Parse_Init(void);
+void CL_Parse_Shutdown(void);
 void CL_ParseServerMessage(void);
-void CL_BitProfile_f(void);
+void CL_Parse_DumpPacket(void);
 
 //
 // view
@@ -469,35 +761,37 @@ void CL_InitTEnts (void);
 // cl_part
 //
 
-#define PARTICLE_INVALID 0
-#define PARTICLE_BILLBOARD 1
-#define PARTICLE_UPRIGHT_FACING 2
-#define PARTICLE_ORIENTED_DOUBLESIDED 3
-
-/*
-typedef struct renderparticle_s
-{
-       int tex;
-       int orientation;
-       int additive;
-       int dynlight;
-       float scalex;
-       float scaley;
-       float org[3];
-       float dir[3];
-       float color[4];
-}
-renderparticle_t;
-*/
+extern cvar_t cl_particles;
+extern cvar_t cl_particles_quality;
+extern cvar_t cl_particles_size;
+extern cvar_t cl_particles_bloodshowers;
+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);
 
 void CL_ParseParticleEffect (void);
 void CL_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count);
-void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent);
-void CL_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent);
-void CL_SparkShower (vec3_t org, vec3_t dir, int count);
+void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *ent);
+void CL_SparkShower (vec3_t org, vec3_t dir, int count, vec_t gravityscale);
+void CL_Smoke (vec3_t org, vec3_t dir, int count);
+void CL_BulletMark (vec3_t org);
 void CL_PlasmaBurn (vec3_t org);
 void CL_BloodPuff (vec3_t org, vec3_t vel, int count);
 void CL_Stardust (vec3_t mins, vec3_t maxs, int count);
@@ -508,49 +802,60 @@ void CL_ParticleCube (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int color
 void CL_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int colorbase, int type);
 void CL_EntityParticles (entity_t *ent);
 void CL_BlobExplosion (vec3_t org);
-void CL_ParticleExplosion (vec3_t org, int smoke);
+void CL_ParticleExplosion (vec3_t org);
 void CL_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength);
 void CL_LavaSplash (vec3_t org);
 void CL_TeleportSplash (vec3_t org);
+void CL_BeamParticle (const vec3_t start, const vec3_t end, vec_t radius, float red, float green, float blue, float alpha, float lifetime);
+void CL_Tei_Smoke(const vec3_t pos, const vec3_t dir, int count);
+void CL_Tei_PlasmaHit(const vec3_t pos, const vec3_t dir, int count);
 void CL_MoveParticles(void);
 void R_MoveExplosions(void);
 void R_NewExplosion(vec3_t org);
 
-// if contents is not zero, it will impact on content changes
-// (leafs matching contents are considered empty, others are solid)
-extern int traceline_endcontents; // set by TraceLine
-// need to call this sometime before using TraceLine with hitbmodels
-void TraceLine_ScanForBModels(void);
-float TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels);
-
 #include "cl_screen.h"
 
-#define MAX_VISEDICTS (MAX_EDICTS + MAX_STATIC_ENTITIES + MAX_TEMP_ENTITIES)
-
 typedef struct
 {
        // area to render in
        int x, y, width, height;
        float fov_x, fov_y;
 
-       // view point
-       vec3_t vieworg;
-       vec3_t viewangles;
+       // these are set for water warping before
+       // fov_x/fov_y are calculated
+       float fovscale_x, fovscale_y;
+
+       // view transform
+       matrix4x4_t viewentitymatrix;
+
+       // which color components to allow (for anaglyph glasses)
+       int colormask[4];
 
        // fullscreen color blend
        float viewblend[4];
 
-       // weapon model
-       entity_render_t viewent;
+       // whether to call S_ExtraUpdate during render to reduce sound chop
+       qboolean extraupdate;
 
-       int numentities;
-       entity_render_t **entities;
+       // client gameworld time for rendering time based effects
+       double time;
 
-       //int numparticles;
-       //struct renderparticle_s *particles;
+       // the world
+       entity_render_t *worldentity;
 
-       qbyte drawqueue[MAX_DRAWQUEUE];
+       // same as worldentity->model
+       model_t *worldmodel;
+
+       // renderable entities (excluding world)
+       entity_render_t **entities;
+       int numentities;
+       int maxentities;
+
+       // 2D art drawing queue
+       // TODO: get rid of this
+       qbyte *drawqueue;
        int drawqueuesize;
+       int maxdrawqueuesize;
 }
 refdef_t;
 
@@ -559,3 +864,6 @@ refdef_t r_refdef;
 extern mempool_t *cl_refdef_mempool;
 
 #include "cgamevm.h"
+
+#endif
+