You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1006 lines
22 KiB
1006 lines
22 KiB
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//============================================================================= |
|
|
|
// cl.input.c -- builds an intended movement command to send to the server |
|
|
|
//xxxxxx Move bob and pitch drifting code here and other stuff from view if needed |
|
|
|
// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All |
|
// rights reserved. |
|
#include "hud.h" |
|
#include "cl_util.h" |
|
#include "camera.h" |
|
extern "C" |
|
{ |
|
#include "kbutton.h" |
|
} |
|
#include "cvardef.h" |
|
#include "usercmd.h" |
|
#include "const.h" |
|
#include "camera.h" |
|
#include "in_defs.h" |
|
#include "view.h" |
|
#include <string.h> |
|
#include <ctype.h> |
|
|
|
|
|
|
|
extern "C" |
|
{ |
|
struct kbutton_s DLLEXPORT *KB_Find( const char *name ); |
|
void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ); |
|
void DLLEXPORT HUD_Shutdown( void ); |
|
int DLLEXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding ); |
|
} |
|
|
|
extern int g_iAlive; |
|
|
|
extern int g_weaponselect; |
|
extern cl_enginefunc_t gEngfuncs; |
|
|
|
// Defined in pm_math.c |
|
extern "C" float anglemod( float a ); |
|
|
|
void IN_Init (void); |
|
void IN_Move ( float frametime, usercmd_t *cmd); |
|
void IN_Shutdown( void ); |
|
void V_Init( void ); |
|
void VectorAngles( const float *forward, float *angles ); |
|
int CL_ButtonBits( int ); |
|
|
|
// xxx need client dll function to get and clear impuse |
|
extern cvar_t *in_joystick; |
|
|
|
int in_impulse = 0; |
|
int in_cancel = 0; |
|
|
|
cvar_t *m_pitch; |
|
cvar_t *m_yaw; |
|
cvar_t *m_forward; |
|
cvar_t *m_side; |
|
|
|
cvar_t *lookstrafe; |
|
cvar_t *lookspring; |
|
cvar_t *cl_pitchup; |
|
cvar_t *cl_pitchdown; |
|
cvar_t *cl_upspeed; |
|
cvar_t *cl_forwardspeed; |
|
cvar_t *cl_backspeed; |
|
cvar_t *cl_sidespeed; |
|
cvar_t *cl_movespeedkey; |
|
cvar_t *cl_yawspeed; |
|
cvar_t *cl_pitchspeed; |
|
cvar_t *cl_anglespeedkey; |
|
cvar_t *cl_vsmoothing; |
|
/* |
|
=============================================================================== |
|
|
|
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 |
|
|
|
=============================================================================== |
|
*/ |
|
|
|
|
|
kbutton_t in_mlook; |
|
kbutton_t in_klook; |
|
kbutton_t in_jlook; |
|
kbutton_t in_left; |
|
kbutton_t in_right; |
|
kbutton_t in_forward; |
|
kbutton_t in_back; |
|
kbutton_t in_lookup; |
|
kbutton_t in_lookdown; |
|
kbutton_t in_moveleft; |
|
kbutton_t in_moveright; |
|
kbutton_t in_strafe; |
|
kbutton_t in_speed; |
|
kbutton_t in_use; |
|
kbutton_t in_jump; |
|
kbutton_t in_attack; |
|
kbutton_t in_attack2; |
|
kbutton_t in_up; |
|
kbutton_t in_down; |
|
kbutton_t in_duck; |
|
kbutton_t in_reload; |
|
kbutton_t in_alt1; |
|
kbutton_t in_score; |
|
kbutton_t in_break; |
|
kbutton_t in_graph; // Display the netgraph |
|
|
|
typedef struct kblist_s |
|
{ |
|
struct kblist_s *next; |
|
kbutton_t *pkey; |
|
char name[32]; |
|
} kblist_t; |
|
|
|
kblist_t *g_kbkeys = NULL; |
|
|
|
/* |
|
============ |
|
KB_ConvertString |
|
|
|
Removes references to +use and replaces them with the keyname in the output string. If |
|
a binding is unfound, then the original text is retained. |
|
NOTE: Only works for text with +word in it. |
|
============ |
|
*/ |
|
int KB_ConvertString( char *in, char **ppout ) |
|
{ |
|
char sz[ 4096 ]; |
|
char binding[ 64 ]; |
|
char *p; |
|
char *pOut; |
|
char *pEnd; |
|
const char *pBinding; |
|
|
|
if ( !ppout ) |
|
return 0; |
|
|
|
*ppout = NULL; |
|
p = in; |
|
pOut = sz; |
|
while ( *p ) |
|
{ |
|
if ( *p == '+' ) |
|
{ |
|
pEnd = binding; |
|
while ( *p && ( isalnum( *p ) || ( pEnd == binding ) ) && ( ( pEnd - binding ) < 63 ) ) |
|
{ |
|
*pEnd++ = *p++; |
|
} |
|
|
|
*pEnd = '\0'; |
|
|
|
pBinding = NULL; |
|
if ( strlen( binding + 1 ) > 0 ) |
|
{ |
|
// See if there is a binding for binding? |
|
pBinding = gEngfuncs.Key_LookupBinding( binding + 1 ); |
|
} |
|
|
|
if ( pBinding ) |
|
{ |
|
*pOut++ = '['; |
|
pEnd = (char *)pBinding; |
|
} |
|
else |
|
{ |
|
pEnd = binding; |
|
} |
|
|
|
while ( *pEnd ) |
|
{ |
|
*pOut++ = *pEnd++; |
|
} |
|
|
|
if ( pBinding ) |
|
{ |
|
*pOut++ = ']'; |
|
} |
|
} |
|
else |
|
{ |
|
*pOut++ = *p++; |
|
} |
|
} |
|
|
|
*pOut = '\0'; |
|
|
|
pOut = ( char * )malloc( strlen( sz ) + 1 ); |
|
strcpy( pOut, sz ); |
|
*ppout = pOut; |
|
|
|
return 1; |
|
} |
|
|
|
/* |
|
============ |
|
KB_Find |
|
|
|
Allows the engine to get a kbutton_t directly ( so it can check +mlook state, etc ) for saving out to .cfg files |
|
============ |
|
*/ |
|
struct kbutton_s DLLEXPORT *KB_Find( const char *name ) |
|
{ |
|
kblist_t *p; |
|
p = g_kbkeys; |
|
while ( p ) |
|
{ |
|
if ( !stricmp( name, p->name ) ) |
|
return p->pkey; |
|
|
|
p = p->next; |
|
} |
|
return NULL; |
|
} |
|
|
|
/* |
|
============ |
|
KB_Add |
|
|
|
Add a kbutton_t * to the list of pointers the engine can retrieve via KB_Find |
|
============ |
|
*/ |
|
void KB_Add( const char *name, kbutton_t *pkb ) |
|
{ |
|
kblist_t *p; |
|
kbutton_t *kb; |
|
|
|
kb = KB_Find( name ); |
|
|
|
if ( kb ) |
|
return; |
|
|
|
p = ( kblist_t * )malloc( sizeof( kblist_t ) ); |
|
memset( p, 0, sizeof( *p ) ); |
|
|
|
strcpy( p->name, name ); |
|
p->pkey = pkb; |
|
|
|
p->next = g_kbkeys; |
|
g_kbkeys = p; |
|
} |
|
|
|
/* |
|
============ |
|
KB_Init |
|
|
|
Add kbutton_t definitions that the engine can query if needed |
|
============ |
|
*/ |
|
void KB_Init( void ) |
|
{ |
|
g_kbkeys = NULL; |
|
|
|
KB_Add( "in_graph", &in_graph ); |
|
KB_Add( "in_mlook", &in_mlook ); |
|
KB_Add( "in_jlook", &in_jlook ); |
|
} |
|
|
|
/* |
|
============ |
|
KB_Shutdown |
|
|
|
Clear kblist |
|
============ |
|
*/ |
|
void KB_Shutdown( void ) |
|
{ |
|
kblist_t *p, *n; |
|
p = g_kbkeys; |
|
while ( p ) |
|
{ |
|
n = p->next; |
|
free( p ); |
|
p = n; |
|
} |
|
g_kbkeys = NULL; |
|
} |
|
|
|
/* |
|
============ |
|
KeyDown |
|
============ |
|
*/ |
|
void KeyDown (kbutton_t *b) |
|
{ |
|
int k; |
|
char *c; |
|
|
|
c = gEngfuncs.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 |
|
{ |
|
gEngfuncs.Con_DPrintf ("Three keys down for a button '%c' '%c' '%c'!\n", b->down[0], b->down[1], c); |
|
return; |
|
} |
|
|
|
if (b->state & 1) |
|
return; // still down |
|
b->state |= 1 + 2; // down + impulse down |
|
} |
|
|
|
/* |
|
============ |
|
KeyUp |
|
============ |
|
*/ |
|
void KeyUp (kbutton_t *b) |
|
{ |
|
int k; |
|
char *c; |
|
|
|
c = gEngfuncs.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]) |
|
{ |
|
//Con_Printf ("Keys down for button: '%c' '%c' '%c' (%d,%d,%d)!\n", b->down[0], b->down[1], c, b->down[0], b->down[1], c); |
|
return; // some other key is still holding it down |
|
} |
|
|
|
if (!(b->state & 1)) |
|
return; // still up (this should not happen) |
|
|
|
b->state &= ~1; // now up |
|
b->state |= 4; // impulse up |
|
} |
|
|
|
/* |
|
============ |
|
HUD_Key_Event |
|
|
|
Return 1 to allow engine to process the key, otherwise, act on it as needed |
|
============ |
|
*/ |
|
int DLLEXPORT HUD_Key_Event( int down, int keynum, const char *pszCurrentBinding ) |
|
{ |
|
|
|
return 1; |
|
} |
|
|
|
void IN_BreakDown( void ) { KeyDown( &in_break );}; |
|
void IN_BreakUp( void ) { KeyUp( &in_break ); }; |
|
void IN_KLookDown (void) {KeyDown(&in_klook);} |
|
void IN_KLookUp (void) {KeyUp(&in_klook);} |
|
void IN_JLookDown (void) {KeyDown(&in_jlook);} |
|
void IN_JLookUp (void) {KeyUp(&in_jlook);} |
|
void IN_MLookDown (void) {KeyDown(&in_mlook);} |
|
void IN_UpDown(void) {KeyDown(&in_up);} |
|
void IN_UpUp(void) {KeyUp(&in_up);} |
|
void IN_DownDown(void) {KeyDown(&in_down);} |
|
void IN_DownUp(void) {KeyUp(&in_down);} |
|
void IN_LeftDown(void) {KeyDown(&in_left);} |
|
void IN_LeftUp(void) {KeyUp(&in_left);} |
|
void IN_RightDown(void) {KeyDown(&in_right);} |
|
void IN_RightUp(void) {KeyUp(&in_right);} |
|
|
|
void IN_ForwardDown(void) |
|
{ |
|
KeyDown(&in_forward); |
|
gHUD.m_Spectator.HandleButtonsDown( IN_FORWARD ); |
|
} |
|
|
|
void IN_ForwardUp(void) |
|
{ |
|
KeyUp(&in_forward); |
|
gHUD.m_Spectator.HandleButtonsUp( IN_FORWARD ); |
|
} |
|
|
|
void IN_BackDown(void) |
|
{ |
|
KeyDown(&in_back); |
|
gHUD.m_Spectator.HandleButtonsDown( IN_BACK ); |
|
} |
|
|
|
void IN_BackUp(void) |
|
{ |
|
KeyUp(&in_back); |
|
gHUD.m_Spectator.HandleButtonsUp( IN_BACK ); |
|
} |
|
void IN_LookupDown(void) {KeyDown(&in_lookup);} |
|
void IN_LookupUp(void) {KeyUp(&in_lookup);} |
|
void IN_LookdownDown(void) {KeyDown(&in_lookdown);} |
|
void IN_LookdownUp(void) {KeyUp(&in_lookdown);} |
|
void IN_MoveleftDown(void) |
|
{ |
|
KeyDown(&in_moveleft); |
|
gHUD.m_Spectator.HandleButtonsDown( IN_MOVELEFT ); |
|
} |
|
|
|
void IN_MoveleftUp(void) |
|
{ |
|
KeyUp(&in_moveleft); |
|
gHUD.m_Spectator.HandleButtonsUp( IN_MOVELEFT ); |
|
} |
|
|
|
void IN_MoverightDown(void) |
|
{ |
|
KeyDown(&in_moveright); |
|
gHUD.m_Spectator.HandleButtonsDown( IN_MOVERIGHT ); |
|
} |
|
|
|
void IN_MoverightUp(void) |
|
{ |
|
KeyUp(&in_moveright); |
|
gHUD.m_Spectator.HandleButtonsUp( IN_MOVERIGHT ); |
|
} |
|
void IN_SpeedDown(void) {KeyDown(&in_speed);} |
|
void IN_SpeedUp(void) {KeyUp(&in_speed);} |
|
void IN_StrafeDown(void) {KeyDown(&in_strafe);} |
|
void IN_StrafeUp(void) {KeyUp(&in_strafe);} |
|
|
|
// needs capture by hud/vgui also |
|
extern void __CmdFunc_InputPlayerSpecial(void); |
|
|
|
void IN_Attack2Down(void) |
|
{ |
|
KeyDown(&in_attack2); |
|
|
|
gHUD.m_Spectator.HandleButtonsDown( IN_ATTACK2 ); |
|
} |
|
|
|
void IN_Attack2Up(void) {KeyUp(&in_attack2);} |
|
void IN_UseDown (void) |
|
{ |
|
KeyDown(&in_use); |
|
gHUD.m_Spectator.HandleButtonsDown( IN_USE ); |
|
} |
|
void IN_UseUp (void) {KeyUp(&in_use);} |
|
void IN_JumpDown (void) |
|
{ |
|
KeyDown(&in_jump); |
|
gHUD.m_Spectator.HandleButtonsDown( IN_JUMP ); |
|
|
|
} |
|
void IN_JumpUp (void) {KeyUp(&in_jump);} |
|
void IN_DuckDown(void) |
|
{ |
|
KeyDown(&in_duck); |
|
gHUD.m_Spectator.HandleButtonsDown( IN_DUCK ); |
|
|
|
} |
|
void IN_DuckUp(void) {KeyUp(&in_duck);} |
|
void IN_ReloadDown(void) {KeyDown(&in_reload);} |
|
void IN_ReloadUp(void) {KeyUp(&in_reload);} |
|
void IN_Alt1Down(void) {KeyDown(&in_alt1);} |
|
void IN_Alt1Up(void) {KeyUp(&in_alt1);} |
|
void IN_GraphDown(void) {KeyDown(&in_graph);} |
|
void IN_GraphUp(void) {KeyUp(&in_graph);} |
|
|
|
void IN_AttackDown(void) |
|
{ |
|
KeyDown( &in_attack ); |
|
gHUD.m_Spectator.HandleButtonsDown( IN_ATTACK ); |
|
} |
|
|
|
void IN_AttackUp(void) |
|
{ |
|
KeyUp( &in_attack ); |
|
in_cancel = 0; |
|
} |
|
|
|
// Special handling |
|
void IN_Cancel(void) |
|
{ |
|
in_cancel = 1; |
|
} |
|
|
|
void IN_Impulse (void) |
|
{ |
|
in_impulse = atoi( gEngfuncs.Cmd_Argv(1) ); |
|
} |
|
|
|
void IN_ScoreDown(void) |
|
{ |
|
KeyDown(&in_score); |
|
} |
|
|
|
void IN_ScoreUp(void) |
|
{ |
|
KeyUp(&in_score); |
|
} |
|
|
|
void IN_MLookUp (void) |
|
{ |
|
KeyUp( &in_mlook ); |
|
} |
|
|
|
/* |
|
=============== |
|
CL_KeyState |
|
|
|
Returns 0.25 if a key was pressed and released during the frame, |
|
0.5 if it was pressed and held |
|
0 if held then released, and |
|
1.0 if held for the entire time |
|
=============== |
|
*/ |
|
float CL_KeyState (kbutton_t *key) |
|
{ |
|
float val = 0.0; |
|
int impulsedown, impulseup, down; |
|
|
|
impulsedown = key->state & 2; |
|
impulseup = key->state & 4; |
|
down = key->state & 1; |
|
|
|
if ( impulsedown && !impulseup ) |
|
{ |
|
// pressed and held this frame? |
|
val = down ? 0.5 : 0.0; |
|
} |
|
|
|
if ( impulseup && !impulsedown ) |
|
{ |
|
// released this frame? |
|
val = down ? 0.0 : 0.0; |
|
} |
|
|
|
if ( !impulsedown && !impulseup ) |
|
{ |
|
// held the entire frame? |
|
val = down ? 1.0 : 0.0; |
|
} |
|
|
|
if ( impulsedown && impulseup ) |
|
{ |
|
if ( down ) |
|
{ |
|
// released and re-pressed this frame |
|
val = 0.75; |
|
} |
|
else |
|
{ |
|
// pressed and released this frame |
|
val = 0.25; |
|
} |
|
} |
|
|
|
// clear impulses |
|
key->state &= 1; |
|
return val; |
|
} |
|
|
|
/* |
|
================ |
|
CL_AdjustAngles |
|
|
|
Moves the local angle positions |
|
================ |
|
*/ |
|
void CL_AdjustAngles ( float frametime, float *viewangles ) |
|
{ |
|
float speed; |
|
float up, down; |
|
|
|
if (in_speed.state & 1) |
|
{ |
|
speed = frametime * cl_anglespeedkey->value; |
|
} |
|
else |
|
{ |
|
speed = frametime; |
|
} |
|
|
|
if (!(in_strafe.state & 1)) |
|
{ |
|
viewangles[YAW] -= speed*cl_yawspeed->value*CL_KeyState (&in_right); |
|
viewangles[YAW] += speed*cl_yawspeed->value*CL_KeyState (&in_left); |
|
viewangles[YAW] = anglemod(viewangles[YAW]); |
|
} |
|
if (in_klook.state & 1) |
|
{ |
|
viewangles[PITCH] -= speed*cl_pitchspeed->value * CL_KeyState (&in_forward); |
|
viewangles[PITCH] += speed*cl_pitchspeed->value * CL_KeyState (&in_back); |
|
} |
|
|
|
up = CL_KeyState (&in_lookup); |
|
down = CL_KeyState(&in_lookdown); |
|
|
|
viewangles[PITCH] -= speed*cl_pitchspeed->value * up; |
|
viewangles[PITCH] += speed*cl_pitchspeed->value * down; |
|
|
|
if (viewangles[PITCH] > cl_pitchdown->value) |
|
viewangles[PITCH] = cl_pitchdown->value; |
|
if (viewangles[PITCH] < -cl_pitchup->value) |
|
viewangles[PITCH] = -cl_pitchup->value; |
|
|
|
if (viewangles[ROLL] > 50) |
|
viewangles[ROLL] = 50; |
|
if (viewangles[ROLL] < -50) |
|
viewangles[ROLL] = -50; |
|
} |
|
|
|
/* |
|
================ |
|
CL_CreateMove |
|
|
|
Send the intended movement message to the server |
|
if active == 1 then we are 1) not playing back demos ( where our commands are ignored ) and |
|
2 ) we have finished signing on to server |
|
================ |
|
*/ |
|
void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ) |
|
{ |
|
float spd; |
|
vec3_t viewangles; |
|
static vec3_t oldangles; |
|
|
|
if ( active ) |
|
{ |
|
//memset( viewangles, 0, sizeof( vec3_t ) ); |
|
//viewangles[ 0 ] = viewangles[ 1 ] = viewangles[ 2 ] = 0.0; |
|
gEngfuncs.GetViewAngles( (float *)viewangles ); |
|
|
|
CL_AdjustAngles ( frametime, viewangles ); |
|
|
|
memset (cmd, 0, sizeof(*cmd)); |
|
|
|
gEngfuncs.SetViewAngles( (float *)viewangles ); |
|
|
|
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_up); |
|
cmd->upmove -= cl_upspeed->value * CL_KeyState (&in_down); |
|
|
|
if ( !(in_klook.state & 1 ) ) |
|
{ |
|
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 ) |
|
{ |
|
cmd->forwardmove *= cl_movespeedkey->value; |
|
cmd->sidemove *= cl_movespeedkey->value; |
|
cmd->upmove *= cl_movespeedkey->value; |
|
} |
|
|
|
// clip to maxspeed |
|
spd = gEngfuncs.GetClientMaxspeed(); |
|
if ( spd != 0.0 ) |
|
{ |
|
// scale the 3 speeds so that the total velocity is not > cl.maxspeed |
|
float fmov = sqrt( (cmd->forwardmove*cmd->forwardmove) + (cmd->sidemove*cmd->sidemove) + (cmd->upmove*cmd->upmove) ); |
|
|
|
if ( fmov > spd ) |
|
{ |
|
float fratio = spd / fmov; |
|
cmd->forwardmove *= fratio; |
|
cmd->sidemove *= fratio; |
|
cmd->upmove *= fratio; |
|
} |
|
} |
|
|
|
// Allow mice and other controllers to add their inputs |
|
IN_Move ( frametime, cmd ); |
|
} |
|
|
|
cmd->impulse = in_impulse; |
|
in_impulse = 0; |
|
|
|
cmd->weaponselect = g_weaponselect; |
|
g_weaponselect = 0; |
|
// |
|
// set button and flag bits |
|
// |
|
cmd->buttons = CL_ButtonBits( 1 ); |
|
|
|
|
|
// Using joystick? |
|
if ( in_joystick->value ) |
|
{ |
|
if ( cmd->forwardmove > 0 ) |
|
{ |
|
cmd->buttons |= IN_FORWARD; |
|
} |
|
else if ( cmd->forwardmove < 0 ) |
|
{ |
|
cmd->buttons |= IN_BACK; |
|
} |
|
} |
|
|
|
gEngfuncs.GetViewAngles( (float *)viewangles ); |
|
// Set current view angles. |
|
|
|
if ( g_iAlive ) |
|
{ |
|
VectorCopy( viewangles, cmd->viewangles ); |
|
VectorCopy( viewangles, oldangles ); |
|
} |
|
else |
|
{ |
|
VectorCopy( oldangles, cmd->viewangles ); |
|
} |
|
|
|
} |
|
|
|
/* |
|
============ |
|
CL_IsDead |
|
|
|
Returns 1 if health is <= 0 |
|
============ |
|
*/ |
|
int CL_IsDead( void ) |
|
{ |
|
return ( gHUD.m_Health.m_iHealth <= 0 ) ? 1 : 0; |
|
} |
|
|
|
/* |
|
============ |
|
CL_ButtonBits |
|
|
|
Returns appropriate button info for keyboard and mouse state |
|
Set bResetState to 1 to clear old state info |
|
============ |
|
*/ |
|
int CL_ButtonBits( int bResetState ) |
|
{ |
|
int bits = 0; |
|
|
|
if ( in_attack.state & 3 ) |
|
{ |
|
if(gHUD.m_MOTD.m_bShow) |
|
gHUD.m_MOTD.Reset(); |
|
else |
|
bits |= IN_ATTACK; |
|
} |
|
|
|
|
|
if (in_duck.state & 3) |
|
{ |
|
bits |= IN_DUCK; |
|
} |
|
|
|
if (in_jump.state & 3) |
|
{ |
|
bits |= IN_JUMP; |
|
} |
|
|
|
if ( in_forward.state & 3 ) |
|
{ |
|
bits |= IN_FORWARD; |
|
} |
|
|
|
if (in_back.state & 3) |
|
{ |
|
bits |= IN_BACK; |
|
} |
|
|
|
if (in_use.state & 3) |
|
{ |
|
bits |= IN_USE; |
|
} |
|
|
|
if (in_cancel) |
|
{ |
|
bits |= IN_CANCEL; |
|
} |
|
|
|
if ( in_left.state & 3 ) |
|
{ |
|
bits |= IN_LEFT; |
|
} |
|
|
|
if (in_right.state & 3) |
|
{ |
|
bits |= IN_RIGHT; |
|
} |
|
|
|
if ( in_moveleft.state & 3 ) |
|
{ |
|
bits |= IN_MOVELEFT; |
|
} |
|
|
|
if (in_moveright.state & 3) |
|
{ |
|
bits |= IN_MOVERIGHT; |
|
} |
|
|
|
if (in_attack2.state & 3) |
|
{ |
|
bits |= IN_ATTACK2; |
|
} |
|
|
|
if (in_reload.state & 3) |
|
{ |
|
bits |= IN_RELOAD; |
|
} |
|
|
|
if (in_alt1.state & 3) |
|
{ |
|
bits |= IN_ALT1; |
|
} |
|
|
|
if ( in_score.state & 3 ) |
|
{ |
|
bits |= IN_SCORE; |
|
} |
|
|
|
// Dead or in intermission? Shore scoreboard, too |
|
if ( CL_IsDead() || gHUD.m_iIntermission ) |
|
{ |
|
bits |= IN_SCORE; |
|
} |
|
|
|
if ( bResetState ) |
|
{ |
|
in_attack.state &= ~2; |
|
in_duck.state &= ~2; |
|
in_jump.state &= ~2; |
|
in_forward.state &= ~2; |
|
in_back.state &= ~2; |
|
in_use.state &= ~2; |
|
in_left.state &= ~2; |
|
in_right.state &= ~2; |
|
in_moveleft.state &= ~2; |
|
in_moveright.state &= ~2; |
|
in_attack2.state &= ~2; |
|
in_reload.state &= ~2; |
|
in_alt1.state &= ~2; |
|
in_score.state &= ~2; |
|
} |
|
|
|
return bits; |
|
} |
|
|
|
/* |
|
============ |
|
CL_ResetButtonBits |
|
|
|
============ |
|
*/ |
|
void CL_ResetButtonBits( int bits ) |
|
{ |
|
int bitsNew = CL_ButtonBits( 0 ) ^ bits; |
|
|
|
// Has the attack button been changed |
|
if ( bitsNew & IN_ATTACK ) |
|
{ |
|
// Was it pressed? or let go? |
|
if ( bits & IN_ATTACK ) |
|
{ |
|
KeyDown( &in_attack ); |
|
} |
|
else |
|
{ |
|
// totally clear state |
|
in_attack.state &= ~7; |
|
} |
|
} |
|
} |
|
|
|
/* |
|
============ |
|
InitInput |
|
============ |
|
*/ |
|
void InitInput (void) |
|
{ |
|
gEngfuncs.pfnAddCommand ("+moveup",IN_UpDown); |
|
gEngfuncs.pfnAddCommand ("-moveup",IN_UpUp); |
|
gEngfuncs.pfnAddCommand ("+movedown",IN_DownDown); |
|
gEngfuncs.pfnAddCommand ("-movedown",IN_DownUp); |
|
gEngfuncs.pfnAddCommand ("+left",IN_LeftDown); |
|
gEngfuncs.pfnAddCommand ("-left",IN_LeftUp); |
|
gEngfuncs.pfnAddCommand ("+right",IN_RightDown); |
|
gEngfuncs.pfnAddCommand ("-right",IN_RightUp); |
|
gEngfuncs.pfnAddCommand ("+forward",IN_ForwardDown); |
|
gEngfuncs.pfnAddCommand ("-forward",IN_ForwardUp); |
|
gEngfuncs.pfnAddCommand ("+back",IN_BackDown); |
|
gEngfuncs.pfnAddCommand ("-back",IN_BackUp); |
|
gEngfuncs.pfnAddCommand ("+lookup", IN_LookupDown); |
|
gEngfuncs.pfnAddCommand ("-lookup", IN_LookupUp); |
|
gEngfuncs.pfnAddCommand ("+lookdown", IN_LookdownDown); |
|
gEngfuncs.pfnAddCommand ("-lookdown", IN_LookdownUp); |
|
gEngfuncs.pfnAddCommand ("+strafe", IN_StrafeDown); |
|
gEngfuncs.pfnAddCommand ("-strafe", IN_StrafeUp); |
|
gEngfuncs.pfnAddCommand ("+moveleft", IN_MoveleftDown); |
|
gEngfuncs.pfnAddCommand ("-moveleft", IN_MoveleftUp); |
|
gEngfuncs.pfnAddCommand ("+moveright", IN_MoverightDown); |
|
gEngfuncs.pfnAddCommand ("-moveright", IN_MoverightUp); |
|
gEngfuncs.pfnAddCommand ("+speed", IN_SpeedDown); |
|
gEngfuncs.pfnAddCommand ("-speed", IN_SpeedUp); |
|
gEngfuncs.pfnAddCommand ("+attack", IN_AttackDown); |
|
gEngfuncs.pfnAddCommand ("-attack", IN_AttackUp); |
|
gEngfuncs.pfnAddCommand ("+attack2", IN_Attack2Down); |
|
gEngfuncs.pfnAddCommand ("-attack2", IN_Attack2Up); |
|
gEngfuncs.pfnAddCommand ("+use", IN_UseDown); |
|
gEngfuncs.pfnAddCommand ("-use", IN_UseUp); |
|
gEngfuncs.pfnAddCommand ("+jump", IN_JumpDown); |
|
gEngfuncs.pfnAddCommand ("-jump", IN_JumpUp); |
|
gEngfuncs.pfnAddCommand ("impulse", IN_Impulse); |
|
gEngfuncs.pfnAddCommand ("+klook", IN_KLookDown); |
|
gEngfuncs.pfnAddCommand ("-klook", IN_KLookUp); |
|
gEngfuncs.pfnAddCommand ("+mlook", IN_MLookDown); |
|
gEngfuncs.pfnAddCommand ("-mlook", IN_MLookUp); |
|
gEngfuncs.pfnAddCommand ("+jlook", IN_JLookDown); |
|
gEngfuncs.pfnAddCommand ("-jlook", IN_JLookUp); |
|
gEngfuncs.pfnAddCommand ("+duck", IN_DuckDown); |
|
gEngfuncs.pfnAddCommand ("-duck", IN_DuckUp); |
|
gEngfuncs.pfnAddCommand ("+reload", IN_ReloadDown); |
|
gEngfuncs.pfnAddCommand ("-reload", IN_ReloadUp); |
|
gEngfuncs.pfnAddCommand ("+alt1", IN_Alt1Down); |
|
gEngfuncs.pfnAddCommand ("-alt1", IN_Alt1Up); |
|
gEngfuncs.pfnAddCommand ("+graph", IN_GraphDown); |
|
gEngfuncs.pfnAddCommand ("-graph", IN_GraphUp); |
|
gEngfuncs.pfnAddCommand ("+break",IN_BreakDown); |
|
gEngfuncs.pfnAddCommand ("-break",IN_BreakUp); |
|
|
|
lookstrafe = gEngfuncs.pfnRegisterVariable ( "lookstrafe", "0", FCVAR_ARCHIVE ); |
|
lookspring = gEngfuncs.pfnRegisterVariable ( "lookspring", "0", FCVAR_ARCHIVE ); |
|
cl_anglespeedkey = gEngfuncs.pfnRegisterVariable ( "cl_anglespeedkey", "0.67", 0 ); |
|
cl_yawspeed = gEngfuncs.pfnRegisterVariable ( "cl_yawspeed", "210", 0 ); |
|
cl_pitchspeed = gEngfuncs.pfnRegisterVariable ( "cl_pitchspeed", "225", 0 ); |
|
cl_upspeed = gEngfuncs.pfnRegisterVariable ( "cl_upspeed", "320", 0 ); |
|
cl_forwardspeed = gEngfuncs.pfnRegisterVariable ( "cl_forwardspeed", "400", FCVAR_ARCHIVE ); |
|
cl_backspeed = gEngfuncs.pfnRegisterVariable ( "cl_backspeed", "400", FCVAR_ARCHIVE ); |
|
cl_sidespeed = gEngfuncs.pfnRegisterVariable ( "cl_sidespeed", "400", 0 ); |
|
cl_movespeedkey = gEngfuncs.pfnRegisterVariable ( "cl_movespeedkey", "0.3", 0 ); |
|
cl_pitchup = gEngfuncs.pfnRegisterVariable ( "cl_pitchup", "89", 0 ); |
|
cl_pitchdown = gEngfuncs.pfnRegisterVariable ( "cl_pitchdown", "89", 0 ); |
|
|
|
cl_vsmoothing = gEngfuncs.pfnRegisterVariable ( "cl_vsmoothing", "0.05", FCVAR_ARCHIVE ); |
|
|
|
m_pitch = gEngfuncs.pfnRegisterVariable ( "m_pitch","0.022", FCVAR_ARCHIVE ); |
|
m_yaw = gEngfuncs.pfnRegisterVariable ( "m_yaw","0.022", FCVAR_ARCHIVE ); |
|
m_forward = gEngfuncs.pfnRegisterVariable ( "m_forward","1", FCVAR_ARCHIVE ); |
|
m_side = gEngfuncs.pfnRegisterVariable ( "m_side","0.8", FCVAR_ARCHIVE ); |
|
|
|
// Initialize third person camera controls. |
|
CAM_Init(); |
|
// Initialize inputs |
|
IN_Init(); |
|
// Initialize keyboard |
|
KB_Init(); |
|
// Initialize view system |
|
V_Init(); |
|
} |
|
|
|
/* |
|
============ |
|
ShutdownInput |
|
============ |
|
*/ |
|
void ShutdownInput (void) |
|
{ |
|
IN_Shutdown(); |
|
KB_Shutdown(); |
|
} |
|
|
|
void DLLEXPORT HUD_Shutdown( void ) |
|
{ |
|
ShutdownInput(); |
|
}
|
|
|