406 lines · 9.1 KB · C
RawDownload
#include "quakedef.h" /* * KEY BUTTONS * * Continuous button event tracking is complicated by the fact that two different * input sources (say, mouse button 1 and the control key) can both press the * same button, but the button should only be released when both of the * pressing key have been released. * * When a key event issues a button command (+forward, +attack, etc), it appends * its key number as a parameter to the command so it can be matched up with * the release. * * state bit 0 is the current state of the key * state bit 1 is edge triggered on the up to down transition * state bit 2 is edge triggered on the down to up transition */ cvar_t cl_upspeed = {"cl_upspeed", "200"};cvar_t cl_forwardspeed = {"cl_forwardspeed", "400", true};cvar_t cl_backspeed = {"cl_backspeed", "400", true};cvar_t cl_sidespeed = {"cl_sidespeed", "350"}; cvar_t cl_movespeedkey = {"cl_movespeedkey", "2.0"}; cvar_t cl_yawspeed = {"cl_yawspeed", "140"};cvar_t cl_pitchspeed = {"cl_pitchspeed", "150"}; cvar_t cl_anglespeedkey = {"cl_anglespeedkey", "1.5"}; kbutton_t in_strafe, in_mlook; static kbutton_t in_left, in_right, in_forward, in_back;static kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright;static kbutton_t in_klook, in_speed;static kbutton_t in_moveup, in_movedown;static kbutton_t in_attack, in_jump, in_button3, in_button4, in_use;static kbutton_t in_button5, in_button6, in_button7, in_button8;static int in_impulse; static voidKeyDown(kbutton_t *b){	int k;	const char *c; 	c = Cmd_Argv(1);	if(c[0])		k = atoi(c);	else		k = -1; // typed manually at the console for continuous down 	if(k == b->down[0] || k == b->down[1])		return; // repeating key 	if(!b->down[0])		b->down[0] = k;	else if(!b->down[1])		b->down[1] = k;	else {		Con_Printf("Three keys down for a button!\n");		return;	} 	if(b->state & 1)		return; // still down	b->state |= 1 + 2; // down + impulse down} static voidKeyUp(kbutton_t *b){	int k;	const char *c; 	c = Cmd_Argv(1);	if(c[0])		k = atoi(c);	else { // typed manually at the console, assume for unsticking, so clear all		b->down[0] = b->down[1] = 0;		b->state = 4; // impulse up		return;	} 	if(b->down[0] == k)		b->down[0] = 0;	else if(b->down[1] == k)		b->down[1] = 0;	else		return; // key up without coresponding down (menu pass through)	if(b->down[0] || b->down[1])		return; // some other key is still holding it down 	if((b->state & 1) == 0)		return; // still up (this should not happen)	b->state &= ~1; // now up	b->state |= 4; // impulse up} #define IN_KEY_DOWN(key) \	static void IN_##key##Down(cmd_t *c) \	{ \		USED(c); \		KeyDown(&in_##key); \	} #define IN_KEY_UP(key) \	static void IN_##key##Up(cmd_t *c) \	{ \		USED(c); \		KeyUp(&in_##key); \	} #define IN_KEY(key) \	IN_KEY_DOWN(key); \	IN_KEY_UP(key); IN_KEY(klook);IN_KEY_DOWN(mlook); static voidIN_mlookUp(cmd_t *c){	KeyUp(&in_mlook);	if((in_mlook.state & 1) == 0 && lookspring.value)		V_StartPitchDrift(c);} IN_KEY(left);IN_KEY(right);IN_KEY(forward);IN_KEY(back);IN_KEY(lookup);IN_KEY(lookdown);IN_KEY(moveleft);IN_KEY(moveright);IN_KEY(moveup);IN_KEY(movedown);IN_KEY(speed);IN_KEY(strafe);IN_KEY(attack);IN_KEY(jump);IN_KEY(button3);IN_KEY(button4);IN_KEY(button5);IN_KEY(button6);IN_KEY(button7);IN_KEY(button8);IN_KEY(use); static voidIN_Impulse(cmd_t *c){	USED(c);	in_impulse = atoi(Cmd_Argv(1));} /*Returns 0.25 if a key was pressed and released during the frame,0.5 if it was pressed and held0 if held then released, and1.0 if held for the entire time*/static floatCL_KeyState(kbutton_t *key){	float val;	bool impulsedown, impulseup, down; 	impulsedown = key->state & 2;	impulseup = key->state & 4;	down = key->state & 1;	val = 0; 	if(impulsedown && !impulseup)		val = down ? 0.5 : 0;	else if(impulseup && !impulsedown)		val = 0;	else if(!impulsedown && !impulseup)		val = down ? 1.0 : 0;	else if(impulsedown && impulseup)		val = down ? 0.75 : 0.25; 	key->state &= 1; // clear impulses 	return val;} /* Moves the local angle positions */static voidCL_AdjustAngles(void){	float speed, up, down; 	if(in_speed.state & 1)		speed = scr_frametime * cl_anglespeedkey.value;	else		speed = scr_frametime; 	if(!(in_strafe.state & 1)) {		cl.viewangles[YAW] -= speed * cl_yawspeed.value * CL_KeyState(&in_right);		cl.viewangles[YAW] += speed * cl_yawspeed.value * CL_KeyState(&in_left);		cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]);	}	if(in_klook.state & 1) {		V_StopPitchDrift();		cl.viewangles[PITCH] -= speed * cl_pitchspeed.value * CL_KeyState(&in_forward);		cl.viewangles[PITCH] += speed * cl_pitchspeed.value * CL_KeyState(&in_back);	} 	up = CL_KeyState(&in_lookup);	down = CL_KeyState(&in_lookdown); 	cl.viewangles[PITCH] -= speed * cl_pitchspeed.value * up;	cl.viewangles[PITCH] += speed * cl_pitchspeed.value * down; 	if(up || down)		V_StopPitchDrift(); 	cl.viewangles[PITCH] = clamp(cl.viewangles[PITCH], -MAX_PITCH, MAX_PITCH);	cl.viewangles[ROLL] = clamp(cl.viewangles[ROLL], -MAX_ROLL, MAX_ROLL);} /* Send the intended movement message to the server */voidCL_BaseMove(usercmd_t *cmd){	if(cls.signon != SIGNONS)		return; 	CL_AdjustAngles(); 	memset(cmd, 0, sizeof(*cmd)); 	if(in_strafe.state & 1) {		cmd->sidemove += cl_sidespeed.value * CL_KeyState(&in_right);		cmd->sidemove -= cl_sidespeed.value * CL_KeyState(&in_left);	} 	cmd->sidemove += cl_sidespeed.value * CL_KeyState(&in_moveright);	cmd->sidemove -= cl_sidespeed.value * CL_KeyState(&in_moveleft); 	cmd->upmove += cl_upspeed.value * CL_KeyState(&in_moveup);	cmd->upmove -= cl_upspeed.value * CL_KeyState(&in_movedown); 	if((in_klook.state & 1) == 0) {		cmd->forwardmove += cl_forwardspeed.value * CL_KeyState(&in_forward);		cmd->forwardmove -= cl_backspeed.value * CL_KeyState(&in_back);	} 	// adjust for speed key	if(in_speed.state & 1) {		if((cmd->forwardmove > 0 && cl_forwardspeed.value > 200) ||		   (cmd->forwardmove < 0 && cl_backspeed.value > 200))			cmd->forwardmove /= cl_movespeedkey.value;		else			cmd->forwardmove *= cl_movespeedkey.value;		cmd->sidemove *= cl_movespeedkey.value;		cmd->upmove *= cl_movespeedkey.value;	}} voidCL_SendMove(usercmd_t *cmd){	byte data[128];	sizebuf_t buf;	int i, bits; 	buf.maxsize = 128;	buf.cursize = 0;	buf.data = data; 	cl.cmd = *cmd; 	// send the movement message	MSG_WriteByte(&buf, clc_move); 	MSG_WriteFloat(&buf, cl.mtime[0]); // so server can get ping times 	for(i = 0; i < 3; i++)		cl.protocol.MSG_WriteAngle(&buf, cl.viewangles[i]); 	MSG_WriteShort(&buf, cmd->forwardmove);	MSG_WriteShort(&buf, cmd->sidemove);	MSG_WriteShort(&buf, cmd->upmove); 	// send button bits	bits = 0; 	if(in_attack.state & 3)		bits |= 1 << 0;	in_attack.state &= ~2; 	if(in_jump.state & 3)		bits |= 1 << 1;	in_jump.state &= ~2; 	if(in_button3.state & 3)		bits |= 1 << 2;	in_button3.state &= ~2; 	if(in_button4.state & 3)		bits |= 1 << 3;	in_button4.state &= ~2; 	if(in_button5.state & 3)		bits |= 1 << 4;	in_button5.state &= ~2; 	if(in_button6.state & 3)		bits |= 1 << 5;	in_button6.state &= ~2; 	if(in_button7.state & 3)		bits |= 1 << 6;	in_button7.state &= ~2; 	if(in_button8.state & 3)		bits |= 1 << 7;	in_button8.state &= ~2;	/* FIXME		if(in_use.state & 3)			bits |= 4;		in_use.state &= ~2;	*/	MSG_WriteByte(&buf, bits); 	MSG_WriteByte(&buf, in_impulse);	in_impulse = 0; 	// deliver the message	if(cls.demoplayback)		return; 	// always dump the first two message, because it may contain leftover inputs	// from the last level	if(++cl.movemessages <= 2)		return; 	if(NET_SendUnreliableMessage(cls.netcon, &buf) == -1) {		Con_Printf("CL_SendMove: lost server connection\n");		CL_Disconnect();	}} voidCL_NewMap(void){	memset(&in_strafe, 0, sizeof(kbutton_t));	memset(&in_left, 0, sizeof(kbutton_t));	memset(&in_right, 0, sizeof(kbutton_t));	memset(&in_forward, 0, sizeof(kbutton_t));	memset(&in_back, 0, sizeof(kbutton_t));	memset(&in_lookup, 0, sizeof(kbutton_t));	memset(&in_lookdown, 0, sizeof(kbutton_t));	memset(&in_moveleft, 0, sizeof(kbutton_t));	memset(&in_moveright, 0, sizeof(kbutton_t));	memset(&in_moveup, 0, sizeof(kbutton_t));	memset(&in_movedown, 0, sizeof(kbutton_t));	memset(&in_attack, 0, sizeof(kbutton_t));	memset(&in_jump, 0, sizeof(kbutton_t));	memset(&in_button3, 0, sizeof(kbutton_t));	memset(&in_button4, 0, sizeof(kbutton_t));	memset(&in_button5, 0, sizeof(kbutton_t));	memset(&in_button6, 0, sizeof(kbutton_t));	memset(&in_button7, 0, sizeof(kbutton_t));	memset(&in_button8, 0, sizeof(kbutton_t));	memset(&in_use, 0, sizeof(kbutton_t));	in_impulse = 0;} voidCL_InitInput(void){#define KEY_CMD(key) \	Cmd_AddCommand("+" #key, IN_##key##Down); \	Cmd_AddCommand("-" #key, IN_##key##Up); 	KEY_CMD(strafe);	KEY_CMD(left);	KEY_CMD(right);	KEY_CMD(forward);	KEY_CMD(back);	KEY_CMD(lookup);	KEY_CMD(lookdown);	KEY_CMD(moveleft);	KEY_CMD(moveright);	KEY_CMD(moveup);	KEY_CMD(movedown);	KEY_CMD(attack);	KEY_CMD(jump);	KEY_CMD(button3);	KEY_CMD(button4);	KEY_CMD(button5);	KEY_CMD(button6);	KEY_CMD(button7);	KEY_CMD(button8);	KEY_CMD(use); 	KEY_CMD(klook);	KEY_CMD(mlook);	KEY_CMD(speed);	Cmd_AddCommand("impulse", IN_Impulse);}

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