Sigrid Solveig HaflínudóttirV_RenderView: crosshair is transparent, fix it1718d381 year agoHistory
728 lines · 18.3 KB · C
RawDownload
#include "quakedef.h"#include "colormatrix.h"#include "crosshairs.h" /* * The view is allowed to move slightly from it's true position for bobbing, * but if it exceeds 8 pixels linear distance (spherical, not box), the list of * entities sent from the server may not include everything in the pvs, especially * when crossing a water boudnary. */ /* Used by view and sv_user */vec3_t forward, right, up; /* * 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 */extern vrect_t scr_vrect; cvar_t v_scale = {"v_scale", "1", true}; static cvar_t v_cshiftpercent = {"v_cshiftpercent", "30", true}; static cvar_t scr_ofsx = {"scr_ofsx", "0"};static cvar_t scr_ofsy = {"scr_ofsy", "0"};static cvar_t scr_ofsz = {"scr_ofsz", "0"};static cvar_t cl_rollspeed = {"cl_rollspeed", "200"};static cvar_t cl_rollangle = {"cl_rollangle", "2.0"};static cvar_t cl_bob = {"cl_bob", "0.02"};static cvar_t cl_bobcycle = {"cl_bobcycle", "0.6"};static cvar_t cl_bobup = {"cl_bobup", "0.5"};static cvar_t v_kicktime = {"v_kicktime", "0.5"};static cvar_t v_kickroll = {"v_kickroll", "0.6"};static cvar_t v_kickpitch = {"v_kickpitch", "0.6"};static cvar_t v_iyaw_cycle = {"v_iyaw_cycle", "2"};static cvar_t v_iroll_cycle = {"v_iroll_cycle", "0.5"};static cvar_t v_ipitch_cycle = {"v_ipitch_cycle", "1"};static cvar_t v_iyaw_level = {"v_iyaw_level", "0.3"};static cvar_t v_iroll_level = {"v_iroll_level", "0.1"};static cvar_t v_ipitch_level = {"v_ipitch_level", "0.3"};static cvar_t v_idlescale = {"v_idlescale", "0"};static cvar_t crosshair = {"crosshair", "1", true};static cvar_t crosshair_shape = {"crosshair_shape", "0", true};static cvar_t cl_crossx = {"cl_crossx", "0"};static cvar_t cl_crossy = {"cl_crossy", "0"};static cvar_t v_centermove = {"v_centermove", "0.15"};static cvar_t v_centerspeed = {"v_centerspeed", "500"}; static double v_dmg_time, v_dmg_roll, v_dmg_pitch;static double v_step_time, v_step_z, v_step_oldz; static cshift_t cshift_empty = {{130, 80, 50}, 0};static cshift_t cshift_water = {{130, 80, 50}, 128};static cshift_t cshift_slime = {{0, 25, 5}, 150};static cshift_t cshift_lava = {{255, 80, 0}, 150}; floatV_CalcRoll(vec3_t angles, vec3_t velocity){	float sign, side, value; 	AngleVectors(angles, forward, right, up);	side = DotProduct(velocity, right);	sign = side < 0 ? -1 : 1;	side = fabs(side); 	value = cl_rollangle.value; 	if(side < cl_rollspeed.value)		side = side * value / cl_rollspeed.value;	else		side = value; 	return side * sign;} static floatV_CalcBob(void){	float bob, 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 = sqrtf(cl.velocity[0] * cl.velocity[0] + cl.velocity[1] * cl.velocity[1]) * cl_bob.value;	bob = bob * 0.3 + bob * 0.7 * sinf(cycle);	if(bob > 4)		bob = 4;	else if(bob < -7)		bob = -7;	return bob;} voidV_StartPitchDrift(cmd_t *c){	USED(c);	if(cl.laststop == cl.time)		return; // something else is keeping it from drifting	if(cl.nodrift || !cl.pitchvel) {		cl.pitchvel = v_centerspeed.value;		cl.nodrift = false;		cl.driftmove = 0;	}} voidV_StopPitchDrift(void){	cl.laststop = cl.time;	cl.nodrift = true;	cl.pitchvel = 0;} /* * Moves the client pitch angle towards cl.idealpitch sent by the server. * * If the user is adjusting pitch manually, either with lookup/lookdown, * mlook and mouse, or klook and keyboard, pitch drifting is constantly stopped. * * Drifting is enabled when the center view key is hit, mlook is released and * lookspring is non 0, or when */static voidV_DriftPitch(void){	float delta, move; 	if(noclip_anglehack || !cl.onground || cls.demoplayback) {		cl.driftmove = 0;		cl.pitchvel = 0;		return;	} 	// don't count small mouse motion	if(cl.nodrift) {		if(fabs(cl.cmd.forwardmove) < cl_forwardspeed.value)			cl.driftmove = 0;		else			cl.driftmove += scr_frametime; 		if(cl.driftmove > v_centermove.value)			V_StartPitchDrift(nil);		return;	} 	delta = cl.idealpitch - cl.viewangles[PITCH]; 	if(!delta) {		cl.pitchvel = 0;		return;	} 	move = scr_frametime * cl.pitchvel;	cl.pitchvel += scr_frametime * v_centerspeed.value; 	// Con_Printf("move: %f (%f)\n", move, scr_frametime); 	if(delta > 0) {		if(move > delta) {			cl.pitchvel = 0;			move = delta;		}		cl.viewangles[PITCH] += move;	} else if(delta < 0) {		if(move > -delta) {			cl.pitchvel = 0;			move = -delta;		}		cl.viewangles[PITCH] -= move;	}} voidV_ParseDamage(void){	int armor, blood;	vec3_t from, forward, right, up;	entity_t *ent;	float side, count; 	armor = MSG_ReadByte();	blood = MSG_ReadByte();	MSG_ReadVec(cl.protocol, from); 	count = blood * 0.5 + armor * 0.5;	if(count < 10)		count = 10; 	cl.faceanimtime = cl.time + 0.2; // but sbar face into pain frame 	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; 	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->origin, from);	VectorNormalize(from); 	AngleVectors(ent->angles, forward, right, up); 	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;} static voidV_cshift_f(cmd_t *c){	USED(c);	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));} /* When you run over an item, the server sends this command */static voidV_BonusFlash_f(cmd_t *c){	USED(c);	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;} /* Underwater, lava, etc each has a color shift */voidV_SetContentsColor(int contents){	switch(contents) {	case CONTENTS_EMPTY:	case CONTENTS_SOLID:		cl.cshifts[CSHIFT_CONTENTS] = cshift_empty;		break;	case CONTENTS_LAVA:		cl.cshifts[CSHIFT_CONTENTS] = cshift_lava;		break;	case CONTENTS_SLIME:		cl.cshifts[CSHIFT_CONTENTS] = cshift_slime;		break;	default:		cl.cshifts[CSHIFT_CONTENTS] = cshift_water;	}} static voidV_CalcPowerupCshift(void){	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) {		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;	} else		cl.cshifts[CSHIFT_POWERUP].percent = 0;} static voidV_Blend(void){	float c[4], a;	int i; 	c[0] = c[1] = c[2] = c[3] = 0;	for(i = 0; i < NUM_CSHIFTS; i++) {		a = ((cl.cshifts[i].percent * v_cshiftpercent.value) / 100.0) / 255.0;		if(a > 0) {			c[3] += a * (1 - c[3]);			a = a / c[3];			c[0] = c[0] * (1 - a) + cl.cshifts[i].destcolor[0] * a;			c[1] = c[1] * (1 - a) + cl.cshifts[i].destcolor[1] * a;			c[2] = c[2] * (1 - a) + cl.cshifts[i].destcolor[2] * a;		}	}	c[3] = clamp(c[3], 0, 1.0);	c[2] *= c[3] / 255.0;	c[1] *= c[3] / 255.0;	c[0] *= c[3] / 255.0;	cmsetvblend(c);} voidV_ApplyShifts(void){	int i, j;	bool update; 	V_CalcPowerupCshift(); 	update = false;	for(i = 0; i < NUM_CSHIFTS; i++) {		if(cl.cshifts[i].percent != cl.prev_cshifts[i].percent) {			cl.prev_cshifts[i].percent = cl.cshifts[i].percent;			update = true;		}		for(j = 0; j < 3; j++) {			if(cl.cshifts[i].destcolor[j] != cl.prev_cshifts[i].destcolor[j]) {				cl.prev_cshifts[i].destcolor[j] = cl.cshifts[i].destcolor[j];				update = true;			}		}	} 	// drop the damage value	if(cl.cshifts[CSHIFT_DAMAGE].percent > 0) {		cl.cshifts[CSHIFT_DAMAGE].percent -= scr_frametime * 150;		if(cl.cshifts[CSHIFT_DAMAGE].percent < 0)			cl.cshifts[CSHIFT_DAMAGE].percent = 0;	} 	// drop the bonus value	if(cl.cshifts[CSHIFT_BONUS].percent > 0) {		cl.cshifts[CSHIFT_BONUS].percent -= scr_frametime * 100;		if(cl.cshifts[CSHIFT_BONUS].percent < 0)			cl.cshifts[CSHIFT_BONUS].percent = 0;	} 	if(update)		V_Blend();} static floatangledelta(float a){	a = anglemod(a);	if(a > 180)		a -= 360;	return a;} static voidCalcGunAngle(void){	static float oldyaw = 0;	static float oldpitch = 0;	float yaw, pitch, move; 	yaw = r_refdef.view.angles[YAW];	pitch = -r_refdef.view.angles[PITCH]; 	yaw = angledelta(yaw - r_refdef.view.angles[YAW]) * 0.4;	if(yaw > 10)		yaw = 10;	else if(yaw < -10)		yaw = -10;	pitch = angledelta(-pitch - r_refdef.view.angles[PITCH]) * 0.4;	if(pitch > 10)		pitch = 10;	else if(pitch < -10)		pitch = -10;	move = scr_frametime * 20;	if(yaw > oldyaw) {		if(oldyaw + move < yaw)			yaw = oldyaw + move;	} else {		if(oldyaw - move > yaw)			yaw = oldyaw - move;	} 	if(pitch > oldpitch) {		if(oldpitch + move < pitch)			pitch = oldpitch + move;	} else {		if(oldpitch - move > pitch)			pitch = oldpitch - move;	} 	oldyaw = yaw;	oldpitch = pitch; 	cl.viewent.angles[YAW] = r_refdef.view.angles[YAW] + yaw;	cl.viewent.angles[PITCH] = -(r_refdef.view.angles[PITCH] + pitch); 	cl.viewent.angles[ROLL] -=		v_idlescale.value * sinf(cl.time * v_iroll_cycle.value) * v_iroll_level.value;	cl.viewent.angles[PITCH] -=		v_idlescale.value * sinf(cl.time * v_ipitch_cycle.value) * v_ipitch_level.value;	cl.viewent.angles[YAW] -=		v_idlescale.value * sinf(cl.time * v_iyaw_cycle.value) * v_iyaw_level.value;} static voidV_BoundOffsets(void){	entity_t *ent; 	ent = &cl_entities[cl.viewentity]; 	// absolutely bound refresh reletive to entity clipping hull	// so the view can never be inside a solid wall 	if(r_refdef.view.org[0] < ent->origin[0] - 14)		r_refdef.view.org[0] = ent->origin[0] - 14;	else if(r_refdef.view.org[0] > ent->origin[0] + 14)		r_refdef.view.org[0] = ent->origin[0] + 14;	if(r_refdef.view.org[1] < ent->origin[1] - 14)		r_refdef.view.org[1] = ent->origin[1] - 14;	else if(r_refdef.view.org[1] > ent->origin[1] + 14)		r_refdef.view.org[1] = ent->origin[1] + 14;	if(r_refdef.view.org[2] < ent->origin[2] - 22)		r_refdef.view.org[2] = ent->origin[2] - 22;	else if(r_refdef.view.org[2] > ent->origin[2] + 30)		r_refdef.view.org[2] = ent->origin[2] + 30;} /* Idle swaying */static voidV_AddIdle(void){	r_refdef.view.angles[ROLL] +=		v_idlescale.value * sinf(cl.time * v_iroll_cycle.value) * v_iroll_level.value;	r_refdef.view.angles[PITCH] +=		v_idlescale.value * sinf(cl.time * v_ipitch_cycle.value) * v_ipitch_level.value;	r_refdef.view.angles[YAW] +=		v_idlescale.value * sinf(cl.time * v_iyaw_cycle.value) * v_iyaw_level.value;} /* Roll is induced by movement and damage */static voidV_CalcViewRoll(void){	float side; 	side = V_CalcRoll(cl_entities[cl.viewentity].angles, cl.velocity);	r_refdef.view.angles[ROLL] += side; 	if(v_dmg_time > 0) {		r_refdef.view.angles[ROLL] += v_dmg_time / v_kicktime.value * v_dmg_roll;		r_refdef.view.angles[PITCH] += v_dmg_time / v_kicktime.value * v_dmg_pitch;		v_dmg_time -= scr_frametime;	} 	if(cl.stats[STAT_HEALTH] <= 0) {		r_refdef.view.angles[ROLL] = 80; // dead view angle		return;	}} static voidV_CalcIntermissionRefdef(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->origin, r_refdef.view.org);	VectorCopy(ent->angles, r_refdef.view.angles);	view->model = nil; 

Lines 1–500 of 728.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t