]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - client.h
Just in case, make QW sequence numbers unsigned too.
[xonotic/darkplaces.git] / client.h
index 8c3522363fd24dd53056037a07abc29924bc5bae..d9facec2aec6c7a53678834bc642d0cd27b186f3 100644 (file)
--- a/client.h
+++ b/client.h
@@ -23,23 +23,221 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define CLIENT_H
 
 #include "matrixlib.h"
+#include "snd_main.h"
 
-// LordHavoc: 256 dynamic lights
-#define MAX_DLIGHTS 256
-
-// this is the maximum number of input packets that can be lost without a
-// misprediction
-#define CL_MAX_USERCMDS 16
+// NOTE: r_stat_name[] must match this indexing
+typedef enum r_stat_e
+{
+       r_stat_timedelta,
+       r_stat_quality,
+       r_stat_renders,
+       r_stat_entities,
+       r_stat_entities_surfaces,
+       r_stat_entities_triangles,
+       r_stat_world_leafs,
+       r_stat_world_portals,
+       r_stat_world_surfaces,
+       r_stat_world_triangles,
+       r_stat_lightmapupdates,
+       r_stat_lightmapupdatepixels,
+       r_stat_particles,
+       r_stat_drawndecals,
+       r_stat_totaldecals,
+       r_stat_draws,
+       r_stat_draws_vertices,
+       r_stat_draws_elements,
+       r_stat_lights,
+       r_stat_lights_clears,
+       r_stat_lights_scissored,
+       r_stat_lights_lighttriangles,
+       r_stat_lights_shadowtriangles,
+       r_stat_lights_dynamicshadowtriangles,
+       r_stat_bouncegrid_lights,
+       r_stat_bouncegrid_particles,
+       r_stat_bouncegrid_traces,
+       r_stat_bouncegrid_hits,
+       r_stat_bouncegrid_splats,
+       r_stat_bouncegrid_bounces,
+       r_stat_photoncache_animated,
+       r_stat_photoncache_cached,
+       r_stat_photoncache_traced,
+       r_stat_bloom,
+       r_stat_bloom_copypixels,
+       r_stat_bloom_drawpixels,
+       r_stat_indexbufferuploadcount,
+       r_stat_indexbufferuploadsize,
+       r_stat_vertexbufferuploadcount,
+       r_stat_vertexbufferuploadsize,
+       r_stat_framedatacurrent,
+       r_stat_framedatasize,
+       r_stat_bufferdatacurrent_vertex, // R_BUFFERDATA_ types are added to this index
+       r_stat_bufferdatacurrent_index16,
+       r_stat_bufferdatacurrent_index32,
+       r_stat_bufferdatacurrent_uniform,
+       r_stat_bufferdatasize_vertex, // R_BUFFERDATA_ types are added to this index
+       r_stat_bufferdatasize_index16,
+       r_stat_bufferdatasize_index32,
+       r_stat_bufferdatasize_uniform,
+       r_stat_animcache_vertexmesh_count,
+       r_stat_animcache_vertexmesh_vertices,
+       r_stat_animcache_vertexmesh_maxvertices,
+       r_stat_animcache_skeletal_count,
+       r_stat_animcache_skeletal_bones,
+       r_stat_animcache_skeletal_maxbones,
+       r_stat_animcache_shade_count,
+       r_stat_animcache_shade_vertices,
+       r_stat_animcache_shade_maxvertices,
+       r_stat_animcache_shape_count,
+       r_stat_animcache_shape_vertices,
+       r_stat_animcache_shape_maxvertices,
+       r_stat_batch_batches,
+       r_stat_batch_withgaps,
+       r_stat_batch_surfaces,
+       r_stat_batch_vertices,
+       r_stat_batch_triangles,
+       r_stat_batch_fast_batches,
+       r_stat_batch_fast_surfaces,
+       r_stat_batch_fast_vertices,
+       r_stat_batch_fast_triangles,
+       r_stat_batch_copytriangles_batches,
+       r_stat_batch_copytriangles_surfaces,
+       r_stat_batch_copytriangles_vertices,
+       r_stat_batch_copytriangles_triangles,
+       r_stat_batch_dynamic_batches,
+       r_stat_batch_dynamic_surfaces,
+       r_stat_batch_dynamic_vertices,
+       r_stat_batch_dynamic_triangles,
+       r_stat_batch_dynamicskeletal_batches,
+       r_stat_batch_dynamicskeletal_surfaces,
+       r_stat_batch_dynamicskeletal_vertices,
+       r_stat_batch_dynamicskeletal_triangles,
+       r_stat_batch_dynamic_batches_because_cvar,
+       r_stat_batch_dynamic_surfaces_because_cvar,
+       r_stat_batch_dynamic_vertices_because_cvar,
+       r_stat_batch_dynamic_triangles_because_cvar,
+       r_stat_batch_dynamic_batches_because_lightmapvertex,
+       r_stat_batch_dynamic_surfaces_because_lightmapvertex,
+       r_stat_batch_dynamic_vertices_because_lightmapvertex,
+       r_stat_batch_dynamic_triangles_because_lightmapvertex,
+       r_stat_batch_dynamic_batches_because_deformvertexes_autosprite,
+       r_stat_batch_dynamic_surfaces_because_deformvertexes_autosprite,
+       r_stat_batch_dynamic_vertices_because_deformvertexes_autosprite,
+       r_stat_batch_dynamic_triangles_because_deformvertexes_autosprite,
+       r_stat_batch_dynamic_batches_because_deformvertexes_autosprite2,
+       r_stat_batch_dynamic_surfaces_because_deformvertexes_autosprite2,
+       r_stat_batch_dynamic_vertices_because_deformvertexes_autosprite2,
+       r_stat_batch_dynamic_triangles_because_deformvertexes_autosprite2,
+       r_stat_batch_dynamic_batches_because_deformvertexes_normal,
+       r_stat_batch_dynamic_surfaces_because_deformvertexes_normal,
+       r_stat_batch_dynamic_vertices_because_deformvertexes_normal,
+       r_stat_batch_dynamic_triangles_because_deformvertexes_normal,
+       r_stat_batch_dynamic_batches_because_deformvertexes_wave,
+       r_stat_batch_dynamic_surfaces_because_deformvertexes_wave,
+       r_stat_batch_dynamic_vertices_because_deformvertexes_wave,
+       r_stat_batch_dynamic_triangles_because_deformvertexes_wave,
+       r_stat_batch_dynamic_batches_because_deformvertexes_bulge,
+       r_stat_batch_dynamic_surfaces_because_deformvertexes_bulge,
+       r_stat_batch_dynamic_vertices_because_deformvertexes_bulge,
+       r_stat_batch_dynamic_triangles_because_deformvertexes_bulge,
+       r_stat_batch_dynamic_batches_because_deformvertexes_move,
+       r_stat_batch_dynamic_surfaces_because_deformvertexes_move,
+       r_stat_batch_dynamic_vertices_because_deformvertexes_move,
+       r_stat_batch_dynamic_triangles_because_deformvertexes_move,
+       r_stat_batch_dynamic_batches_because_tcgen_lightmap,
+       r_stat_batch_dynamic_surfaces_because_tcgen_lightmap,
+       r_stat_batch_dynamic_vertices_because_tcgen_lightmap,
+       r_stat_batch_dynamic_triangles_because_tcgen_lightmap,
+       r_stat_batch_dynamic_batches_because_tcgen_vector,
+       r_stat_batch_dynamic_surfaces_because_tcgen_vector,
+       r_stat_batch_dynamic_vertices_because_tcgen_vector,
+       r_stat_batch_dynamic_triangles_because_tcgen_vector,
+       r_stat_batch_dynamic_batches_because_tcgen_environment,
+       r_stat_batch_dynamic_surfaces_because_tcgen_environment,
+       r_stat_batch_dynamic_vertices_because_tcgen_environment,
+       r_stat_batch_dynamic_triangles_because_tcgen_environment,
+       r_stat_batch_dynamic_batches_because_tcmod_turbulent,
+       r_stat_batch_dynamic_surfaces_because_tcmod_turbulent,
+       r_stat_batch_dynamic_vertices_because_tcmod_turbulent,
+       r_stat_batch_dynamic_triangles_because_tcmod_turbulent,
+       r_stat_batch_dynamic_batches_because_interleavedarrays,
+       r_stat_batch_dynamic_surfaces_because_interleavedarrays,
+       r_stat_batch_dynamic_vertices_because_interleavedarrays,
+       r_stat_batch_dynamic_triangles_because_interleavedarrays,
+       r_stat_batch_dynamic_batches_because_nogaps,
+       r_stat_batch_dynamic_surfaces_because_nogaps,
+       r_stat_batch_dynamic_vertices_because_nogaps,
+       r_stat_batch_dynamic_triangles_because_nogaps,
+       r_stat_batch_dynamic_batches_because_derived,
+       r_stat_batch_dynamic_surfaces_because_derived,
+       r_stat_batch_dynamic_vertices_because_derived,
+       r_stat_batch_dynamic_triangles_because_derived,
+       r_stat_batch_entitycache_count,
+       r_stat_batch_entitycache_surfaces,
+       r_stat_batch_entitycache_vertices,
+       r_stat_batch_entitycache_triangles,
+       r_stat_batch_entityanimate_count,
+       r_stat_batch_entityanimate_surfaces,
+       r_stat_batch_entityanimate_vertices,
+       r_stat_batch_entityanimate_triangles,
+       r_stat_batch_entityskeletal_count,
+       r_stat_batch_entityskeletal_surfaces,
+       r_stat_batch_entityskeletal_vertices,
+       r_stat_batch_entityskeletal_triangles,
+       r_stat_batch_entitystatic_count,
+       r_stat_batch_entitystatic_surfaces,
+       r_stat_batch_entitystatic_vertices,
+       r_stat_batch_entitystatic_triangles,
+       r_stat_batch_entitycustom_count,
+       r_stat_batch_entitycustom_surfaces,
+       r_stat_batch_entitycustom_vertices,
+       r_stat_batch_entitycustom_triangles,
+       r_stat_count // size of array
+}
+r_stat_t;
 
 // flags for rtlight rendering
 #define LIGHTFLAG_NORMALMODE 1
 #define LIGHTFLAG_REALTIMEMODE 2
 
