X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=view.c;h=8b55d0c3f30cad8c44fd1428965c75d385c3fe1f;hp=5a8e7af55913760ca2c637bc2d48c3b9a6e11027;hb=001e49ea761abfc2982a5999e102b6bfe83a4e50;hpb=d57be67cb00229acb8564b92c8b7c58eeed8a0cb diff --git a/view.c b/view.c index 5a8e7af5..8b55d0c3 100644 --- a/view.c +++ b/view.c @@ -20,6 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // view.c -- player eye positioning #include "quakedef.h" +#include "cl_collision.h" + +void CL_VM_UpdateDmgGlobals (int dmg_take, int dmg_save, vec3_t dmg_origin); /* @@ -30,35 +33,52 @@ when crossing a water boudnary. */ -cvar_t cl_rollspeed = {0, "cl_rollspeed", "200"}; -cvar_t cl_rollangle = {0, "cl_rollangle", "2.0"}; +cvar_t cl_rollspeed = {0, "cl_rollspeed", "200", "how much strafing is necessary to tilt the view"}; +cvar_t cl_rollangle = {0, "cl_rollangle", "2.0", "how much to tilt the view when strafing"}; + +cvar_t cl_bob = {CVAR_SAVE, "cl_bob","0.02", "view bobbing amount"}; +cvar_t cl_bobcycle = {CVAR_SAVE, "cl_bobcycle","0.6", "view bobbing speed"}; +cvar_t cl_bobup = {CVAR_SAVE, "cl_bobup","0.5", "view bobbing adjustment that makes the up or down swing of the bob last longer"}; + +cvar_t cl_bobmodel = {CVAR_SAVE, "cl_bobmodel", "1", "enables gun bobbing"}; +cvar_t cl_bobmodel_side = {CVAR_SAVE, "cl_bobmodel_side", "0.15", "gun bobbing sideways sway amount"}; +cvar_t cl_bobmodel_up = {CVAR_SAVE, "cl_bobmodel_up", "0.06", "gun bobbing upward movement amount"}; +cvar_t cl_bobmodel_speed = {CVAR_SAVE, "cl_bobmodel_speed", "7", "gun bobbing speed"}; + +cvar_t cl_viewmodel_scale = {0, "cl_viewmodel_scale", "1", "changes size of gun model, lower values prevent poking into walls but cause strange artifacts on lighting and especially r_stereo/vid_stereobuffer options where the size of the gun becomes visible"}; -cvar_t cl_bob = {0, "cl_bob","0.02"}; -cvar_t cl_bobcycle = {0, "cl_bobcycle","0.6"}; -cvar_t cl_bobup = {0, "cl_bobup","0.5"}; +cvar_t v_kicktime = {0, "v_kicktime", "0.5", "how long a view kick from damage lasts"}; +cvar_t v_kickroll = {0, "v_kickroll", "0.6", "how much a view kick from damage rolls your view"}; +cvar_t v_kickpitch = {0, "v_kickpitch", "0.6", "how much a view kick from damage pitches your view"}; -cvar_t v_kicktime = {0, "v_kicktime", "0.5"}; -cvar_t v_kickroll = {0, "v_kickroll", "0.6"}; -cvar_t v_kickpitch = {0, "v_kickpitch", "0.6"}; +cvar_t v_iyaw_cycle = {0, "v_iyaw_cycle", "2", "v_idlescale yaw speed"}; +cvar_t v_iroll_cycle = {0, "v_iroll_cycle", "0.5", "v_idlescale roll speed"}; +cvar_t v_ipitch_cycle = {0, "v_ipitch_cycle", "1", "v_idlescale pitch speed"}; +cvar_t v_iyaw_level = {0, "v_iyaw_level", "0.3", "v_idlescale yaw amount"}; +cvar_t v_iroll_level = {0, "v_iroll_level", "0.1", "v_idlescale roll amount"}; +cvar_t v_ipitch_level = {0, "v_ipitch_level", "0.3", "v_idlescale pitch amount"}; -cvar_t v_punch = {0, "v_punch", "1"}; +cvar_t v_idlescale = {0, "v_idlescale", "0", "how much of the quake 'drunken view' effect to use"}; -cvar_t v_iyaw_cycle = {0, "v_iyaw_cycle", "2"}; -cvar_t v_iroll_cycle = {0, "v_iroll_cycle", "0.5"}; -cvar_t v_ipitch_cycle = {0, "v_ipitch_cycle", "1"}; -cvar_t v_iyaw_level = {0, "v_iyaw_level", "0.3"}; -cvar_t v_iroll_level = {0, "v_iroll_level", "0.1"}; -cvar_t v_ipitch_level = {0, "v_ipitch_level", "0.3"}; +cvar_t crosshair = {CVAR_SAVE, "crosshair", "0", "selects crosshair to use (0 is none)"}; -cvar_t v_idlescale = {0, "v_idlescale", "0"}; +cvar_t v_centermove = {0, "v_centermove", "0.15", "how long before the view begins to center itself (if freelook/+mlook/+jlook/+klook are off)"}; +cvar_t v_centerspeed = {0, "v_centerspeed","500", "how fast the view centers itself"}; -cvar_t crosshair = {CVAR_SAVE, "crosshair", "0"}; +cvar_t cl_stairsmoothspeed = {CVAR_SAVE, "cl_stairsmoothspeed", "160", "how fast your view moves upward/downward when running up/down stairs"}; -//cvar_t gl_cshiftpercent = {0, "gl_cshiftpercent", "100"}; -cvar_t gl_polyblend = {CVAR_SAVE, "gl_polyblend", "1"}; +cvar_t chase_back = {CVAR_SAVE, "chase_back", "48", "chase cam distance from the player"}; +cvar_t chase_up = {CVAR_SAVE, "chase_up", "24", "chase cam distance from the player"}; +cvar_t chase_active = {CVAR_SAVE, "chase_active", "0", "enables chase cam"}; +cvar_t chase_overhead = {CVAR_SAVE, "chase_overhead", "0", "chase cam looks straight down if this is not zero"}; +// GAME_GOODVSBAD2 +cvar_t chase_stevie = {0, "chase_stevie", "0", "chase cam view from above (used only by GoodVsBad2)"}; -cvar_t v_centermove = {0, "v_centermove", "0.15"}; -cvar_t v_centerspeed = {0, "v_centerspeed","500"}; +cvar_t v_deathtilt = {0, "v_deathtilt", "1", "whether to use sideways view when dead"}; +cvar_t v_deathtiltangle = {0, "v_deathtiltangle", "80", "what roll angle to use when tilting the view while dead"}; + +// Prophecy camera pitchangle by Alexander "motorsep" Zubov +cvar_t chase_pitchangle = {CVAR_SAVE, "chase_pitchangle", "55", "chase cam pitch angle"}; float v_dmg_time, v_dmg_roll, v_dmg_pitch; @@ -76,15 +96,13 @@ float V_CalcRoll (vec3_t angles, vec3_t velocity) float sign; float side; float value; - + AngleVectors (angles, NULL, right, NULL); side = DotProduct (velocity, right); sign = side < 0 ? -1 : 1; side = fabs(side); - + value = cl_rollangle.value; -// if (cl.inwater) -// value *= 6; if (side < cl_rollspeed.value) side = side * value / cl_rollspeed.value; @@ -95,51 +113,11 @@ float V_CalcRoll (vec3_t angles, vec3_t velocity) } - -/* -=============== -V_CalcBob - -=============== -*/ -float V_CalcBob (void) -{ - float bob; - float cycle; - - cycle = cl.time - (int)(cl.time/cl_bobcycle.value)*cl_bobcycle.value; - cycle /= cl_bobcycle.value; - if (cycle < cl_bobup.value) - cycle = M_PI * cycle / cl_bobup.value; - else - cycle = M_PI + M_PI*(cycle-cl_bobup.value)/(1.0 - cl_bobup.value); - -// bob is proportional to velocity in the xy plane -// (don't count Z, or jumping messes it up) - - bob = sqrt(cl.velocity[0]*cl.velocity[0] + cl.velocity[1]*cl.velocity[1]) * cl_bob.value; -//Con_Printf ("speed: %5.1f\n", Length(cl.velocity)); - bob = bob*0.3 + bob*0.7*sin(cycle); - if (bob > 4) - bob = 4; - else if (bob < -7) - bob = -7; - return bob; - -} - - -//============================================================================= - - void V_StartPitchDrift (void) { -#if 1 if (cl.laststop == cl.time) - { return; // something else is keeping it from drifting - } -#endif + if (cl.nodrift || !cl.pitchvel) { cl.pitchvel = v_centerspeed.value; @@ -185,15 +163,15 @@ void V_DriftPitch (void) if ( fabs(cl.cmd.forwardmove) < cl_forwardspeed.value) cl.driftmove = 0; else - cl.driftmove += cl.frametime; - + cl.driftmove += cl.realframetime; + if ( cl.driftmove > v_centermove.value) { V_StartPitchDrift (); } return; } - + delta = cl.idealpitch - cl.viewangles[PITCH]; if (!delta) @@ -202,10 +180,8 @@ void V_DriftPitch (void) return; } - move = cl.frametime * cl.pitchvel; - cl.pitchvel += cl.frametime * v_centerspeed.value; - -//Con_Printf ("move: %f (%f)\n", move, cl.frametime); + move = cl.realframetime * cl.pitchvel; + cl.pitchvel += cl.realframetime * v_centerspeed.value; if (delta > 0) { @@ -228,25 +204,14 @@ void V_DriftPitch (void) } +/* +============================================================================== + SCREEN FLASHES +============================================================================== +*/ -/* -============================================================================== - - SCREEN FLASHES - -============================================================================== -*/ - - -cshift_t cshift_empty = { {130,80,50}, 0 }; -cshift_t cshift_water = { {130,80,50}, 128 }; -cshift_t cshift_slime = { {0,25,5}, 150 }; -cshift_t cshift_lava = { {255,80,0}, 150 }; - -byte ramps[3][256]; -float v_blend[4]; // rgba 0.0 - 1.0 /* =============== @@ -255,18 +220,20 @@ V_ParseDamage */ void V_ParseDamage (void) { - int armor, blood; - vec3_t from; - int i; - vec3_t forward, right; - entity_t *ent; - float side; - float count; - + int armor, blood; + vec3_t from; + //vec3_t forward, right; + vec3_t localfrom; + entity_t *ent; + //float side; + float count; + armor = MSG_ReadByte (); blood = MSG_ReadByte (); - for (i=0 ; i<3 ; i++) - from[i] = MSG_ReadCoord (); + MSG_ReadVector(from, cls.protocol); + + // Send the Dmg Globals to CSQC + CL_VM_UpdateDmgGlobals(blood, armor, from); count = blood*0.5 + armor*0.5; if (count < 10) @@ -274,65 +241,57 @@ void V_ParseDamage (void) cl.faceanimtime = cl.time + 0.2; // put sbar face into pain frame - if (gl_polyblend.value) - { - cl.cshifts[CSHIFT_DAMAGE].percent += 3*count; - if (cl.cshifts[CSHIFT_DAMAGE].percent < 0) - cl.cshifts[CSHIFT_DAMAGE].percent = 0; - if (cl.cshifts[CSHIFT_DAMAGE].percent > 150) - cl.cshifts[CSHIFT_DAMAGE].percent = 150; + cl.cshifts[CSHIFT_DAMAGE].percent += 3*count; + cl.cshifts[CSHIFT_DAMAGE].alphafade = 150; + if (cl.cshifts[CSHIFT_DAMAGE].percent < 0) + cl.cshifts[CSHIFT_DAMAGE].percent = 0; + if (cl.cshifts[CSHIFT_DAMAGE].percent > 150) + cl.cshifts[CSHIFT_DAMAGE].percent = 150; - if (armor > blood) - { - cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200; - cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100; - cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 100; - } - else if (armor) - { - cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 220; - cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 50; - cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50; - } - else - { - cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 255; - cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 0; - cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 0; - } + if (armor > blood) + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200; + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100; + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 100; + } + else if (armor) + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 220; + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 50; + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50; + } + else + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 255; + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 0; + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 0; } -// -// calculate view angle kicks -// - ent = &cl_entities[cl.viewentity]; - - VectorSubtract (from, ent->render.origin, from); - VectorNormalize (from); - - AngleVectors (ent->render.angles, forward, right, NULL); - - side = DotProduct (from, right); - v_dmg_roll = count*side*v_kickroll.value; - - side = DotProduct (from, forward); - v_dmg_pitch = count*side*v_kickpitch.value; - - v_dmg_time = v_kicktime.value; + // calculate view angle kicks + if (cl.entities[cl.viewentity].state_current.active) + { + ent = &cl.entities[cl.viewentity]; + Matrix4x4_Transform(&ent->render.inversematrix, from, localfrom); + VectorNormalize(localfrom); + v_dmg_pitch = count * localfrom[0] * v_kickpitch.value; + v_dmg_roll = count * localfrom[1] * v_kickroll.value; + v_dmg_time = v_kicktime.value; + } } +static cshift_t v_cshift; /* ================== V_cshift_f ================== */ -void V_cshift_f (void) +static void V_cshift_f (void) { - cshift_empty.destcolor[0] = atoi(Cmd_Argv(1)); - cshift_empty.destcolor[1] = atoi(Cmd_Argv(2)); - cshift_empty.destcolor[2] = atoi(Cmd_Argv(3)); - cshift_empty.percent = atoi(Cmd_Argv(4)); + v_cshift.destcolor[0] = atof(Cmd_Argv(1)); + v_cshift.destcolor[1] = atof(Cmd_Argv(2)); + v_cshift.destcolor[2] = atof(Cmd_Argv(3)); + v_cshift.percent = atof(Cmd_Argv(4)); } @@ -343,482 +302,448 @@ V_BonusFlash_f When you run over an item, the server sends this command ================== */ -void V_BonusFlash_f (void) +static void V_BonusFlash_f (void) { - if (gl_polyblend.value) + if(Cmd_Argc() == 1) { cl.cshifts[CSHIFT_BONUS].destcolor[0] = 215; cl.cshifts[CSHIFT_BONUS].destcolor[1] = 186; cl.cshifts[CSHIFT_BONUS].destcolor[2] = 69; cl.cshifts[CSHIFT_BONUS].percent = 50; + cl.cshifts[CSHIFT_BONUS].alphafade = 100; } -} - -/* -============= -V_SetContentsColor - -Underwater, lava, etc each has a color shift -============= -*/ -void V_SetContentsColor (int contents) -{ - cshift_t* c; - c = &cl.cshifts[CSHIFT_CONTENTS]; // just to shorten the code below - if (!gl_polyblend.value) - { - c->percent = 0; - return; - } - switch (contents) - { - case CONTENTS_EMPTY: - case CONTENTS_SOLID: - //cl.cshifts[CSHIFT_CONTENTS] = cshift_empty; - c->destcolor[0] = cshift_empty.destcolor[0]; - c->destcolor[1] = cshift_empty.destcolor[1]; - c->destcolor[2] = cshift_empty.destcolor[2]; - c->percent = cshift_empty.percent; - break; - case CONTENTS_LAVA: - //cl.cshifts[CSHIFT_CONTENTS] = cshift_lava; - c->destcolor[0] = cshift_lava.destcolor[0]; - c->destcolor[1] = cshift_lava.destcolor[1]; - c->destcolor[2] = cshift_lava.destcolor[2]; - c->percent = cshift_lava.percent; - break; - case CONTENTS_SLIME: - //cl.cshifts[CSHIFT_CONTENTS] = cshift_slime; - c->destcolor[0] = cshift_slime.destcolor[0]; - c->destcolor[1] = cshift_slime.destcolor[1]; - c->destcolor[2] = cshift_slime.destcolor[2]; - c->percent = cshift_slime.percent; - break; - default: - //cl.cshifts[CSHIFT_CONTENTS] = cshift_water; - c->destcolor[0] = cshift_water.destcolor[0]; - c->destcolor[1] = cshift_water.destcolor[1]; - c->destcolor[2] = cshift_water.destcolor[2]; - c->percent = cshift_water.percent; - } -} - -/* -============= -V_CalcPowerupCshift -============= -*/ -void V_CalcPowerupCshift (void) -{ - if (!gl_polyblend.value) - { - cl.cshifts[CSHIFT_POWERUP].percent = 0; - return; - } - if (cl.items & IT_QUAD) - { - cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; - cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 0; - cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255; - cl.cshifts[CSHIFT_POWERUP].percent = 30; - } - else if (cl.items & IT_SUIT) - { - cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; - cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; - cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; - cl.cshifts[CSHIFT_POWERUP].percent = 20; - } - else if (cl.items & IT_INVISIBILITY) + else if(Cmd_Argc() >= 4 && Cmd_Argc() <= 6) { - cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 100; - cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 100; - cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 100; - cl.cshifts[CSHIFT_POWERUP].percent = 100; - } - else if (cl.items & IT_INVULNERABILITY) - { - cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255; - cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; - cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; - cl.cshifts[CSHIFT_POWERUP].percent = 30; + cl.cshifts[CSHIFT_BONUS].destcolor[0] = atof(Cmd_Argv(1)) * 255; + cl.cshifts[CSHIFT_BONUS].destcolor[1] = atof(Cmd_Argv(2)) * 255; + cl.cshifts[CSHIFT_BONUS].destcolor[2] = atof(Cmd_Argv(3)) * 255; + if(Cmd_Argc() >= 5) + cl.cshifts[CSHIFT_BONUS].percent = atof(Cmd_Argv(4)) * 255; // yes, these are HEXADECIMAL percent ;) + else + cl.cshifts[CSHIFT_BONUS].percent = 50; + if(Cmd_Argc() >= 6) + cl.cshifts[CSHIFT_BONUS].alphafade = atof(Cmd_Argv(5)) * 255; + else + cl.cshifts[CSHIFT_BONUS].alphafade = 100; } else - cl.cshifts[CSHIFT_POWERUP].percent = 0; + Con_Printf("usage:\nbf, or bf R G B [A [alphafade]]\n"); } /* -============= -V_CalcBlend -============= -*/ -// LordHavoc: fixed V_CalcBlend -void V_CalcBlend (void) -{ - float r, g, b, a, a2; - int j; +============================================================================== - r = 0; - g = 0; - b = 0; - a = 0; + VIEW RENDERING -// if (gl_cshiftpercent.value) -// { - for (j=0 ; j 1) - a2 = 1; - r += (cl.cshifts[j].destcolor[0]-r) * a2; - g += (cl.cshifts[j].destcolor[1]-g) * a2; - b += (cl.cshifts[j].destcolor[2]-b) * a2; - a = 1 - (1 - a) * (1 - a2); // correct alpha multiply... took a while to find it on the web - } - // saturate color (to avoid blending in black) - if (a) - { - a2 = 1 / a; - r *= a2; - g *= a2; - b *= a2; - } -// } +============================================================================== +*/ - v_blend[0] = bound(0, r * (1.0/255.0), 1); - v_blend[1] = bound(0, g * (1.0/255.0), 1); - v_blend[2] = bound(0, b * (1.0/255.0), 1); - v_blend[3] = bound(0, a , 1); -} +extern matrix4x4_t viewmodelmatrix; + +#include "cl_collision.h" +#include "csprogs.h" /* -============= -V_UpdateBlends -============= +================== +V_CalcRefdef + +================== */ -void V_UpdateBlends (void) +#if 0 +static vec3_t eyeboxmins = {-16, -16, -24}; +static vec3_t eyeboxmaxs = { 16, 16, 32}; +#endif +void V_CalcRefdef (void) { - int i, j; - qboolean new; - - V_CalcPowerupCshift (); - - new = false; - - for (i=0 ; irender.matrix, vieworg); + VectorCopy(cl.viewangles, viewangles); + + // calculate how much time has passed since the last V_CalcRefdef + smoothtime = bound(0, cl.time - cl.stairsmoothtime, 0.1); + cl.stairsmoothtime = cl.time; + + // fade damage flash + if (v_dmg_time > 0) + v_dmg_time -= bound(0, smoothtime, 0.1); + + if (cl.intermission) { - new = true; - cl.prev_cshifts[i].percent = cl.cshifts[i].percent; + // entity is a fixed camera, just copy the matrix + if (cls.protocol == PROTOCOL_QUAKEWORLD) + Matrix4x4_CreateFromQuakeEntity(&r_refdef.view.matrix, cl.qw_intermission_origin[0], cl.qw_intermission_origin[1], cl.qw_intermission_origin[2], cl.qw_intermission_angles[0], cl.qw_intermission_angles[1], cl.qw_intermission_angles[2], 1); + else + { + r_refdef.view.matrix = ent->render.matrix; + Matrix4x4_AdjustOrigin(&r_refdef.view.matrix, 0, 0, cl.stats[STAT_VIEWHEIGHT]); + } + viewmodelmatrix = r_refdef.view.matrix; } - for (j=0 ; j<3 ; j++) - if (cl.cshifts[i].destcolor[j] != cl.prev_cshifts[i].destcolor[j]) + else + { + // smooth stair stepping, but only if onground and enabled + if (!cl.onground || cl_stairsmoothspeed.value <= 0) + cl.stairsmoothz = vieworg[2]; + else { - new = true; - cl.prev_cshifts[i].destcolor[j] = cl.cshifts[i].destcolor[j]; + if (cl.stairsmoothz < vieworg[2]) + vieworg[2] = cl.stairsmoothz = bound(vieworg[2] - 16, cl.stairsmoothz + smoothtime * cl_stairsmoothspeed.value, vieworg[2]); + else if (cl.stairsmoothz > vieworg[2]) + vieworg[2] = cl.stairsmoothz = bound(vieworg[2], cl.stairsmoothz - smoothtime * cl_stairsmoothspeed.value, vieworg[2] + 16); } - } - -// drop the damage value - cl.cshifts[CSHIFT_DAMAGE].percent -= (cl.time - cl.oldtime)*150; - if (cl.cshifts[CSHIFT_DAMAGE].percent <= 0) - cl.cshifts[CSHIFT_DAMAGE].percent = 0; - -// drop the bonus value - cl.cshifts[CSHIFT_BONUS].percent -= (cl.time - cl.oldtime)*100; - if (cl.cshifts[CSHIFT_BONUS].percent <= 0) - cl.cshifts[CSHIFT_BONUS].percent = 0; - - if (!new) - return; - - V_CalcBlend (); -} - -/* -============================================================================== - - VIEW RENDERING - -============================================================================== -*/ - -float angledelta (float a) -{ - a = ANGLEMOD(a); - if (a > 180) - a -= 360; - return a; -} - -/* -================== -CalcGunAngle -================== -*/ -void CalcGunAngle (void) -{ - cl.viewent.render.angles[YAW] = r_refdef.viewangles[YAW]; - cl.viewent.render.angles[PITCH] = -r_refdef.viewangles[PITCH]; - - cl.viewent.render.angles[ROLL] -= v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value; - cl.viewent.render.angles[PITCH] -= v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; - cl.viewent.render.angles[YAW] -= v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; -} - -/* -============== -V_BoundOffsets -============== -*/ -void V_BoundOffsets (void) -{ - entity_t *ent; - - ent = &cl_entities[cl.viewentity]; - -// absolutely bound refresh relative to entity clipping hull -// so the view can never be inside a solid wall - - if (r_refdef.vieworg[0] < ent->render.origin[0] - 14) - r_refdef.vieworg[0] = ent->render.origin[0] - 14; - else if (r_refdef.vieworg[0] > ent->render.origin[0] + 14) - r_refdef.vieworg[0] = ent->render.origin[0] + 14; - if (r_refdef.vieworg[1] < ent->render.origin[1] - 14) - r_refdef.vieworg[1] = ent->render.origin[1] - 14; - else if (r_refdef.vieworg[1] > ent->render.origin[1] + 14) - r_refdef.vieworg[1] = ent->render.origin[1] + 14; - if (r_refdef.vieworg[2] < ent->render.origin[2] - 22) - r_refdef.vieworg[2] = ent->render.origin[2] - 22; - else if (r_refdef.vieworg[2] > ent->render.origin[2] + 30) - r_refdef.vieworg[2] = ent->render.origin[2] + 30; -} - -/* -============== -V_AddIdle -Idle swaying -============== -*/ -void V_AddIdle (void) -{ - r_refdef.viewangles[ROLL] += v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value; - r_refdef.viewangles[PITCH] += v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; - r_refdef.viewangles[YAW] += v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; -} + // apply qw weapon recoil effect (this did not work in QW) + // TODO: add a cvar to disable this + viewangles[PITCH] += cl.qw_weaponkick; + // apply the viewofs (even if chasecam is used) + vieworg[2] += cl.stats[STAT_VIEWHEIGHT]; -/* -============== -V_CalcViewRoll + if (chase_active.value) + { + // observing entity from third person. Added "campitch" by Alexander "motorsep" Zubov + vec_t camback, camup, dist, campitch, forward[3], chase_dest[3]; -Roll is induced by movement and damage -============== -*/ -void V_CalcViewRoll (void) -{ - float side; - - side = V_CalcRoll (cl_entities[cl.viewentity].render.angles, cl.velocity); - r_refdef.viewangles[ROLL] += side; + camback = chase_back.value; + camup = chase_up.value; + campitch = chase_pitchangle.value; - if (v_dmg_time > 0) - { - r_refdef.viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll; - r_refdef.viewangles[PITCH] += v_dmg_time/v_kicktime.value*v_dmg_pitch; - v_dmg_time -= cl.frametime; - } + AngleVectors(viewangles, forward, NULL, NULL); - if (cl.stats[STAT_HEALTH] <= 0) - { - r_refdef.viewangles[ROLL] = 80; // dead view angle - return; + if (chase_overhead.integer) + { +#if 1 + vec3_t offset; + vec3_t bestvieworg; +#endif + vec3_t up; + viewangles[PITCH] = 0; + AngleVectors(viewangles, forward, NULL, up); + // trace a little further so it hits a surface more consistently (to avoid 'snapping' on the edge of the range) + chase_dest[0] = vieworg[0] - forward[0] * camback + up[0] * camup; + chase_dest[1] = vieworg[1] - forward[1] * camback + up[1] * camup; + chase_dest[2] = vieworg[2] - forward[2] * camback + up[2] * camup; +#if 0 +#if 1 + //trace = CL_TraceLine(vieworg, eyeboxmins, eyeboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); + trace = CL_TraceLine(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#else + //trace = CL_TraceBox(vieworg, eyeboxmins, eyeboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); + trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#endif + VectorCopy(trace.endpos, vieworg); + vieworg[2] -= 8; +#else + // trace from first person view location to our chosen third person view location +#if 1 + trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#else + trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#endif + VectorCopy(trace.endpos, bestvieworg); + offset[2] = 0; + for (offset[0] = -16;offset[0] <= 16;offset[0] += 8) + { + for (offset[1] = -16;offset[1] <= 16;offset[1] += 8) + { + AngleVectors(viewangles, NULL, NULL, up); + chase_dest[0] = vieworg[0] - forward[0] * camback + up[0] * camup + offset[0]; + chase_dest[1] = vieworg[1] - forward[1] * camback + up[1] * camup + offset[1]; + chase_dest[2] = vieworg[2] - forward[2] * camback + up[2] * camup + offset[2]; +#if 1 + trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#else + trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#endif + if (bestvieworg[2] > trace.endpos[2]) + bestvieworg[2] = trace.endpos[2]; + } + } + bestvieworg[2] -= 8; + VectorCopy(bestvieworg, vieworg); +#endif + viewangles[PITCH] = campitch; + } + else + { + if (gamemode == GAME_GOODVSBAD2 && chase_stevie.integer) + { + // look straight down from high above + viewangles[PITCH] = 90; + camback = 2048; + VectorSet(forward, 0, 0, -1); + } + + // trace a little further so it hits a surface more consistently (to avoid 'snapping' on the edge of the range) + dist = -camback - 8; + chase_dest[0] = vieworg[0] + forward[0] * dist; + chase_dest[1] = vieworg[1] + forward[1] * dist; + chase_dest[2] = vieworg[2] + forward[2] * dist + camup; + trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); + VectorMAMAM(1, trace.endpos, 8, forward, 4, trace.plane.normal, vieworg); + } + } + else + { + // first person view from entity + // angles + if (cl.stats[STAT_HEALTH] <= 0 && v_deathtilt.integer) + viewangles[ROLL] = v_deathtiltangle.value; + VectorAdd(viewangles, cl.punchangle, viewangles); + viewangles[ROLL] += V_CalcRoll(cl.viewangles, cl.movement_velocity); + if (v_dmg_time > 0) + { + viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll; + viewangles[PITCH] += v_dmg_time/v_kicktime.value*v_dmg_pitch; + } + // origin + VectorAdd(vieworg, cl.punchvector, vieworg); + if (cl.stats[STAT_HEALTH] > 0) + { + double xyspeed, bob; + + xyspeed = sqrt(cl.movement_velocity[0]*cl.movement_velocity[0] + cl.movement_velocity[1]*cl.movement_velocity[1]); + if (cl_bob.value && cl_bobcycle.value) + { + float cycle; + // LordHavoc: this code is *weird*, but not replacable (I think it + // should be done in QC on the server, but oh well, quake is quake) + // LordHavoc: figured out bobup: the time at which the sin is at 180 + // degrees (which allows lengthening or squishing the peak or valley) + cycle = cl.time / cl_bobcycle.value; + cycle -= (int) cycle; + if (cycle < cl_bobup.value) + cycle = sin(M_PI * cycle / cl_bobup.value); + else + cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value)); + // bob is proportional to velocity in the xy plane + // (don't count Z, or jumping messes it up) + bob = xyspeed * cl_bob.value; + bob = bob*0.3 + bob*0.7*cycle; + vieworg[2] += bound(-7, bob, 4); + } + + VectorCopy(vieworg, gunorg); + + if (cl_bob.value && cl_bobmodel.value) + { + // calculate for swinging gun model + // the gun bobs when running on the ground, but doesn't bob when you're in the air. + // Sajt: I tried to smooth out the transitions between bob and no bob, which works + // for the most part, but for some reason when you go through a message trigger or + // pick up an item or anything like that it will momentarily jolt the gun. + vec3_t forward, right, up; + float bspeed; + float s; + float t; + + s = cl.time * cl_bobmodel_speed.value; + if (cl.onground) + { + if (cl.time - cl.hitgroundtime < 0.2) + { + // just hit the ground, speed the bob back up over the next 0.2 seconds + t = cl.time - cl.hitgroundtime; + t = bound(0, t, 0.2); + t *= 5; + } + else + t = 1; + } + else + { + // recently left the ground, slow the bob down over the next 0.2 seconds + t = cl.time - cl.lastongroundtime; + t = 0.2 - bound(0, t, 0.2); + t *= 5; + } + + bspeed = bound (0, xyspeed, 400) * 0.01f; + AngleVectors (viewangles, forward, right, up); + bob = bspeed * cl_bobmodel_side.value * cl_viewmodel_scale.value * sin (s) * t; + VectorMA (gunorg, bob, right, gunorg); + bob = bspeed * cl_bobmodel_up.value * cl_viewmodel_scale.value * cos (s * 2) * t; + VectorMA (gunorg, bob, up, gunorg); + } + } + } + // calculate a view matrix for rendering the scene + if (v_idlescale.value) + Matrix4x4_CreateFromQuakeEntity(&r_refdef.view.matrix, vieworg[0], vieworg[1], vieworg[2], viewangles[0] + v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value, viewangles[1] + v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value, viewangles[2] + v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value, 1); + else + Matrix4x4_CreateFromQuakeEntity(&r_refdef.view.matrix, vieworg[0], vieworg[1], vieworg[2], viewangles[0], viewangles[1], viewangles[2] + v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value, 1); + // calculate a viewmodel matrix for use in view-attached entities + Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, gunorg[0], gunorg[1], gunorg[2], viewangles[0], viewangles[1], viewangles[2], cl_viewmodel_scale.value); + VectorCopy(vieworg, cl.csqc_origin); + VectorCopy(viewangles, cl.csqc_angles); + } } - } - -/* -================== -V_CalcIntermissionRefdef - -================== -*/ -void V_CalcIntermissionRefdef (void) +void V_FadeViewFlashs(void) { - entity_t *ent, *view; - float old; - -// ent is the player model (visible when out of body) - ent = &cl_entities[cl.viewentity]; -// view is the weapon model (only visible from inside body) - view = &cl.viewent; - - VectorCopy (ent->render.origin, r_refdef.vieworg); - VectorCopy (ent->render.angles, r_refdef.viewangles); - view->render.model = NULL; - -// always idle in intermission - old = v_idlescale.value; - v_idlescale.value = 1; - V_AddIdle (); - v_idlescale.value = old; + // don't flash if time steps backwards + if (cl.time <= cl.oldtime) + return; + // drop the damage value + cl.cshifts[CSHIFT_DAMAGE].percent -= (cl.time - cl.oldtime)*cl.cshifts[CSHIFT_DAMAGE].alphafade; + if (cl.cshifts[CSHIFT_DAMAGE].percent <= 0) + cl.cshifts[CSHIFT_DAMAGE].percent = 0; + // drop the bonus value + cl.cshifts[CSHIFT_BONUS].percent -= (cl.time - cl.oldtime)*cl.cshifts[CSHIFT_BONUS].alphafade; + if (cl.cshifts[CSHIFT_BONUS].percent <= 0) + cl.cshifts[CSHIFT_BONUS].percent = 0; } -/* -================== -V_CalcRefdef - -================== -*/ -void V_CalcRefdef (void) +void V_CalcViewBlend(void) { - entity_t *ent, *view; - int i; - vec3_t forward; - vec3_t angles; - float bob; -// static float oldz = 0; - - V_DriftPitch (); - -// ent is the player model (visible when out of body) - ent = &cl_entities[cl.viewentity]; -// view is the weapon model (only visible from inside body) - view = &cl.viewent; - - - if (chase_active.value) - { - VectorCopy (ent->render.origin, r_refdef.vieworg); - VectorCopy (cl.viewangles, r_refdef.viewangles); - Chase_Update (); - V_AddIdle (); - } - else + float a2; + int j; + r_refdef.viewblend[0] = 0; + r_refdef.viewblend[1] = 0; + r_refdef.viewblend[2] = 0; + r_refdef.viewblend[3] = 0; + r_refdef.frustumscale_x = 1; + r_refdef.frustumscale_y = 1; + if (cls.state == ca_connected && cls.signon == SIGNONS) { - // transform the view offset by the model's matrix to get the offset from model origin for the view - // if (!chase_active.value) // LordHavoc: get rid of angle problems in chase_active mode - // { - // ent->render.angles[YAW] = cl.viewangles[YAW]; // the model should face the view dir - // ent->render.angles[PITCH] = -cl.viewangles[PITCH]; // the model should face the view dir - // } - - bob = V_CalcBob (); - - // refresh position - VectorCopy (ent->render.origin, r_refdef.vieworg); - r_refdef.vieworg[2] += cl.viewheight + bob; - - // LordHavoc: the protocol has changed... so this is an obsolete approach - // never let it sit exactly on a node line, because a water plane can - // dissapear when viewed with the eye exactly on it. - // the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis - // r_refdef.vieworg[0] += 1.0/32; - // r_refdef.vieworg[1] += 1.0/32; - // r_refdef.vieworg[2] += 1.0/32; - - if (!intimerefresh) - VectorCopy (cl.viewangles, r_refdef.viewangles); - V_CalcViewRoll (); - V_AddIdle (); - - // offsets - angles[PITCH] = -ent->render.angles[PITCH]; // because entity pitches are actually backward - angles[YAW] = ent->render.angles[YAW]; - angles[ROLL] = ent->render.angles[ROLL]; - - AngleVectors (angles, forward, NULL, NULL); - - V_BoundOffsets (); - - // set up gun position - VectorCopy (ent->render.origin, view->render.origin); - view->render.origin[2] += cl.viewheight; - VectorCopy (cl.viewangles, view->render.angles); - - CalcGunAngle (); - - for (i=0 ; i<3 ; i++) + // set contents color + int supercontents; + vec3_t vieworigin; + Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, vieworigin); + supercontents = CL_PointSuperContents(vieworigin); + if (supercontents & SUPERCONTENTS_LIQUIDSMASK) { - view->render.origin[i] += forward[i]*bob*0.4; - // view->render.origin[i] += right[i]*bob*0.4; - // view->render.origin[i] += up[i]*bob*0.8; + r_refdef.frustumscale_x *= 1 - (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value); + r_refdef.frustumscale_y *= 1 - (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value); + if (supercontents & SUPERCONTENTS_LAVA) + { + cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 255; + cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 80; + cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 0; + } + else if (supercontents & SUPERCONTENTS_SLIME) + { + cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 0; + cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 25; + cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 5; + } + else + { + cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 130; + cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 80; + cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 50; + } + cl.cshifts[CSHIFT_CONTENTS].percent = 150 * 0.5; + } + else + { + cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 0; + cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 0; + cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 0; + cl.cshifts[CSHIFT_CONTENTS].percent = 0; } - view->render.origin[2] += bob; - - // FIXME: this setup code is somewhat evil (CL_LerpUpdate should be private) - CL_LerpUpdate(view, cl.stats[STAT_WEAPONFRAME], cl.stats[STAT_WEAPON]); - view->render.model = cl.model_precache[cl.stats[STAT_WEAPON]]; - view->render.frame = cl.stats[STAT_WEAPONFRAME]; - view->render.colormap = -1; // no special coloring - view->render.alpha = ent->render.alpha; // LordHavoc: if the player is transparent, so is the gun - view->render.effects = ent->render.effects; - view->render.scale = 1; + if (gamemode != GAME_TRANSFUSION) + { + if (cl.stats[STAT_ITEMS] & IT_QUAD) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255; + cl.cshifts[CSHIFT_POWERUP].percent = 30; + } + else if (cl.stats[STAT_ITEMS] & IT_SUIT) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; + cl.cshifts[CSHIFT_POWERUP].percent = 20; + } + else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 100; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 100; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 100; + cl.cshifts[CSHIFT_POWERUP].percent = 100; + } + else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; + cl.cshifts[CSHIFT_POWERUP].percent = 30; + } + else + cl.cshifts[CSHIFT_POWERUP].percent = 0; + } - // set up the refresh position + cl.cshifts[CSHIFT_VCSHIFT].destcolor[0] = v_cshift.destcolor[0]; + cl.cshifts[CSHIFT_VCSHIFT].destcolor[1] = v_cshift.destcolor[1]; + cl.cshifts[CSHIFT_VCSHIFT].destcolor[2] = v_cshift.destcolor[2]; + cl.cshifts[CSHIFT_VCSHIFT].percent = v_cshift.percent; - // LordHavoc: this never looked all that good to begin with... - /* - // smooth out stair step ups - if (cl.onground && ent->render.origin[2] - oldz > 0) - { - float steptime; - - steptime = cl.time - cl.oldtime; - if (steptime < 0) - //FIXME I_Error ("steptime < 0"); - steptime = 0; - - oldz += steptime * 80; - if (oldz > ent->render.origin[2]) - oldz = ent->render.origin[2]; - if (ent->render.origin[2] - oldz > 12) - oldz = ent->render.origin[2] - 12; - r_refdef.vieworg[2] += oldz - ent->render.origin[2]; - view->render.origin[2] += oldz - ent->render.origin[2]; - } - else - oldz = ent->render.origin[2]; - */ + // LordHavoc: fixed V_CalcBlend + for (j = 0;j < NUM_CSHIFTS;j++) + { + a2 = bound(0.0f, cl.cshifts[j].percent * (1.0f / 255.0f), 1.0f); + if (a2 > 0) + { + VectorLerp(r_refdef.viewblend, a2, cl.cshifts[j].destcolor, r_refdef.viewblend); + r_refdef.viewblend[3] = (1 - (1 - r_refdef.viewblend[3]) * (1 - a2)); // correct alpha multiply... took a while to find it on the web + } + } + // saturate color (to avoid blending in black) + if (r_refdef.viewblend[3]) + { + a2 = 1 / r_refdef.viewblend[3]; + VectorScale(r_refdef.viewblend, a2, r_refdef.viewblend); + } + r_refdef.viewblend[0] = bound(0.0f, r_refdef.viewblend[0] * (1.0f/255.0f), 1.0f); + r_refdef.viewblend[1] = bound(0.0f, r_refdef.viewblend[1] * (1.0f/255.0f), 1.0f); + r_refdef.viewblend[2] = bound(0.0f, r_refdef.viewblend[2] * (1.0f/255.0f), 1.0f); + r_refdef.viewblend[3] = bound(0.0f, r_refdef.viewblend[3] * gl_polyblend.value, 1.0f); + + // Samual: Ugly hack, I know. But it's the best we can do since + // there is no way to detect client states from the engine. + if (cl.stats[STAT_HEALTH] <= 0 && cl.stats[STAT_HEALTH] != -666 && + cl.stats[STAT_HEALTH] != -2342 && cl_deathfade.value > 0) + { + cl.deathfade += cl_deathfade.value * max(0.00001, cl.time - cl.oldtime); + cl.deathfade = bound(0.0f, cl.deathfade, 0.9f); + } + else + cl.deathfade = 0.0f; - // LordHavoc: origin view kick added - if (!intimerefresh && v_punch.value) + if(cl.deathfade > 0) { - VectorAdd(r_refdef.viewangles, cl.punchangle, r_refdef.viewangles); - VectorAdd(r_refdef.vieworg, cl.punchvector, r_refdef.vieworg); + float a; + float deathfadevec[3] = {0.3f, 0.0f, 0.0f}; + a = r_refdef.viewblend[3] + cl.deathfade - r_refdef.viewblend[3]*cl.deathfade; + if(a > 0) + VectorMAM(r_refdef.viewblend[3] * (1 - cl.deathfade) / a, r_refdef.viewblend, cl.deathfade / a, deathfadevec, r_refdef.viewblend); + r_refdef.viewblend[3] = a; } } } -/* -================== -V_RenderView - -The player's clipping box goes from (-16 -16 -24) to (16 16 32) from -the entity origin, so any view position inside that will be valid -================== -*/ -void V_RenderView (void) -{ - if (scr_con_current >= vid.conheight) - return; - - if (cl.intermission) - V_CalcIntermissionRefdef (); - else - V_CalcRefdef (); - - R_RenderView (); -} - //============================================================================ /* @@ -828,9 +753,9 @@ V_Init */ void V_Init (void) { - Cmd_AddCommand ("v_cshift", V_cshift_f); - Cmd_AddCommand ("bf", V_BonusFlash_f); - Cmd_AddCommand ("centerview", V_StartPitchDrift); + Cmd_AddCommand ("v_cshift", V_cshift_f, "sets tint color of view"); + Cmd_AddCommand ("bf", V_BonusFlash_f, "briefly flashes a bright color tint on view (used when items are picked up); optionally takes R G B [A [alphafade]] arguments to specify how the flash looks"); + Cmd_AddCommand ("centerview", V_StartPitchDrift, "gradually recenter view (stop looking up/down)"); Cvar_RegisterVariable (&v_centermove); Cvar_RegisterVariable (&v_centerspeed); @@ -844,20 +769,34 @@ void V_Init (void) Cvar_RegisterVariable (&v_idlescale); Cvar_RegisterVariable (&crosshair); -// Cvar_RegisterVariable (&gl_cshiftpercent); - Cvar_RegisterVariable (&gl_polyblend); Cvar_RegisterVariable (&cl_rollspeed); Cvar_RegisterVariable (&cl_rollangle); Cvar_RegisterVariable (&cl_bob); Cvar_RegisterVariable (&cl_bobcycle); Cvar_RegisterVariable (&cl_bobup); + Cvar_RegisterVariable (&cl_bobmodel); + Cvar_RegisterVariable (&cl_bobmodel_side); + Cvar_RegisterVariable (&cl_bobmodel_up); + Cvar_RegisterVariable (&cl_bobmodel_speed); + + Cvar_RegisterVariable (&cl_viewmodel_scale); Cvar_RegisterVariable (&v_kicktime); Cvar_RegisterVariable (&v_kickroll); - Cvar_RegisterVariable (&v_kickpitch); + Cvar_RegisterVariable (&v_kickpitch); - Cvar_RegisterVariable (&v_punch); -} + Cvar_RegisterVariable (&cl_stairsmoothspeed); + + Cvar_RegisterVariable (&chase_back); + Cvar_RegisterVariable (&chase_up); + Cvar_RegisterVariable (&chase_active); + Cvar_RegisterVariable (&chase_overhead); + Cvar_RegisterVariable (&chase_pitchangle); + if (gamemode == GAME_GOODVSBAD2) + Cvar_RegisterVariable (&chase_stevie); + Cvar_RegisterVariable (&v_deathtilt); + Cvar_RegisterVariable (&v_deathtiltangle); +}