#define CLIENT_H
#include "matrixlib.h"
-
-// LordHavoc: 256 dynamic lights
-#define MAX_DLIGHTS 256
-
-// this is the maximum number of input packets that can be predicted
-#define CL_MAX_USERCMDS 256
+#include "snd_main.h"
// flags for rtlight rendering
#define LIGHTFLAG_NORMALMODE 1
#define LIGHTFLAG_REALTIMEMODE 2
+typedef struct tridecal_s
+{
+ // color and initial alpha value
+ unsigned char colors[3][4];
+ // 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;
+}
+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;
// 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
// 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_Shadow_Cubemap(rtlight->cubemapname)
rtexture_t *currentcubemap;
- // static light info
- // true if this light should be compiled as a static light
+ /// 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;
}
rtlight_t;
}
dlight_t;
-typedef struct frameblend_s
+#define MAX_FRAMEGROUPBLENDS 4
+typedef struct framegroupblend_s
{
+ // animation number and blend factor
+ // (for most models this is the frame number)
int frame;
float lerp;
+ // time frame began playing (for framegroup animations)
+ double start;
+}
+framegroupblend_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 subframe;
+ float lerp;
}
frameblend_t;
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
// 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];
+
+ // animation cache index
+ int animcacheindex;
// 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;
vec_t cursor_fraction;
int cursor_entitynumber;
- double time;
- double receivetime;
+ 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;
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
#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
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("%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;
// 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 timedemo;
// -1 = use normal cd track
// (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;
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;
PARTICLE_BILLBOARD = 0,
PARTICLE_SPARK = 1,
PARTICLE_ORIENTED_DOUBLESIDED = 2,
- PARTICLE_BEAM = 3
+ PARTICLE_VBEAM = 3,
+ PARTICLE_HBEAM = 4,
+ PARTICLE_INVALID = -1
}
porientation_t;
{
PBLEND_ALPHA = 0,
PBLEND_ADD = 1,
- PBLEND_MOD = 2
+ PBLEND_INVMOD = 2,
+ PBLEND_INVALID = -1
}
pblend_t;
typedef struct decal_s
{
- // fields used by rendering: (40 bytes)
+ // fields used by rendering: (44 bytes)
unsigned short typeindex;
unsigned short texnum;
vec3_t org;
float alpha; // 0-255
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
}
typedef struct particle_s
{
// fields used by rendering: (40 bytes)
- unsigned short typeindex;
- unsigned short texnum;
+ unsigned char typeindex;
+ pblend_t blendmode;
+ porientation_t orientation;
+ unsigned char texnum;
vec3_t org;
vec3_t vel; // velocity of particle, or orientation of decal, or end point of beam
float size;
float alpha; // 0-255
unsigned char color[3];
unsigned char qualityreduction; // enables skipping of this particle according to r_refdef.view.qualityreduction
+ float stretch; // only for sparks
+ int staincolor;
+ signed char staintexnum;
+ float stainsizefactor;
// fields not used by rendering: (40 bytes)
float sizeincrease; // rate of size change per second
// 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;
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;
double lastpackettime;
// movement parameters for client prediction
+ unsigned int moveflags;
float movevars_wallfriction;
float movevars_waterfriction;
float movevars_friction;
float movevars_stepheight;
float movevars_airaccel_qw;
float movevars_airaccel_sideways_friction;
+ float movevars_airstopaccelerate;
+ float movevars_airstrafeaccelerate;
+ float movevars_maxairstrafespeed;
+ float movevars_aircontrol;
+ float movevars_warsowbunny_airforwardaccel;
+ float movevars_warsowbunny_accel;
+ float movevars_warsowbunny_topspeed;
+ float movevars_warsowbunny_turnaccel;
+ float movevars_warsowbunny_backtosideratio;
+ float movevars_ticrate;
// models used by qw protocol
int qw_modelindex_spike;
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_render_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_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);
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
void CL_Particles_Clear(void);
void CL_Particles_Init(void);
void CL_Particles_Shutdown(void);
+particle_t *CL_NewParticle(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);
typedef enum effectnameindex_s
{
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
{
}
r_refdef_stats_t;
+typedef enum r_viewport_type_e
+{
+ R_VIEWPORTTYPE_ORTHO,
+ R_VIEWPORTTYPE_PERSPECTIVE,
+ R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP,
+ R_VIEWPORTTYPE_PERSPECTIVECUBESIDE,
+ R_VIEWPORTTYPE_TOTAL
+}
+r_viewport_type_t;
+
+typedef struct r_viewport_s
+{
+ double m[16];
+ 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;
+}
+r_viewport_t;
+
typedef struct r_refdef_view_s
{
// view information (changes multiple times per frame)
int width;
int height;
int depth;
+ r_viewport_t viewport;
// which color components to allow (for anaglyph glasses)
int colormask[4];
typedef struct r_refdef_viewcache_s
{
+ // updated by gl_main_newmap()
+ int maxentities;
+ int world_numclusters;
+ 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.scene.numentities)
- unsigned char entityvisible[MAX_EDICTS];
+ 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.scene.worldmodel->brush.num_clusters
- unsigned char world_pvsbits[(32768+7)>>3]; // FIXME: buffer overflow on huge maps
- // TODO: dynamic resize according to r_refdef.scene.worldmodel->brush.num_leafs
- unsigned char world_leafvisible[32768]; // FIXME: buffer overflow on huge maps
- // TODO: dynamic resize according to r_refdef.scene.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;
}
entity_render_t *worldentity;
// same as worldentity->model
- model_t *worldmodel;
+ dp_model_t *worldmodel;
// renderable entities (excluding world)
entity_render_t **entities;
int maxtempentities;
// renderable dynamic lights
- rtlight_t lights[MAX_DLIGHTS];
+ rtlight_t *lights[MAX_DLIGHTS];
+ rtlight_t templights[MAX_DLIGHTS];
int numlights;
// intensities for light styles right now, controls rtlights
- float rtlightstylevalue[256]; // float fraction of base light value
+ 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[256]; // 8.8 fraction of base light value
+ unsigned short lightstylevalue[MAX_LIGHTSTYLES]; // 8.8 fraction of base light value
float ambient;
r_refdef_scene_t scene;
- vec3_t fogcolor;
- vec_t fogrange;
- vec_t fograngerecip;
- vec_t fogmasktabledistmultiplier;
+ 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_alpha;
float fog_start;
float fog_end;
+ float fog_height;
+ float fog_fadedepth;
qboolean fogenabled;
qboolean oldgl_fogenable;