+typedef struct tridecal_s
+{
+       // color and initial alpha value
+       float                   texcoord2f[3][2];
+       float                   vertex3f[3][3];
+       float                   color4f[3][4];
+       float                   plane[4]; // backface culling
+       // how long this decal has lived so far (the actual fade begins at cl_decals_time)
+       float                   lived;
+       // if >= 0 this indicates the decal should follow an animated triangle
+       int                             triangleindex;
+       // for visibility culling
+       int                             surfaceindex;
+       // old decals are killed to obey cl_decals_max
+       unsigned int    decalsequence;
+}
+tridecal_t;
+
+typedef struct decalsystem_s
+{
+       dp_model_t *model;
+       double lastupdatetime;
+       int maxdecals;
+       int freedecal;
+       int numdecals;
+       tridecal_t *decals;
+       float *vertex3f;
+       float *texcoord2f;
+       float *color4f;
+       int *element3i;
+       unsigned short *element3s;
+}
+decalsystem_t;
+
 typedef struct effect_s
 {
        int active;
        vec3_t origin;
-       float starttime;
+       double starttime;
        float framerate;
        int modelindex;
        int startframe;
@@ -62,6 +260,13 @@ typedef struct beam_s
 }
 beam_t;
 
+typedef struct rtlight_particle_s
+{
+       float origin[3];
+       float color[3];
+}
+rtlight_particle_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
@@ -69,37 +274,37 @@ typedef struct rtlight_s
        // note that the world to light matrices are inversely scaled (divided) by lightradius
 
        // core properties
-       // matrix for transforming light filter coordinates to world coordinates
+       /// matrix for transforming light filter coordinates to world coordinates
        matrix4x4_t matrix_lighttoworld;
-       // matrix for transforming world coordinates to light filter coordinates
+       /// matrix for transforming world coordinates to light filter coordinates
        matrix4x4_t matrix_worldtolight;
-       // typically 1 1 1, can be lower (dim) or higher (overbright)
+       /// typically 1 1 1, can be lower (dim) or higher (overbright)
        vec3_t color;
-       // size of the light (remove?)
+       /// size of the light (remove?)
        vec_t radius;
-       // light filter
+       /// light filter
        char cubemapname[64];
-       // light style to monitor for brightness
+       /// light style to monitor for brightness
        int style;
-       // whether light should render shadows
+       /// whether light should render shadows
        int shadow;
-       // intensity of corona to render
+       /// intensity of corona to render
        vec_t corona;
-       // radius scale of corona to render (1.0 means same as light radius)
+       /// radius scale of corona to render (1.0 means same as light radius)
        vec_t coronasizescale;
-       // ambient intensity to render
+       /// ambient intensity to render
        vec_t ambientscale;
-       // diffuse intensity to render
+       /// diffuse intensity to render
        vec_t diffusescale;
-       // specular intensity to render
+       /// specular intensity to render
        vec_t specularscale;
-       // LIGHTFLAG_* flags
+       /// LIGHTFLAG_* flags
        int flags;
 
        // generated properties
-       // used only for shadow volumes
+       /// used only for shadow volumes
        vec3_t shadoworigin;
-       // culling
+       /// culling
        vec3_t cullmins;
        vec3_t cullmaxs;
        // culling
@@ -110,37 +315,80 @@ typedef struct rtlight_s
        // 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)
+       /// used by corona updates, due to occlusion query
+       float corona_visibility;
+       unsigned int corona_queryindex_visiblepixels;
+       unsigned int corona_queryindex_allpixels;
+       /// this is R_GetCubemap(rtlight->cubemapname)
        rtexture_t *currentcubemap;
-
-       // static light info
-       // true if this light should be compiled as a static light
+       /// set by R_Shadow_PrepareLight to decide whether R_Shadow_DrawLight should draw it
+       qboolean draw;
+       /// these fields are set by R_Shadow_PrepareLight for later drawing
+       int cached_numlightentities;
+       int cached_numlightentities_noselfshadow;
+       int cached_numshadowentities;
+       int cached_numshadowentities_noselfshadow;
+       int cached_numsurfaces;
+       struct entity_render_s **cached_lightentities;
+       struct entity_render_s **cached_lightentities_noselfshadow;
+       struct entity_render_s **cached_shadowentities;
+       struct entity_render_s **cached_shadowentities_noselfshadow;
+       unsigned char *cached_shadowtrispvs;
+       unsigned char *cached_lighttrispvs;
+       int *cached_surfacelist;
+       // reduced light cullbox from GetLightInfo
+       vec3_t cached_cullmins;
+       vec3_t cached_cullmaxs;
+       // current shadow-caster culling planes based on view
+       // (any geometry outside these planes can not contribute to the visible
+       //  shadows in any way, and thus can be culled safely)
+       int cached_numfrustumplanes;
+       mplane_t cached_frustumplanes[5]; // see R_Shadow_ComputeShadowCasterCullingPlanes
+
+       /// 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
+       /// 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)
+       /// the shadowing mode used to compile this light
+       int shadowmode;
+       /// premade shadow volumes to render for world entity
+       shadowmesh_t *static_meshchain_shadow_zpass;
+       shadowmesh_t *static_meshchain_shadow_zfail;
+       shadowmesh_t *static_meshchain_shadow_shadowmap;
+       /// 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
+       /// surfaces seen by light
        int static_numsurfaces;
        int *static_surfacelist;
