#include "quakedef.h"
#include "cl_collision.h"
+#include "cl_gecko.h"
#include "cl_video.h"
#include "image.h"
#include "csprogs.h"
cvar_t cl_explosions_size_end = {CVAR_SAVE, "cl_explosions_size_end", "128","ending alpha of an explosion shell (just before it disappears)"};
cvar_t cl_explosions_lifetime = {CVAR_SAVE, "cl_explosions_lifetime", "0.5","how long an explosion shell lasts"};
-cvar_t cl_stainmaps = {CVAR_SAVE, "cl_stainmaps", "1","stains lightmaps, much faster than decals but blurred"};
+cvar_t cl_stainmaps = {CVAR_SAVE, "cl_stainmaps", "0","stains lightmaps, much faster than decals but blurred"};
cvar_t cl_stainmaps_clearonload = {CVAR_SAVE, "cl_stainmaps_clearonload", "1","clear stainmaps on map restart"};
cvar_t cl_beams_polygons = {CVAR_SAVE, "cl_beams_polygons", "1","use beam polygons instead of models"};
client_state_t cl;
#define MAX_PARTICLES 32768 // default max # of particles at one time
+#define MAX_DECALS 32768 // default max # of decals at one time
#define ABSOLUTE_MIN_PARTICLES 512 // no fewer than this no matter what's on the command line
/*
// reset the view zoom interpolation
cl.mviewzoom[0] = cl.mviewzoom[1] = 1;
+ cl.sensitivityscale = 1.0f;
// enable rendering of the world and such
cl.csqc_vidvars.drawworld = true;
cl.max_lightstyle = MAX_LIGHTSTYLES;
cl.max_brushmodel_entities = MAX_EDICTS;
cl.max_particles = MAX_PARTICLES;
+ cl.max_decals = MAX_DECALS;
+ cl.max_showlmps = 0;
// COMMANDLINEOPTION: Client: -particles <number> changes maximum number of particles at once, default 32768
i = COM_CheckParm ("-particles");
cl.lightstyle = (lightstyle_t *)Mem_Alloc(cls.levelmempool, cl.max_lightstyle * sizeof(lightstyle_t));
cl.brushmodel_entities = (int *)Mem_Alloc(cls.levelmempool, cl.max_brushmodel_entities * sizeof(int));
cl.particles = (particle_t *) Mem_Alloc(cls.levelmempool, cl.max_particles * sizeof(particle_t));
+ cl.decals = (decal_t *) Mem_Alloc(cls.levelmempool, cl.max_decals * sizeof(decal_t));
+ cl.showlmps = NULL;
// LordHavoc: have to set up the baseline info for alpha and other stuff
for (i = 0;i < cl.max_entities;i++)
ent->state_current.active = true;
ent->render.model = cl.worldmodel = NULL; // no world model yet
ent->render.alpha = 1;
- ent->render.colormap = -1; // no special coloring
ent->render.flags = RENDER_SHADOW | RENDER_LIGHT;
Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, 0, 0, 0, 0, 0, 0, 1);
CL_UpdateRenderEntity(&ent->render);
// mark all frames invalid for delta
memset(cl.qw_deltasequence, -1, sizeof(cl.qw_deltasequence));
+ // set bestweapon data back to Quake data
+ IN_BestWeapon_ResetData();
+
CL_Screen_NewMap();
}
}
}
+static void CL_UpdateRenderEntity_Lighting(entity_render_t *ent)
+{
+ vec3_t tempdiffusenormal;
+
+ // fetch the lighting from the worldmodel data
+ VectorSet(ent->modellight_ambient, r_ambient.value * (2.0f / 128.0f), r_ambient.value * (2.0f / 128.0f), r_ambient.value * (2.0f / 128.0f));
+ VectorClear(ent->modellight_diffuse);
+ VectorClear(tempdiffusenormal);
+ if ((ent->flags & RENDER_LIGHT) && cl.worldmodel && cl.worldmodel->brush.LightPoint)
+ {
+ vec3_t org;
+ Matrix4x4_OriginFromMatrix(&ent->matrix, org);
+ cl.worldmodel->brush.LightPoint(cl.worldmodel, org, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
+ }
+ else // highly rare
+ VectorSet(ent->modellight_ambient, 1, 1, 1);
+
+ // move the light direction into modelspace coordinates for lighting code
+ Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
+ if(VectorLength2(ent->modellight_lightdir) <= 0)
+ VectorSet(ent->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here
+ VectorNormalize(ent->modellight_lightdir);
+}
+
//static const vec3_t nomodelmins = {-16, -16, -16};
//static const vec3_t nomodelmaxs = {16, 16, 16};
void CL_UpdateRenderEntity(entity_render_t *ent)
ent->maxs[1] = org[1] + 16;
ent->maxs[2] = org[2] + 16;
}
+ CL_UpdateRenderEntity_Lighting(ent);
}
/*
memset (ent, 0, sizeof(*ent));
r_refdef.entities[r_refdef.numentities++] = &ent->render;
- ent->render.colormap = -1; // no special coloring
ent->render.alpha = 1;
VectorSet(ent->render.colormod, 1, 1, 1);
return ent;
{
if (!cl.lightstyle || !cl.lightstyle[j].length)
{
+ r_refdef.rtlightstylevalue[j] = 1;
r_refdef.lightstylevalue[j] = 256;
continue;
}
l = (i-1) % cl.lightstyle[j].length;
k = cl.lightstyle[j].map[k] - 'a';
l = cl.lightstyle[j].map[l] - 'a';
- r_refdef.lightstylevalue[j] = (unsigned short)(((k*frac)+(l*(1-frac)))*22);
+ // rtlightstylevalue is always interpolated because it has no bad
+ // consequences for performance
+ // lightstylevalue is subject to a cvar for performance reasons;
+ // skipping lightmap updates on most rendered frames substantially
+ // improves framerates (but makes light fades look bad)
+ r_refdef.rtlightstylevalue[j] = ((k*frac)+(l*(1-frac)))*(22/256.0f);
+ r_refdef.lightstylevalue[j] = r_lerplightstyles.integer ? (unsigned short)(((k*frac)+(l*(1-frac)))*22) : k*22;
}
}
flag->render.model = cl.model_precache[cl.qw_modelindex_flag];
flag->render.skinnum = skin;
- flag->render.colormap = -1; // no special coloring
flag->render.alpha = 1;
VectorSet(flag->render.colormod, 1, 1, 1);
// attach the flag to the player matrix
extern void V_CalcViewBlend(void);
extern void V_CalcRefdef(void);
+void CL_SetEntityColormapColors(entity_render_t *ent, int colormap)
+{
+ const unsigned char *cbcolor;
+ if (colormap >= 0)
+ {
+ cbcolor = palette_rgb_pantscolormap[colormap & 0xF];
+ VectorScale(cbcolor, (1.0f / 255.0f), ent->colormap_pantscolor);
+ cbcolor = palette_rgb_shirtcolormap[(colormap & 0xF0) >> 4];
+ VectorScale(cbcolor, (1.0f / 255.0f), ent->colormap_shirtcolor);
+ }
+ else
+ {
+ VectorClear(ent->colormap_pantscolor);
+ VectorClear(ent->colormap_shirtcolor);
+ }
+}
+
// note this is a recursive function, recursionlimit should be 32 or so on the initial call
void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolate)
{
const matrix4x4_t *matrix;
matrix4x4_t blendmatrix, tempmatrix, matrix2;
- int j, k, l;
+ int j, k, l, frame;
float origin[3], angles[3], delta[3], lerp, d;
entity_t *t;
model_t *model;
VectorScale(e->state_current.colormod, (1.0f / 32.0f), e->render.colormod);
e->render.entitynumber = e - cl.entities;
if (e->state_current.flags & RENDER_COLORMAPPED)
- {
- int cb;
- unsigned char *cbcolor;
- e->render.colormap = e->state_current.colormap;
- cb = (e->render.colormap & 0xF) << 4;cb += (cb >= 128 && cb < 224) ? 4 : 12;
- cbcolor = (unsigned char *) (&palette_complete[cb]);
- e->render.colormap_pantscolor[0] = cbcolor[0] * (1.0f / 255.0f);
- e->render.colormap_pantscolor[1] = cbcolor[1] * (1.0f / 255.0f);
- e->render.colormap_pantscolor[2] = cbcolor[2] * (1.0f / 255.0f);
- cb = (e->render.colormap & 0xF0);cb += (cb >= 128 && cb < 224) ? 4 : 12;
- cbcolor = (unsigned char *) (&palette_complete[cb]);
- e->render.colormap_shirtcolor[0] = cbcolor[0] * (1.0f / 255.0f);
- e->render.colormap_shirtcolor[1] = cbcolor[1] * (1.0f / 255.0f);
- e->render.colormap_shirtcolor[2] = cbcolor[2] * (1.0f / 255.0f);
- }
- else if (e->state_current.colormap && cl.scores != NULL)
- {
- int cb;
- unsigned char *cbcolor;
- e->render.colormap = cl.scores[e->state_current.colormap - 1].colors; // color it
- cb = (e->render.colormap & 0xF) << 4;cb += (cb >= 128 && cb < 224) ? 4 : 12;
- cbcolor = (unsigned char *) (&palette_complete[cb]);
- e->render.colormap_pantscolor[0] = cbcolor[0] * (1.0f / 255.0f);
- e->render.colormap_pantscolor[1] = cbcolor[1] * (1.0f / 255.0f);
- e->render.colormap_pantscolor[2] = cbcolor[2] * (1.0f / 255.0f);
- cb = (e->render.colormap & 0xF0);cb += (cb >= 128 && cb < 224) ? 4 : 12;
- cbcolor = (unsigned char *) (&palette_complete[cb]);
- e->render.colormap_shirtcolor[0] = cbcolor[0] * (1.0f / 255.0f);
- e->render.colormap_shirtcolor[1] = cbcolor[1] * (1.0f / 255.0f);
- e->render.colormap_shirtcolor[2] = cbcolor[2] * (1.0f / 255.0f);
- }
+ CL_SetEntityColormapColors(&e->render, e->state_current.colormap);
+ else if (e->state_current.colormap > 0 && e->state_current.colormap <= cl.maxclients && cl.scores != NULL)
+ CL_SetEntityColormapColors(&e->render, cl.scores[e->state_current.colormap-1].colors);
else
- {
- e->render.colormap = -1; // no special coloring
- VectorClear(e->render.colormap_pantscolor);
- VectorClear(e->render.colormap_shirtcolor);
- }
+ CL_SetEntityColormapColors(&e->render, -1);
e->render.skinnum = e->state_current.skin;
if (e->state_current.tagentity)
{
}
// model setup and some modelflags
- if(e->state_current.modelindex < MAX_MODELS)
+ frame = e->state_current.frame;
+ if (e->state_current.modelindex < MAX_MODELS)
e->render.model = cl.model_precache[e->state_current.modelindex];
+ else
+ e->render.model = NULL;
if (e->render.model)
{
+ if (e->render.skinnum >= e->render.model->numskins)
+ e->render.skinnum = 0;
+ if (frame >= e->render.model->numframes)
+ frame = 0;
// models can set flags such as EF_ROCKET
// this 0xFF800000 mask is EF_NOMODELFLAGS plus all the higher EF_ flags such as EF_ROCKET
if (!(e->render.effects & 0xFF800000))
}
// animation lerp
- if (e->render.frame2 == e->state_current.frame)
+ if (e->render.frame2 == frame)
{
// update frame lerp fraction
e->render.framelerp = 1;
// begin a new frame lerp
e->render.frame1 = e->render.frame2;
e->render.frame1time = e->render.frame2time;
- e->render.frame2 = e->state_current.frame;
+ e->render.frame2 = frame;
e->render.frame2time = cl.time;
e->render.framelerp = 0;
}
Matrix4x4_CreateFromQuakeEntity(&e->render.matrix, origin[0], origin[1], origin[2], angles[0], angles[1], angles[2], e->render.scale);
}
- // make the other useful stuff
- CL_UpdateRenderEntity(&e->render);
-
// tenebrae's sprites are all additive mode (weird)
if (gamemode == GAME_TENEBRAE && e->render.model && e->render.model->type == mod_sprite)
e->render.effects |= EF_ADDITIVE;
e->render.flags |= RENDER_SHADOW;
if (e->render.flags & RENDER_VIEWMODEL)
e->render.flags |= RENDER_NOSELFSHADOW;
+
+ // make the other useful stuff
+ CL_UpdateRenderEntity(&e->render);
}
// creates light and trails from an entity
// * 4 for the expansion from 0-255 to 0-1023 range,
// / 255 to scale down byte colors
dlightradius = max(dlightradius, e->state_current.glowsize * 4);
- VectorMA(dlightcolor, (1.0f / 255.0f), (unsigned char *)&palette_complete[e->state_current.glowcolor], dlightcolor);
+ VectorMA(dlightcolor, (1.0f / 255.0f), palette_rgb[e->state_current.glowcolor], dlightcolor);
}
// make the glow dlight
if (dlightradius > 0 && (dlightcolor[0] || dlightcolor[1] || dlightcolor[2]) && !(e->render.flags & RENDER_VIEWMODEL) && r_refdef.numlights < MAX_DLIGHTS)
entity_t *ent = &cl.entities[0];
// FIXME: this should be done at load
ent->render.matrix = identitymatrix;
- CL_UpdateRenderEntity(&ent->render);
ent->render.flags = RENDER_SHADOW;
if (!r_fullbright.integer)
ent->render.flags |= RENDER_LIGHT;
VectorSet(ent->render.colormod, 1, 1, 1);
+ CL_UpdateRenderEntity(&ent->render);
r_refdef.worldentity = &ent->render;
r_refdef.worldmodel = cl.worldmodel;
}
// if the model was not loaded when the static entity was created we
// need to re-fetch the model pointer
e->render.model = cl.model_precache[e->state_baseline.modelindex];
- CL_UpdateRenderEntity(&e->render);
// either fullbright or lit
if (!(e->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer)
e->render.flags |= RENDER_LIGHT;
e->render.flags |= RENDER_SHADOW;
VectorSet(e->render.colormod, 1, 1, 1);
R_LerpAnimation(&e->render);
+ CL_UpdateRenderEntity(&e->render);
r_refdef.entities[r_refdef.numentities++] = &e->render;
}
}
ent->render.model = cl.model_precache[e->modelindex];
else
ent->render.model = cl.csqc_model_precache[-(e->modelindex+1)];
- ent->render.colormap = -1; // no special coloring
ent->render.alpha = 1;
VectorSet(ent->render.colormod, 1, 1, 1);
// normal stuff
ent->render.model = cl.model_precache[cl.qw_modelindex_spike];
- ent->render.colormap = -1; // no special coloring
ent->render.alpha = 1;
VectorSet(ent->render.colormod, 1, 1, 1);
CL_RelinkLightFlashes();
CSQC_RelinkAllEntities(ENTMASK_ENGINE | ENTMASK_ENGINEVIEWMODELS);
- // move particles
+ // move decals, particles, and any other effects
+ CL_MoveDecals();
CL_MoveParticles();
R_MoveExplosions();
}
{
if (Cmd_Argc () == 1)
{
- Con_Printf("\"fog\" is \"%f %f %f %f\"\n", r_refdef.fog_density, r_refdef.fog_red, r_refdef.fog_green, r_refdef.fog_blue);
+ Con_Printf("\"fog\" is \"%f %f %f %f %f %f %f\"\n", r_refdef.fog_density, r_refdef.fog_red, r_refdef.fog_green, r_refdef.fog_blue, r_refdef.fog_alpha, r_refdef.fog_start, r_refdef.fog_end);
return;
}
- r_refdef.fog_density = atof(Cmd_Argv(1));
- r_refdef.fog_red = atof(Cmd_Argv(2));
- r_refdef.fog_green = atof(Cmd_Argv(3));
- r_refdef.fog_blue = atof(Cmd_Argv(4));
+ r_refdef.fog_start = 0;
+ r_refdef.fog_end = 16384;
+ r_refdef.fog_alpha = 1;
+ if(Cmd_Argc() > 1)
+ r_refdef.fog_density = atof(Cmd_Argv(1));
+ if(Cmd_Argc() > 2)
+ r_refdef.fog_red = atof(Cmd_Argv(2));
+ if(Cmd_Argc() > 3)
+ r_refdef.fog_green = atof(Cmd_Argv(3));
+ if(Cmd_Argc() > 4)
+ r_refdef.fog_blue = atof(Cmd_Argv(4));
+ if(Cmd_Argc() > 5)
+ r_refdef.fog_alpha = atof(Cmd_Argv(5));
+ if(Cmd_Argc() > 6)
+ r_refdef.fog_start = atof(Cmd_Argv(6));
+ if(Cmd_Argc() > 7)
+ r_refdef.fog_end = atof(Cmd_Argv(7));
}
/*
Cvar_RegisterVariable (&cl_autodemo);
Cvar_RegisterVariable (&cl_autodemo_nameformat);
- Cmd_AddCommand ("fog", CL_Fog_f, "set global fog parameters (density red green blue)");
+ Cmd_AddCommand ("fog", CL_Fog_f, "set global fog parameters (density red green blue [alpha [mindist maxdist]])");
// LordHavoc: added pausedemo
Cmd_AddCommand ("pausedemo", CL_PauseDemo_f, "pause demo playback (can also safely pause demo recording if using QUAKE, QUAKEDP or NEHAHRAMOVIE protocol, useful for making movies)");
CL_Screen_Init();
CL_Video_Init();
+#ifdef SUPPORT_GECKO
+ CL_Gecko_Init();
+#endif
}