-       // flag bits indicating which triangles of the world model should cast
-       // shadows, and which ones should be lit
-       //
-       // this avoids redundantly scanning the triangles in each surface twice
-       // for whether they should cast shadows, once in culling and once in the
-       // actual shadowmarklist production.
+       /// flag bits indicating which triangles of the world model should cast
+       /// shadows, and which ones should be lit
+       ///
+       /// this avoids redundantly scanning the triangles in each surface twice
+       /// for whether they should cast shadows, once in culling and once in the
+       /// actual shadowmarklist production.
        int static_numshadowtrispvsbytes;
        unsigned char *static_shadowtrispvs;
-       // this allows the lighting batch code to skip backfaces andother culled
-       // triangles not relevant for lighting
-       // (important on big surfaces such as terrain)
+       /// this allows the lighting batch code to skip backfaces andother culled
+       /// triangles not relevant for lighting
+       /// (important on big surfaces such as terrain)
        int static_numlighttrispvsbytes;
        unsigned char *static_lighttrispvs;
+       /// masks of all shadowmap sides that have any potential static receivers or casters
+       int static_shadowmap_receivers;
+       int static_shadowmap_casters;
+       /// particle-tracing cache for global illumination
+       int particlecache_numparticles;
+       int particlecache_maxparticles;
+       int particlecache_updateparticle;
+       rtlight_particle_t *particlecache_particles;
+
+       /// bouncegrid light info
+       float photoncolor[3];
+       float photons;
 }
 rtlight_t;
 
@@ -217,9 +465,14 @@ typedef struct dlight_s
 }
 dlight_t;
 
+// this is derived from processing of the framegroupblend array
+// note: technically each framegroupblend can produce two of these, but that
+// never happens in practice because no one blends between more than 2
+// framegroups at once
+#define MAX_FRAMEBLENDS (MAX_FRAMEGROUPBLENDS * 2)
 typedef struct frameblend_s
 {
-       int frame;
+       int subframe;
        float lerp;
 }
 frameblend_t;
@@ -246,9 +499,11 @@ typedef struct entity_render_s
        float alpha;
        // size the model is shown
        float scale;
+       // transparent sorting offset
+       float transparent_offset;
 
        // NULL = no model
-       model_t *model;
+       dp_model_t *model;
        // number of the entity represents, or 0 for non-network entities
        int entitynumber;
        // literal colormap colors for renderer, if both are 0 0 0 it is not colormapped
@@ -265,60 +520,81 @@ typedef struct entity_render_s
 
        // colormod tinting of models
        float colormod[3];
+       float glowmod[3];
 
-       // interpolated animation
+       // interpolated animation - active framegroups and blend factors
+       framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
 
-       // 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;
+       // time of last model change (for shader animations)
+       double shadertime;
 
        // calculated by the renderer (but not persistent)
 
        // 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];
+       // subframe numbers (-1 if not used) and their blending scalers (0-1), if interpolation is not desired, use subframeblend[0].subframe
+       frameblend_t frameblend[MAX_FRAMEBLENDS];
+       // skeletal animation data (if skeleton.relativetransforms is not NULL, it overrides frameblend)
+       skeleton_t *skeleton;
+
+       // animation cache (pointers allocated using R_FrameData_Alloc)
+       // ONLY valid during R_RenderView!  may be NULL (not cached)
+       float          *animcache_vertex3f;
+       r_meshbuffer_t *animcache_vertex3f_vertexbuffer;
+       int             animcache_vertex3f_bufferoffset;
+       float          *animcache_normal3f;
+       r_meshbuffer_t *animcache_normal3f_vertexbuffer;
+       int             animcache_normal3f_bufferoffset;
+       float          *animcache_svector3f;
+       r_meshbuffer_t *animcache_svector3f_vertexbuffer;
+       int             animcache_svector3f_bufferoffset;
+       float          *animcache_tvector3f;
+       r_meshbuffer_t *animcache_tvector3f_vertexbuffer;
+       int             animcache_tvector3f_bufferoffset;
+       // interleaved arrays for rendering and dynamic vertex buffers for them
+       r_vertexmesh_t *animcache_vertexmesh;
+       r_meshbuffer_t *animcache_vertexmesh_vertexbuffer;
+       int             animcache_vertexmesh_bufferoffset;
+       // gpu-skinning shader needs transforms in a certain format, we have to
+       // upload this to a uniform buffer for the shader to use, and also keep a
+       // backup copy in system memory for the dynamic batch fallback code
+       // if this is not NULL, the other animcache variables are NULL
+       float *animcache_skeletaltransform3x4;
+       r_meshbuffer_t *animcache_skeletaltransform3x4buffer;
+       int animcache_skeletaltransform3x4offset;
+       int animcache_skeletaltransform3x4size;
 
        // current lighting from map (updated ONLY by client code, not renderer)
        vec3_t modellight_ambient;
        vec3_t modellight_diffuse; // q3bsp
        vec3_t modellight_lightdir; // q3bsp
 
+       // storage of decals on this entity
+       // (note: if allowdecals is set, be sure to call R_DecalSystem_Reset on removal!)
+       int allowdecals;
+       decalsystem_t decalsystem;
+
        // FIELDS UPDATED BY RENDERER:
        // last time visible during trace culling
        double last_trace_visibility;
+
+       // user wavefunc parameters (from csqc)
+       vec_t userwavefunc_param[Q3WAVEFUNC_USER_COUNT];
 }
 entity_render_t;
 
 typedef struct entity_persistent_s
 {
-       vec3_t trail_origin;
-
-       // particle trail
-       float trail_time;
+       vec3_t trail_origin; // previous position for particle trail spawning
+       vec3_t oldorigin; // lerp
+       vec3_t oldangles; // lerp
+       vec3_t neworigin; // lerp
+       vec3_t newangles; // lerp
+       vec_t lerpstarttime; // lerp
+       vec_t lerpdeltatime; // lerp
+       float muzzleflash; // muzzleflash intensity, fades over time
+       float trail_time; // residual error accumulation for particle trail spawning (to keep spacing across frames)
        qboolean trail_allowed; // set to false by teleports, true by update code, prevents bad lerps
-
-       // 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;
 
@@ -356,14 +632,21 @@ typedef struct usercmd_s
        vec_t   cursor_fraction;
        int             cursor_entitynumber;
 
-       double time;
-       double receivetime;
-       int msec; // for qw moves
+       double time; // time the move is executed for (cl_movement: clienttime, non-cl_movement: receivetime)
+       double receivetime; // time the move was received at
+       double clienttime; // time to which server state the move corresponds to
+       int msec; // for predicted moves
        int buttons;
        int impulse;
-       int sequence;
+       unsigned int sequence;
        qboolean applied; // if false we're still accumulating a move
        qboolean predicted; // if true the sequence should be sent as 0
+
+       // derived properties
+       double frametime;
+       qboolean canjump;
+       qboolean jump;
+       qboolean crouch;
 } usercmd_t;
 
 typedef struct lightstyle_s
@@ -383,6 +666,7 @@ typedef struct scoreboard_s
        float   qw_entertime;
        int             qw_ping;
        int             qw_packetloss;
+       int             qw_movementloss;
        int             qw_spectator;
        char    qw_team[8];
        char    qw_skin[MAX_QPATH];
@@ -391,7 +675,8 @@ typedef struct scoreboard_s
 typedef struct cshift_s
 {
        float   destcolor[3];
-       float   percent;                // 0-256
+       float   percent;                // 0-255
+       float   alphafade;      // (any speed)
 } cshift_t;
 
 #define        CSHIFT_CONTENTS 0
@@ -410,11 +695,9 @@ typedef struct cshift_s
 
 #define        SIGNONS         4                       // signon messages to receive before connected
 
-#define        MAX_DEMOS               8
-#define        MAX_DEMONAME    16
-
 typedef enum cactive_e
 {
+       ca_uninitialized,       // during early startup
        ca_dedicated,           // a dedicated server with no ability to start a client
        ca_disconnected,        // full screen console with no connection
        ca_connected            // valid netcon, talking to a server
@@ -433,46 +716,53 @@ qw_downloadtype_t;
 
 typedef enum capturevideoformat_e
 {
-       CAPTUREVIDEOFORMAT_AVI_I420
+       CAPTUREVIDEOFORMAT_AVI_I420,
+       CAPTUREVIDEOFORMAT_OGG_VORBIS_THEORA
 }
 capturevideoformat_t;
 
 typedef struct capturevideostate_s
 {
-       double starttime;
+       double startrealtime;
        double framerate;
-       // for AVI saving some values have to be written after capture ends
-       fs_offset_t videofile_firstchunkframes_offset;
-       fs_offset_t videofile_totalframes_offset1;
-       fs_offset_t videofile_totalframes_offset2;
-       fs_offset_t videofile_totalsampleframes_offset;
-       int videofile_ix_master_audio_inuse;
-       fs_offset_t videofile_ix_master_audio_inuse_offset;
-       fs_offset_t videofile_ix_master_audio_start_offset;
-       int videofile_ix_master_video_inuse;
-       fs_offset_t videofile_ix_master_video_inuse_offset;
-       fs_offset_t videofile_ix_master_video_start_offset;
-       fs_offset_t videofile_ix_movistart;
-       qfile_t *videofile;
+       int framestep;
+       int framestepframe;
        qboolean active;
        qboolean realtime;
        qboolean error;
-       capturevideoformat_t format;
        int soundrate;
+       int soundchannels;
        int frame;
-       int soundsampleframe; // for AVI saving
+       double starttime;
+       double lastfpstime;
+       int lastfpsframe;
+       int soundsampleframe;
        unsigned char *screenbuffer;
        unsigned char *outbuffer;
-       sizebuf_t riffbuffer;
-       unsigned char riffbufferdata[128];
-       // note: riffindex buffer has an allocated ->data member, not static like most!
-       sizebuf_t riffindexbuffer;
-       int riffstacklevel;
-       fs_offset_t riffstackstartoffset[4];
+       char basename[MAX_QPATH];
+       int width, height;
+
+       // precomputed RGB to YUV tables
+       // converts the RGB values to YUV (see cap_avi.c for how to use them)
        short rgbtoyuvscaletable[3][3][256];
        unsigned char yuvnormalizetable[3][256];
-       char basename[64];
-       int width, height;
+
+       // precomputed gamma ramp (only needed if the capturevideo module uses RGB output)
+       // note: to map from these values to RGB24, you have to multiply by 255.0/65535.0, then add 0.5, then cast to integer
+       unsigned short vidramp[256 * 3];
+
+       // stuff to be filled in by the video format module
+       capturevideoformat_t format;
+       const char *formatextension;
+       qfile_t *videofile;
+               // always use this:
+               //   cls.capturevideo.videofile = FS_OpenRealFile(va(vabuf, sizeof(vabuf), "%s.%s", cls.capturevideo.basename, cls.capturevideo.formatextension), "wb", false);
+       void (*endvideo) (void);
+       void (*videoframes) (int num);
+       void (*soundframe) (const portable_sampleframe_t *paintbuffer, size_t length);
+
+       // format specific data
+       void *formatspecific;
 }
 capturevideostate_t;
 
@@ -484,6 +774,14 @@ typedef struct cl_downloadack_s
 }
 cl_downloadack_t;
 
+typedef struct cl_soundstats_s
+{
+       int mixedsounds;
+       int totalsounds;
+       int latency_milliseconds;
+}
+cl_soundstats_t;
+
 //
 // the client_static_t structure is persistent through an arbitrary number
 // of server connections
@@ -502,12 +800,15 @@ typedef struct client_static_s
        // list of demos in loop
        char demos[MAX_DEMOS][MAX_DEMONAME];
        // the actively playing demo (set by CL_PlayDemo_f)
-       char demoname[64];
+       char demoname[MAX_QPATH];
 
 // demo recording info must be here, because record is started before
 // entering a map (and clearing client_state_t)
        qboolean demorecording;
+       fs_offset_t demo_lastcsprogssize;
+       int demo_lastcsprogscrc;
        qboolean demoplayback;
+       qboolean demostarting; // set if currently starting a demo, to stop -demo from quitting when switching to another demo
        qboolean timedemo;
        // -1 = use normal cd track
        int forcetrack;
@@ -517,13 +818,17 @@ typedef struct client_static_s
        int td_frames; // total frames parsed
        double td_onesecondnexttime;
        double td_onesecondframes;
-       double td_onesecondminframes;
-       double td_onesecondmaxframes;
-       double td_onesecondavgframes;
+       double td_onesecondrealtime;
+       double td_onesecondminfps;
+       double td_onesecondmaxfps;
+       double td_onesecondavgfps;
        int td_onesecondavgcount;
        // LordHavoc: pausedemo
        qboolean demopaused;
 
+       // sound mixer statistics for showsound display
+       cl_soundstats_t soundstats;
+
        qboolean connect_trying;
        int connect_remainingtries;
        double connect_nextsendtime;
@@ -533,6 +838,13 @@ typedef struct client_static_s
        // (kept outside client_state_t because it's used between levels)
        protocolversion_t protocol;
 
+#define MAX_RCONS 16
+       int rcon_trying;
+       lhnetaddress_t rcon_addresses[MAX_RCONS];
+       char rcon_commands[MAX_RCONS][MAX_INPUTLINE];
+       double rcon_timeout[MAX_RCONS];
+       int rcon_ringpos;
+
 // connection information
        // 0 to SIGNONS
        int signon;
@@ -544,16 +856,15 @@ typedef struct client_static_s
        cl_downloadack_t dp_downloadack[CL_MAX_DOWNLOADACKS];
 
        // input sequence numbers are not reset on level change, only connect
-       int movesequence;
-       int servermovesequence;
+       unsigned int servermovesequence;
 
        // quakeworld stuff below
 
        // value of "qport" cvar at time of connection
        int qw_qport;
        // copied from cls.netcon->qw. variables every time they change, or set by demos (which have no cls.netcon)
-       int qw_incoming_sequence;
-       int qw_outgoing_sequence;
+       unsigned int qw_incoming_sequence;
+       unsigned int qw_outgoing_sequence;
 
        // current file download buffer (only saved when file is completed)
        char qw_downloadname[MAX_QPATH];
@@ -567,6 +878,7 @@ typedef struct client_static_s
        double qw_downloadspeedtime;
        int qw_downloadspeedcount;
        int qw_downloadspeedrate;
+       qboolean qw_download_deflate;
 
        // current file upload buffer (for uploading screenshots to server)
        unsigned char *qw_uploaddata;
@@ -578,26 +890,36 @@ typedef struct client_static_s
        // password spectator name team skin topcolor bottomcolor rate noaim msg *ver *ip
        char userinfo[MAX_USERINFO_STRING];
 
+       // extra user info for the "connect" command
+       char connect_userinfo[MAX_USERINFO_STRING];
+
        // video capture stuff
        capturevideostate_t capturevideo;
+
+       // crypto channel
+       crypto_t crypto;
+
+       // ProQuake compatibility stuff
+       int proquake_servermod; // 0 = not proquake, 1 = proquake
+       int proquake_serverversion; // actual proquake server version * 10 (3.40 = 34, etc)
+       int proquake_serverflags; // 0 (PQF_CHEATFREE not supported)
+
+       // don't write-then-read csprogs.dat (useful for demo playback)
+       unsigned char *caughtcsprogsdata;
+       fs_offset_t caughtcsprogsdatasize;
+
+       int r_speeds_graph_length;
+       int r_speeds_graph_current;
+       int *r_speeds_graph_data;
+
+       // graph scales
+       int r_speeds_graph_datamin[r_stat_count];
+       int r_speeds_graph_datamax[r_stat_count];
 }
 client_static_t;
 
 extern client_static_t cls;
 
-typedef struct client_movementqueue_s
-{
-       double time;
-       float frametime;
-       int sequence;
-       float viewangles[3];
-       float move[3];
-       qboolean jump;
-       qboolean crouch;
-       qboolean canjump;
-}
-client_movementqueue_t;
-
 //[515]: csqc
 typedef struct
 {
@@ -611,7 +933,9 @@ typedef enum
        PARTICLE_BILLBOARD = 0,
        PARTICLE_SPARK = 1,
        PARTICLE_ORIENTED_DOUBLESIDED = 2,
-       PARTICLE_BEAM = 3
+       PARTICLE_VBEAM = 3,
+       PARTICLE_HBEAM = 4,
+       PARTICLE_INVALID = -1
 }
 porientation_t;
 
@@ -619,7 +943,8 @@ typedef enum
 {
        PBLEND_ALPHA = 0,
        PBLEND_ADD = 1,
-       PBLEND_MOD = 2
+       PBLEND_INVMOD = 2,
+       PBLEND_INVALID = -1
 }
 pblend_t;
 
@@ -631,7 +956,7 @@ typedef struct particletype_s
 }
 particletype_t;
 
-typedef enum
+typedef enum ptype_e
 {
        pt_dead, 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
 }
@@ -639,16 +964,22 @@ ptype_t;
 
 typedef struct decal_s
 {
+       // fields used by rendering:  (44 bytes)
        unsigned short  typeindex;
        unsigned short  texnum;
+       unsigned int    decalsequence;
        vec3_t                  org;
        vec3_t                  normal;
        float                   size;
        float                   alpha; // 0-255
-       float                   time2; // used for snow fluttering and decal fade
-       unsigned char   color[4];
+       unsigned char   color[3];
+       unsigned char   unused1;
+       int                             clusterindex; // cheap culling by pvs
+
+       // fields not used by rendering: (36 bytes in 32bit, 40 bytes in 64bit)
+       float                   time2; // used for decal fade
        unsigned int    owner; // decal stuck to this entity
-       model_t                 *ownermodel; // model the decal is stuck to (used to make sure the entity is still alive)
+       dp_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                  relativenormal; // decal oriented this way relative to entity's coordinate space
 }
@@ -656,23 +987,43 @@ decal_t;
 
 typedef struct particle_s
 {
-       unsigned short  typeindex;
-       unsigned short  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];
-       float                   delayedcollisions; // time that p->bounce becomes active
-       float                   delayedspawn; // time that particle appears and begins moving
-       float                   die; // time when this particle should be removed, regardless of alpha
+       // for faster batch rendering, particles are rendered in groups by effect (resulting in less perfect sorting but far less state changes)
+
+       // fields used by rendering: (48 bytes)
+       vec3_t          sortorigin; // sort by this group origin, not particle org
+       vec3_t          org;
+       vec3_t          vel; // velocity of particle, or orientation of decal, or end point of beam
+       float           size;
+       float           alpha; // 0-255
+       float           stretch; // only for sparks
+
+       // fields not used by rendering:  (44 bytes)
+       float           stainsize;
+       float           stainalpha;
+       float           sizeincrease; // rate of size change per second
+       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)
+//     float           delayedcollisions; // time that p->bounce becomes active
+       float           delayedspawn; // time that particle appears and begins moving
+       float           die; // time when this particle should be removed, regardless of alpha
+
+       // short variables grouped to save memory (4 bytes)
+       short                   angle; // base rotation of particle
+       short                   spin; // geometry rotation speed around the particle center normal
+
+       // byte variables grouped to save memory (12 bytes)
+       unsigned char   color[3];
+       unsigned char   qualityreduction; // enables skipping of this particle according to r_refdef.view.qualityreduction
+       unsigned char   typeindex;
+       unsigned char   blendmode;
+       unsigned char   orientation;
+       unsigned char   texnum;
+       unsigned char   staincolor[3];
+       signed char     staintexnum;
 }
 particle_t;
 
@@ -773,21 +1124,23 @@ typedef struct client_state_s
        qboolean movement_predicted;
        // if true the CL_ClientMovement_Replay function will update origin, etc
        qboolean movement_replay;
-       // this is set true by svc_time parsing and causes a new movement to be
-       // queued for prediction purposes
-       qboolean movement_needupdate;
-       // timestamps of latest two predicted moves for interpolation
-       double movement_time[4];
        // 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[256];
        // whether the replay should allow a jump at the first sequence
        qboolean movement_replay_canjump;
 
+       // previous gun angles (for leaning effects)
+       vec3_t gunangles_prev;
+       vec3_t gunangles_highpass;
+       vec3_t gunangles_adjustment_lowpass;
+       vec3_t gunangles_adjustment_highpass;
+       // previous gun angles (for leaning effects)
+       vec3_t gunorg_prev;
+       vec3_t gunorg_highpass;
+       vec3_t gunorg_adjustment_lowpass;
+       vec3_t gunorg_adjustment_highpass;
+
 // pitch drifting vars
        float idealpitch;
        float pitchvel;
@@ -799,6 +1152,7 @@ typedef struct client_state_s
        float sensitivityscale;
        csqc_vidvars_t csqc_vidvars;    //[515]: these parms must be set to true by default
        qboolean csqc_wantsmousemove;
+       qboolean csqc_paused; // vortex: int because could be flags
        struct model_s *csqc_model_precache[MAX_MODELS];
 
        // local amount for smoothing stepups
@@ -813,6 +1167,10 @@ typedef struct client_state_s
        qboolean oldonground;
        double lastongroundtime;
        double hitgroundtime;
+       float bob2_smooth;
+       float bobfall_speed;
+       float bobfall_swing;
+       double calcrefdef_prevtime;
 
        // don't change view angle, full screen, etc
        int intermission;
@@ -831,6 +1189,12 @@ typedef struct client_state_s
        // 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;
+       
+       // fade var for fading while dead
+       float deathfade;
+
+       // motionblur alpha level variable
+       float motionbluralpha;
 
        // copy of realtime from last recieved message, for net trouble icon
        float last_received_message;
@@ -844,7 +1208,11 @@ typedef struct client_state_s
        char sound_name[MAX_SOUNDS][MAX_QPATH];
 
        // for display on solo scoreboard
-       char levelname[40];
+       char worldmessage[40]; // map title (not related to filename)
+       // variants of map name
+       char worldbasename[MAX_QPATH]; // %s
+       char worldname[MAX_QPATH]; // maps/%s.bsp
+       char worldnamenoextension[MAX_QPATH]; // maps/%s
        // cl_entitites[cl.viewentity] = player
        int viewentity;
        // the real player entity (normally same as viewentity,
@@ -861,10 +1229,10 @@ typedef struct client_state_s
        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;
+       dp_model_t *model_bolt;
+       dp_model_t *model_bolt2;
+       dp_model_t *model_bolt3;
+       dp_model_t *model_beam;
        sfx_t *sfx_wizhit;
        sfx_t *sfx_knighthit;
        sfx_t *sfx_tink1;
@@ -903,8 +1271,10 @@ typedef struct client_state_s
 
        // entity database stuff
        // latest received entity frame numbers
-#define LATESTFRAMENUMS 3
+#define LATESTFRAMENUMS 32
+       int latestframenumsposition;
        int latestframenums[LATESTFRAMENUMS];
+       unsigned int latestsendnums[LATESTFRAMENUMS];
        entityframe_database_t *entitydatabase;
        entityframe4_database_t *entitydatabase4;
        entityframeqw_database_t *entitydatabaseqw;
@@ -919,9 +1289,12 @@ typedef struct client_state_s
        vec3_t playercrouchmins;
        vec3_t playercrouchmaxs;
 
+       // old decals are killed based on this
+       unsigned int decalsequence;
+
        int max_entities;
+       int max_csqcrenderentities;
        int max_static_entities;
-       int max_temp_entities;
        int max_effects;
        int max_beams;
        int max_dlights;
@@ -932,9 +1305,9 @@ typedef struct client_state_s
        int max_showlmps;
 
        entity_t *entities;
+       entity_render_t *csqcrenderentities;
        unsigned char *entities_active;
        entity_t *static_entities;
-       entity_t *temp_entities;
        cl_effect_t *effects;
        beam_t *beams;
        dlight_t *dlights;
@@ -946,7 +1319,6 @@ typedef struct client_state_s
 
        int num_entities;
        int num_static_entities;
-       int num_temp_entities;
        int num_brushmodel_entities;
        int num_effects;
        int num_beams;
@@ -955,6 +1327,8 @@ typedef struct client_state_s
        int num_decals;
        int num_showlmps;
 
+       double particles_updatetime;
+       double decals_updatetime;
        int free_particle;
        int free_decal;
 
@@ -988,11 +1362,14 @@ typedef struct client_state_s
        // use cl.scores[cl.playerentity-1].qw_spectator instead
        //qboolean qw_spectator;
 
+       // last time an input packet was sent
+       double lastpackettime;
+
        // movement parameters for client prediction
+       unsigned int moveflags;
        float movevars_wallfriction;
        float movevars_waterfriction;
        float movevars_friction;
-       float movevars_ticrate;
        float movevars_timescale;
        float movevars_gravity;
        float movevars_stopspeed;
@@ -1007,7 +1384,22 @@ typedef struct client_state_s
        float movevars_maxairspeed;
        float movevars_stepheight;
        float movevars_airaccel_qw;
+       float movevars_airaccel_qw_stretchfactor;
        float movevars_airaccel_sideways_friction;
+       float movevars_airstopaccelerate;
+       float movevars_airstrafeaccelerate;
+       float movevars_maxairstrafespeed;
+       float movevars_airstrafeaccel_qw;
+       float movevars_aircontrol;
+       float movevars_aircontrol_power;
+       float movevars_aircontrol_penalty;
+       float movevars_warsowbunny_airforwardaccel;
+       float movevars_warsowbunny_accel;
+       float movevars_warsowbunny_topspeed;
+       float movevars_warsowbunny_turnaccel;
+       float movevars_warsowbunny_backtosideratio;
+       float movevars_ticrate;
+       float movevars_airspeedlimit_nonqw;
 
        // models used by qw protocol
        int qw_modelindex_spike;
@@ -1024,16 +1416,19 @@ typedef struct client_state_s
 
        float qw_weaponkick;
 
-       int qw_validsequence;
+       unsigned int qw_validsequence;
 
-       int qw_deltasequence[QW_UPDATE_BACKUP];
+       unsigned int qw_deltasequence[QW_UPDATE_BACKUP];
 
        // csqc stuff:
        // server entity number corresponding to a clientside entity
        unsigned short csqc_server2csqcentitynumber[MAX_EDICTS];
        qboolean csqc_loaded;
-       vec3_t csqc_origin;
-       vec3_t csqc_angles;
+       vec3_t csqc_vieworigin;
+       vec3_t csqc_viewangles;
+       vec3_t csqc_vieworiginfromengine;
+       vec3_t csqc_viewanglesfromengine;
+       matrix4x4_t csqc_viewmodelmatrixfromengine;
        qboolean csqc_usecsqclistener;
        matrix4x4_t csqc_listenermatrix;
        char csqc_printtextbuf[MAX_INPUTLINE];
@@ -1051,6 +1446,9 @@ typedef struct client_state_s
        // freed on each level change
        size_t buildlightmapmemorysize;
        unsigned char *buildlightmapmemory;
+
+       // used by EntityState5_ReadUpdate
+       skeleton_t *engineskeletonobjects;
 }
 client_state_t;
 
@@ -1060,6 +1458,7 @@ client_state_t;
 extern cvar_t cl_name;
 extern cvar_t cl_color;
 extern cvar_t cl_rate;
+extern cvar_t cl_rate_burstsize;
 extern cvar_t cl_pmodel;
 extern cvar_t cl_playermodel;
 extern cvar_t cl_playerskin;
@@ -1101,6 +1500,7 @@ extern cvar_t m_side;
 
 extern cvar_t cl_autodemo;
 extern cvar_t cl_autodemo_nameformat;
+extern cvar_t cl_autodemo_delete;
 
 extern cvar_t r_draweffects;
 
@@ -1113,6 +1513,7 @@ extern cvar_t cl_stainmaps;
 extern cvar_t cl_stainmaps_clearonload;
 
 extern cvar_t cl_prydoncursor;
+extern cvar_t cl_prydoncursor_notrace;
 
 extern cvar_t cl_locs_enable;
 
@@ -1132,7 +1533,7 @@ void CL_Locs_FindLocationName(char *buffer, size_t buffersize, vec3_t point);
 void CL_Shutdown (void);
 void CL_Init (void);
 
-void CL_EstablishConnection(const char *host);
+void CL_EstablishConnection(const char *host, int firstarg);
 
 void CL_Disconnect (void);
 void CL_Disconnect_f (void);
@@ -1162,29 +1563,30 @@ 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_NewBeam (int ent, vec3_t start, vec3_t end, model_t *m, int lightning);
+void CL_NewBeam (int ent, vec3_t start, vec3_t end, dp_model_t *m, int lightning);
 void CL_RelinkBeams (void);
 void CL_Beam_CalculatePositions (const beam_t *b, vec3_t start, vec3_t end);
 void CL_ClientMovement_Replay(void);
 
 void CL_ClearTempEntities (void);
-entity_t *CL_NewTempEntity (void);
+entity_render_t *CL_NewTempEntity (double shadertime);
 
 void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate);
 
 void CL_ClearState (void);
 void CL_ExpandEntities(int num);
+void CL_ExpandCSQCRenderEntities(int num);
 void CL_SetInfo(const char *key, const char *value, qboolean send, qboolean allowstarkey, qboolean allowmodel, qboolean quiet);
 
 
 void CL_UpdateWorld (void);
 void CL_WriteToServer (void);
 void CL_Input (void);
-extern qboolean cl_ignoremousemove;
+extern int cl_ignoremousemoves;
 
 
 float CL_KeyState (kbutton_t *key);
-const char *Key_KeynumToString (int keynum);
+const char *Key_KeynumToString (int keynum, char *buf, size_t buflength);
 int Key_StringToKeynum (const char *str);
 
 //
@@ -1194,6 +1596,9 @@ void CL_StopPlayback(void);
 void CL_ReadDemoMessage(void);
 void CL_WriteDemoMessage(sizebuf_t *mesage);
 
+void CL_CutDemo(unsigned char **buf, fs_offset_t *filesize);
+void CL_PasteDemo(unsigned char **buf, fs_offset_t *filesize);
+
 void CL_NextDemo(void);
 void CL_Stop_f(void);
 void CL_Record_f(void);
@@ -1210,6 +1615,7 @@ void CL_Parse_DumpPacket(void);
 void CL_Parse_ErrorCleanUp(void);
 void QW_CL_StartUpload(unsigned char *data, int size);
 extern cvar_t qport;
+void CL_KeepaliveMessage(qboolean readmessages); // call this during loading of large content
 
 //
 // view
@@ -1218,7 +1624,7 @@ void V_StartPitchDrift (void);
 void V_StopPitchDrift (void);
 
 void V_Init (void);
-float V_CalcRoll (vec3_t angles, vec3_t velocity);
+float V_CalcRoll (const vec3_t angles, const vec3_t velocity);
 void V_UpdateBlends (void);
 void V_ParseDamage (void);
 
@@ -1232,6 +1638,9 @@ 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_decal_alpha;
+extern cvar_t cl_particles_blood_decal_scalemin;
+extern cvar_t cl_particles_blood_decal_scalemax;
 extern cvar_t cl_particles_blood_bloodhack;
 extern cvar_t cl_particles_bulletimpacts;
 extern cvar_t cl_particles_explosions_sparks;
@@ -1250,6 +1659,7 @@ extern cvar_t cl_decals_fadetime;
 void CL_Particles_Clear(void);
 void CL_Particles_Init(void);
 void CL_Particles_Shutdown(void);
+particle_t *CL_NewParticle(const vec3_t sortorigin, unsigned short ptypeindex, int pcolor1, int pcolor2, int ptex, float psize, float psizeincrease, float palpha, float palphafade, float pgravity, float pbounce, float px, float py, float pz, float pvx, float pvy, float pvz, float pairfriction, float pliquidfriction, float originjitter, float velocityjitter, qboolean pqualityreduction, float lifetime, float stretch, pblend_t blendmode, porientation_t orientation, int staincolor1, int staincolor2, int staintex, float stainalpha, float stainsize, float angle, float spin, float tint[4]);
 
 typedef enum effectnameindex_s
 {
@@ -1296,19 +1706,17 @@ 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_ParticleTrail(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, qboolean spawndlight, qboolean spawnparticles);
+void CL_ParticleTrail(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, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade);
+void CL_ParticleBox(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, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade);
 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_MoveDecals(void);
-void CL_MoveParticles(void);
-void R_MoveExplosions(void);
 void R_NewExplosion(const vec3_t org);
 
-void Debug_PolygonBegin(const char *picname, int flags, qboolean draw2d, float linewidth);
+void Debug_PolygonBegin(const char *picname, int flags);
 void Debug_PolygonVertex(float x, float y, float z, float s, float t, float r, float g, float b, float a);
 void Debug_PolygonEnd(void);
 
@@ -1316,125 +1724,39 @@ void Debug_PolygonEnd(void);
 
 extern qboolean sb_showscores;
 
-float FogPoint_World(const vec3_t p);
-float FogPoint_Model(const vec3_t p);
-float FogForDistance(vec_t dist);
+float RSurf_FogVertex(const vec3_t p);
+float RSurf_FogPoint(const vec3_t p);
 
-typedef struct r_refdef_stats_s
+typedef enum r_viewport_type_e
 {
-       int entities;
-       int entities_surfaces;
-       int entities_triangles;
-       int world_leafs;
-       int world_portals;
-       int world_surfaces;
-       int world_triangles;
-       int lightmapupdates;
-       int lightmapupdatepixels;
-       int particles;
-       int decals;
-       int meshes;
-       int meshes_elements;
-       int lights;
-       int lights_clears;
-       int lights_scissored;
-       int lights_lighttriangles;
-       int lights_shadowtriangles;
-       int lights_dynamicshadowtriangles;
-       int bloom;
-       int bloom_copypixels;
-       int bloom_drawpixels;
+       R_VIEWPORTTYPE_ORTHO,
+       R_VIEWPORTTYPE_PERSPECTIVE,
+       R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP,
+       R_VIEWPORTTYPE_PERSPECTIVECUBESIDE,
+       R_VIEWPORTTYPE_TOTAL
 }
-r_refdef_stats_t;
+r_viewport_type_t;
 
-typedef struct r_refdef_s
+typedef struct r_viewport_s
 {
-       // these fields define the basic rendering information for the world
-       // but not the view, which could change multiple times in one rendered
-       // frame (for example when rendering textures for certain effects)
-
-       // these are set for water warping before
-       // frustum_x/frustum_y are calculated
-       float frustumscale_x, frustumscale_y;
-
-       // minimum visible distance (pixels closer than this disappear)
-       double nearclip;
-       // maximum visible distance (pixels further than this disappear in 16bpp modes,
-       // in 32bpp an infinite-farclip matrix is used instead)
-       double farclip;
-
-       // 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
-       rtlight_t lights[MAX_DLIGHTS];
-       int numlights;
-
-       // intensities for light styles right now, controls rtlights
-       float rtlightstylevalue[256];   // float fraction of base light value
-       // 8.8bit fixed point intensities for light styles
-       // controls intensity lightmap layers
-       unsigned short lightstylevalue[256];    // 8.8 fraction of base light value
-
-       vec3_t fogcolor;
-       vec_t fogrange;
-       vec_t fograngerecip;
-       vec_t fogmasktabledistmultiplier;
-#define FOGMASKTABLEWIDTH 1024
-       float fogmasktable[FOGMASKTABLEWIDTH];
-       float fog_density;
-       float fog_red;
-       float fog_green;
-       float fog_blue;
-       float fog_start, fog_alpha;
-       qboolean fogenabled;
-       qboolean oldgl_fogenable;
-
-       qboolean draw2dstage;
-
-       // true during envmap command capture
-       qboolean envmap;
-
-       // brightness of world lightmaps and related lighting
-       // (often reduced when world rtlights are enabled)
-       float lightmapintensity;
-       // whether to draw world lights realtime, dlights realtime, and their shadows
-       qboolean rtworld;
-       qboolean rtworldshadows;
-       qboolean rtdlight;
-       qboolean rtdlightshadows;
-       float polygonfactor;
-       float polygonoffset;
-       float shadowpolygonfactor;
-       float shadowpolygonoffset;
-
-       // rendering stats for r_speeds display
-       // (these are incremented in many places)
-       r_refdef_stats_t stats;
+       matrix4x4_t cameramatrix; // from entity (transforms from camera entity to world)
+       matrix4x4_t viewmatrix; // actual matrix for rendering (transforms to viewspace)
+       matrix4x4_t projectmatrix; // actual projection matrix (transforms from viewspace to screen)
+       int x;
+       int y;
+       int z;
+       int width;
+       int height;
+       int depth;
+       r_viewport_type_t type;
+       float screentodepth[2]; // used by deferred renderer to calculate linear depth from device depth coordinates
 }
-r_refdef_t;
+r_viewport_t;
 
-typedef struct r_view_s
+typedef struct r_refdef_view_s
 {
        // view information (changes multiple times per frame)
-       // if any of these variables change then r_viewcache must be regenerated
+       // if any of these variables change then r_refdef.viewcache must be regenerated
        // by calling R_View_Update
        // (which also updates viewport, scissor, colormask)
 
@@ -1452,7 +1774,7 @@ typedef struct r_view_s
        int numfrustumplanes;
        mplane_t frustum[6];
        qboolean useclipplane;
-       qboolean usecustompvs; // uses r_viewcache.pvsbits as-is rather than computing it
+       qboolean usecustompvs; // uses r_refdef.viewcache.pvsbits as-is rather than computing it
        mplane_t clipplane;
        float frustum_x, frustum_y;
        vec3_t frustumcorner[4];
@@ -1467,50 +1789,243 @@ typedef struct r_view_s
        int width;
        int height;
        int depth;
+       r_viewport_t viewport; // note: if r_viewscale is used, the viewport.width and viewport.height may be less than width and height
 
        // which color components to allow (for anaglyph glasses)
        int colormask[4];
 
-       // global RGB color multiplier for rendering, this is required by HDR
+       // global RGB color multiplier for rendering
        float colorscale;
 
        // whether to call R_ClearScreen before rendering stuff
        qboolean clear;
+       // if true, don't clear or do any post process effects (bloom, etc)
+       qboolean isoverlay;
+       // if true, this is the MAIN view (which is, after CSQC, copied into the scene for use e.g. by r_speeds 1, showtex, prydon cursor)
+       qboolean ismain;
 
        // whether to draw r_showtris and such, this is only true for the main
-       // view render, all secondary renders (HDR, mirrors, portals, cameras,
+       // view render, all secondary renders (mirrors, portals, cameras,
        // distortion effects, etc) omit such debugging information
        qboolean showdebug;
 
        // these define which values to use in GL_CullFace calls to request frontface or backface culling
        int cullface_front;
        int cullface_back;
+
+       // render quality (0 to 1) - affects r_drawparticles_drawdistance and others
+       float quality;
 }
-r_view_t;
+r_refdef_view_t;
 
-typedef struct r_viewcache_s
+typedef struct r_refdef_viewcache_s
 {
+       // updated by gl_main_newmap()
+       int maxentities;
+       int world_numclusters;
+       int world_numclusterbytes;
+       int world_numleafs;
+       int world_numsurfaces;
+
        // these properties are generated by R_View_Update()
 
        // which entities are currently visible for this viewpoint
-       // (the used range is 0...r_refdef.numentities)
-       unsigned char entityvisible[MAX_EDICTS];
+       // (the used range is 0...r_refdef.scene.numentities)
+       unsigned char *entityvisible;
+
        // flag arrays used for visibility checking on world model
        // (all other entities have no per-surface/per-leaf visibility checks)
-       // TODO: dynamic resize according to r_refdef.worldmodel->brush.num_clusters
-       unsigned char world_pvsbits[(32768+7)>>3]; // FIXME: buffer overflow on huge maps
-       // TODO: dynamic resize according to r_refdef.worldmodel->brush.num_leafs
-       unsigned char world_leafvisible[32768]; // FIXME: buffer overflow on huge maps
-       // TODO: dynamic resize according to r_refdef.worldmodel->num_surfaces
-       unsigned char world_surfacevisible[262144]; // FIXME: buffer overflow on huge maps
+       unsigned char *world_pvsbits;
+       unsigned char *world_leafvisible;
+       unsigned char *world_surfacevisible;
        // if true, the view is currently in a leaf without pvs data
        qboolean world_novis;
 }
-r_viewcache_t;
+r_refdef_viewcache_t;
+
+// TODO: really think about which fields should go into scene and which one should stay in refdef [1/7/2008 Black]
+// maybe also refactor some of the functions to support different setting sources (ie. fogenabled, etc.) for different scenes
+typedef struct r_refdef_scene_s {
+       // 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
+       dp_model_t *worldmodel;
+
+       // renderable entities (excluding world)
+       entity_render_t **entities;
+       int numentities;
+       int maxentities;
+
+       // field of temporary entities that is reset each (client) frame
+       entity_render_t *tempentities;
+       int numtempentities;
+       int maxtempentities;
+       qboolean expandtempentities;
+
+       // renderable dynamic lights
+       rtlight_t *lights[MAX_DLIGHTS];
+       rtlight_t templights[MAX_DLIGHTS];
+       int numlights;
+
+       // intensities for light styles right now, controls rtlights
+       float rtlightstylevalue[MAX_LIGHTSTYLES];       // float fraction of base light value
+       // 8.8bit fixed point intensities for light styles
+       // controls intensity lightmap layers
+       unsigned short lightstylevalue[MAX_LIGHTSTYLES];        // 8.8 fraction of base light value
+
+       float ambient;
+
+       qboolean rtworld;
+       qboolean rtworldshadows;
+       qboolean rtdlight;
+       qboolean rtdlightshadows;
+} r_refdef_scene_t;
+
+typedef struct r_refdef_s
+{
+       // these fields define the basic rendering information for the world
+       // but not the view, which could change multiple times in one rendered
+       // frame (for example when rendering textures for certain effects)
+
+       // these are set for water warping before
+       // frustum_x/frustum_y are calculated
+       float frustumscale_x, frustumscale_y;
+
+       // current view settings (these get reset a few times during rendering because of water rendering, reflections, etc)
+       r_refdef_view_t view;
+       r_refdef_viewcache_t viewcache;
+
+       // minimum visible distance (pixels closer than this disappear)
+       double nearclip;
+       // maximum visible distance (pixels further than this disappear in 16bpp modes,
+       // in 32bpp an infinite-farclip matrix is used instead)
+       double farclip;
+
+       // fullscreen color blend
+       float viewblend[4];
+
+       r_refdef_scene_t scene;
+
+       float fogplane[4];
+       float fogplaneviewdist;
+       qboolean fogplaneviewabove;
+       float fogheightfade;
+       float fogcolor[3];
+       float fogrange;
+       float fograngerecip;
+       float fogmasktabledistmultiplier;
+#define FOGMASKTABLEWIDTH 1024
+       float fogmasktable[FOGMASKTABLEWIDTH];
+       float fogmasktable_start, fogmasktable_alpha, fogmasktable_range, fogmasktable_density;
+       float fog_density;
+       float fog_red;
+       float fog_green;
+       float fog_blue;
+       float fog_alpha;
+       float fog_start;
+       float fog_end;
+       float fog_height;
+       float fog_fadedepth;
+       qboolean fogenabled;
+       qboolean oldgl_fogenable;
+
+       // new flexible texture height fog (overrides normal fog)
+       char fog_height_texturename[64]; // note: must be 64 for the sscanf code
+       unsigned char *fog_height_table1d;
+       unsigned char *fog_height_table2d;
+       int fog_height_tablesize; // enable
+       float fog_height_tablescale;
+       float fog_height_texcoordscale;
+       char fogheighttexturename[64]; // detects changes to active fog height texture
+
+       int draw2dstage; // 0 = no, 1 = yes, other value = needs setting up again
+
+       // true during envmap command capture
+       qboolean envmap;
+
+       // brightness of world lightmaps and related lighting
+       // (often reduced when world rtlights are enabled)
+       float lightmapintensity;
+       // whether to draw world lights realtime, dlights realtime, and their shadows
+       float polygonfactor;
+       float polygonoffset;
+       float shadowpolygonfactor;
+       float shadowpolygonoffset;
+
+       // how long R_RenderView took on the previous frame
+       double lastdrawscreentime;
+
+       // rendering stats for r_speeds display
+       // (these are incremented in many places)
+       int stats[r_stat_count];
+}
+r_refdef_t;
 
 extern r_refdef_t r_refdef;
-extern r_view_t r_view;
-extern r_viewcache_t r_viewcache;
+
+typedef enum waterlevel_e
+{
+       WATERLEVEL_NONE,
+       WATERLEVEL_WETFEET,
+       WATERLEVEL_SWIMMING,
+       WATERLEVEL_SUBMERGED
+}
+waterlevel_t;
+
+typedef struct cl_clientmovement_state_s
+{
+       // entity to be ignored for movement
+       struct prvm_edict_s *self;
+       // position
+       vec3_t origin;
+       vec3_t velocity;
+       // current bounding box (different if crouched vs standing)
+       vec3_t mins;
+       vec3_t maxs;
+       // currently on the ground
+       qboolean onground;
+       // currently crouching
+       qboolean crouched;
+       // what kind of water (SUPERCONTENTS_LAVA for instance)
+       int watertype;
+       // how deep
+       waterlevel_t waterlevel;
+       // weird hacks when jumping out of water
+       // (this is in seconds and counts down to 0)
+       float waterjumptime;
+
+       // user command
+       usercmd_t cmd;
+}
+cl_clientmovement_state_t;
+void CL_ClientMovement_PlayerMove_Frame(cl_clientmovement_state_t *s);
+
+// warpzone prediction hack (CSQC builtin)
+void CL_RotateMoves(const matrix4x4_t *m);
+
+void CL_NewFrameReceived(int num);
+void CL_ParseEntityLump(char *entitystring);
+void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
+void CL_RelinkLightFlashes(void);
+void Sbar_ShowFPS(void);
+void Sbar_ShowFPS_Update(void);
+void Host_SaveConfig(void);
+void Host_LoadConfig_f(void);
+void CL_UpdateMoveVars(void);
+void SCR_CaptureVideo_SoundFrame(const portable_sampleframe_t *paintbuffer, size_t length);
+void V_DriftPitch(void);
+void V_FadeViewFlashs(void);
+void V_CalcViewBlend(void);
+void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewangles, qboolean teleported, qboolean clonground, qboolean clcmdjump, float clstatsviewheight, qboolean cldead, qboolean clintermission, const vec3_t clvelocity);
+void V_CalcRefdef(void);
+void CL_Locs_Reload_f(void);
 
 #endif