2011-11-22 21:28:15 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 GPL Source Code
2011-12-06 18:20:15 +00:00
Copyright ( C ) 1999 - 2011 id Software LLC , a ZeniMax Media company .
2011-11-22 21:28:15 +00:00
2011-12-06 16:14:59 +00:00
This file is part of the Doom 3 GPL Source Code ( " Doom 3 Source Code " ) .
2011-11-22 21:28:15 +00:00
Doom 3 Source Code is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Doom 3 Source Code is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2011-12-16 22:28:29 +00:00
# include "sys/platform.h"
# include "idlib/math/Vector.h"
# include "idlib/Lib.h"
# include "framework/CVarSystem.h"
# include "framework/KeyInput.h"
# include "framework/async/AsyncNetwork.h"
# include "framework/UsercmdGen.h"
2011-11-22 21:28:15 +00:00
/*
= = = = = = = = = = = = = = = =
usercmd_t : : ByteSwap
= = = = = = = = = = = = = = = =
*/
void usercmd_t : : ByteSwap ( void ) {
angles [ 0 ] = LittleShort ( angles [ 0 ] ) ;
angles [ 1 ] = LittleShort ( angles [ 1 ] ) ;
angles [ 2 ] = LittleShort ( angles [ 2 ] ) ;
2012-06-28 10:49:24 +00:00
sequence = LittleInt ( sequence ) ;
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = = = =
usercmd_t : : operator = =
= = = = = = = = = = = = = = = =
*/
2011-12-06 18:20:15 +00:00
bool usercmd_t : : operator = = ( const usercmd_t & rhs ) const {
2011-11-22 21:28:15 +00:00
return ( buttons = = rhs . buttons & &
forwardmove = = rhs . forwardmove & &
rightmove = = rhs . rightmove & &
upmove = = rhs . upmove & &
angles [ 0 ] = = rhs . angles [ 0 ] & &
angles [ 1 ] = = rhs . angles [ 1 ] & &
angles [ 2 ] = = rhs . angles [ 2 ] & &
impulse = = rhs . impulse & &
flags = = rhs . flags & &
mx = = rhs . mx & &
my = = rhs . my ) ;
}
const int KEY_MOVESPEED = 127 ;
typedef enum {
UB_NONE ,
UB_UP ,
UB_DOWN ,
UB_LEFT ,
UB_RIGHT ,
UB_FORWARD ,
UB_BACK ,
UB_LOOKUP ,
UB_LOOKDOWN ,
UB_STRAFE ,
UB_MOVELEFT ,
UB_MOVERIGHT ,
UB_BUTTON0 ,
UB_BUTTON1 ,
UB_BUTTON2 ,
UB_BUTTON3 ,
UB_BUTTON4 ,
UB_BUTTON5 ,
UB_BUTTON6 ,
UB_BUTTON7 ,
2024-01-18 18:53:45 +00:00
UB_ATTACK , // NOTE: this value (20) is hardcoded in idUserInterfaceLocal::HandleEvent() !
2011-11-22 21:28:15 +00:00
UB_SPEED ,
UB_ZOOM ,
UB_SHOWSCORES ,
UB_MLOOK ,
UB_IMPULSE0 ,
UB_IMPULSE1 ,
UB_IMPULSE2 ,
UB_IMPULSE3 ,
UB_IMPULSE4 ,
UB_IMPULSE5 ,
UB_IMPULSE6 ,
UB_IMPULSE7 ,
UB_IMPULSE8 ,
UB_IMPULSE9 ,
UB_IMPULSE10 ,
UB_IMPULSE11 ,
UB_IMPULSE12 ,
UB_IMPULSE13 ,
UB_IMPULSE14 ,
UB_IMPULSE15 ,
UB_IMPULSE16 ,
UB_IMPULSE17 ,
UB_IMPULSE18 ,
UB_IMPULSE19 ,
UB_IMPULSE20 ,
UB_IMPULSE21 ,
UB_IMPULSE22 ,
UB_IMPULSE23 ,
UB_IMPULSE24 ,
UB_IMPULSE25 ,
UB_IMPULSE26 ,
UB_IMPULSE27 ,
UB_IMPULSE28 ,
UB_IMPULSE29 ,
UB_IMPULSE30 ,
UB_IMPULSE31 ,
UB_IMPULSE32 ,
UB_IMPULSE33 ,
UB_IMPULSE34 ,
UB_IMPULSE35 ,
UB_IMPULSE36 ,
UB_IMPULSE37 ,
UB_IMPULSE38 ,
UB_IMPULSE39 ,
UB_IMPULSE40 ,
UB_IMPULSE41 ,
UB_IMPULSE42 ,
UB_IMPULSE43 ,
UB_IMPULSE44 ,
UB_IMPULSE45 ,
UB_IMPULSE46 ,
UB_IMPULSE47 ,
UB_IMPULSE48 ,
UB_IMPULSE49 ,
UB_IMPULSE50 ,
UB_IMPULSE51 ,
UB_IMPULSE52 ,
UB_IMPULSE53 ,
UB_IMPULSE54 ,
UB_IMPULSE55 ,
UB_IMPULSE56 ,
UB_IMPULSE57 ,
UB_IMPULSE58 ,
UB_IMPULSE59 ,
UB_IMPULSE60 ,
UB_IMPULSE61 ,
UB_IMPULSE62 ,
UB_IMPULSE63 ,
UB_MAX_BUTTONS
} usercmdButton_t ;
typedef struct {
const char * string ;
usercmdButton_t button ;
} userCmdString_t ;
userCmdString_t userCmdStrings [ ] = {
{ " _moveUp " , UB_UP } ,
{ " _moveDown " , UB_DOWN } ,
{ " _left " , UB_LEFT } ,
{ " _right " , UB_RIGHT } ,
{ " _forward " , UB_FORWARD } ,
{ " _back " , UB_BACK } ,
{ " _lookUp " , UB_LOOKUP } ,
{ " _lookDown " , UB_LOOKDOWN } ,
{ " _strafe " , UB_STRAFE } ,
{ " _moveLeft " , UB_MOVELEFT } ,
{ " _moveRight " , UB_MOVERIGHT } ,
{ " _attack " , UB_ATTACK } ,
{ " _speed " , UB_SPEED } ,
{ " _zoom " , UB_ZOOM } ,
{ " _showScores " , UB_SHOWSCORES } ,
{ " _mlook " , UB_MLOOK } ,
{ " _button0 " , UB_BUTTON0 } ,
{ " _button1 " , UB_BUTTON1 } ,
{ " _button2 " , UB_BUTTON2 } ,
{ " _button3 " , UB_BUTTON3 } ,
{ " _button4 " , UB_BUTTON4 } ,
{ " _button5 " , UB_BUTTON5 } ,
{ " _button6 " , UB_BUTTON6 } ,
{ " _button7 " , UB_BUTTON7 } ,
{ " _impulse0 " , UB_IMPULSE0 } ,
{ " _impulse1 " , UB_IMPULSE1 } ,
{ " _impulse2 " , UB_IMPULSE2 } ,
{ " _impulse3 " , UB_IMPULSE3 } ,
{ " _impulse4 " , UB_IMPULSE4 } ,
{ " _impulse5 " , UB_IMPULSE5 } ,
{ " _impulse6 " , UB_IMPULSE6 } ,
{ " _impulse7 " , UB_IMPULSE7 } ,
{ " _impulse8 " , UB_IMPULSE8 } ,
{ " _impulse9 " , UB_IMPULSE9 } ,
{ " _impulse10 " , UB_IMPULSE10 } ,
{ " _impulse11 " , UB_IMPULSE11 } ,
{ " _impulse12 " , UB_IMPULSE12 } ,
{ " _impulse13 " , UB_IMPULSE13 } ,
{ " _impulse14 " , UB_IMPULSE14 } ,
{ " _impulse15 " , UB_IMPULSE15 } ,
{ " _impulse16 " , UB_IMPULSE16 } ,
{ " _impulse17 " , UB_IMPULSE17 } ,
{ " _impulse18 " , UB_IMPULSE18 } ,
{ " _impulse19 " , UB_IMPULSE19 } ,
{ " _impulse20 " , UB_IMPULSE20 } ,
{ " _impulse21 " , UB_IMPULSE21 } ,
{ " _impulse22 " , UB_IMPULSE22 } ,
{ " _impulse23 " , UB_IMPULSE23 } ,
{ " _impulse24 " , UB_IMPULSE24 } ,
{ " _impulse25 " , UB_IMPULSE25 } ,
{ " _impulse26 " , UB_IMPULSE26 } ,
{ " _impulse27 " , UB_IMPULSE27 } ,
{ " _impulse28 " , UB_IMPULSE28 } ,
{ " _impulse29 " , UB_IMPULSE29 } ,
{ " _impulse30 " , UB_IMPULSE30 } ,
{ " _impulse31 " , UB_IMPULSE31 } ,
{ " _impulse32 " , UB_IMPULSE32 } ,
{ " _impulse33 " , UB_IMPULSE33 } ,
{ " _impulse34 " , UB_IMPULSE34 } ,
{ " _impulse35 " , UB_IMPULSE35 } ,
{ " _impulse36 " , UB_IMPULSE36 } ,
{ " _impulse37 " , UB_IMPULSE37 } ,
{ " _impulse38 " , UB_IMPULSE38 } ,
{ " _impulse39 " , UB_IMPULSE39 } ,
{ " _impulse40 " , UB_IMPULSE40 } ,
{ " _impulse41 " , UB_IMPULSE41 } ,
{ " _impulse42 " , UB_IMPULSE42 } ,
{ " _impulse43 " , UB_IMPULSE43 } ,
{ " _impulse44 " , UB_IMPULSE44 } ,
{ " _impulse45 " , UB_IMPULSE45 } ,
{ " _impulse46 " , UB_IMPULSE46 } ,
{ " _impulse47 " , UB_IMPULSE47 } ,
{ " _impulse48 " , UB_IMPULSE48 } ,
{ " _impulse49 " , UB_IMPULSE49 } ,
{ " _impulse50 " , UB_IMPULSE50 } ,
{ " _impulse51 " , UB_IMPULSE51 } ,
{ " _impulse52 " , UB_IMPULSE52 } ,
{ " _impulse53 " , UB_IMPULSE53 } ,
{ " _impulse54 " , UB_IMPULSE54 } ,
{ " _impulse55 " , UB_IMPULSE55 } ,
{ " _impulse56 " , UB_IMPULSE56 } ,
{ " _impulse57 " , UB_IMPULSE57 } ,
{ " _impulse58 " , UB_IMPULSE58 } ,
{ " _impulse59 " , UB_IMPULSE59 } ,
{ " _impulse60 " , UB_IMPULSE60 } ,
{ " _impulse61 " , UB_IMPULSE61 } ,
{ " _impulse62 " , UB_IMPULSE62 } ,
{ " _impulse63 " , UB_IMPULSE63 } ,
{ NULL , UB_NONE } ,
} ;
class buttonState_t {
public :
int on ;
bool held ;
buttonState_t ( ) { Clear ( ) ; } ;
void Clear ( void ) ;
void SetKeyState ( int keystate , bool toggle ) ;
} ;
/*
= = = = = = = = = = = = = = = =
buttonState_t : : Clear
= = = = = = = = = = = = = = = =
*/
void buttonState_t : : Clear ( void ) {
held = false ;
on = 0 ;
}
/*
= = = = = = = = = = = = = = = =
buttonState_t : : SetKeyState
= = = = = = = = = = = = = = = =
*/
void buttonState_t : : SetKeyState ( int keystate , bool toggle ) {
if ( ! toggle ) {
held = false ;
on = keystate ;
} else if ( ! keystate ) {
held = false ;
} else if ( ! held ) {
held = true ;
on ^ = 1 ;
}
}
const int NUM_USER_COMMANDS = sizeof ( userCmdStrings ) / sizeof ( userCmdString_t ) ;
const int MAX_CHAT_BUFFER = 127 ;
class idUsercmdGenLocal : public idUsercmdGen {
public :
idUsercmdGenLocal ( void ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
void Init ( void ) ;
void InitForNewMap ( void ) ;
void Shutdown ( void ) ;
void Clear ( void ) ;
void ClearAngles ( void ) ;
usercmd_t TicCmd ( int ticNumber ) ;
void InhibitUsercmd ( inhibit_t subsystem , bool inhibit ) ;
void UsercmdInterrupt ( void ) ;
int CommandStringUsercmdData ( const char * cmdString ) ;
int GetNumUserCommands ( void ) ;
const char * GetUserCommandName ( int index ) ;
void MouseState ( int * x , int * y , int * button , bool * down ) ;
int ButtonState ( int key ) ;
int KeyState ( int key ) ;
usercmd_t GetDirectUsercmd ( void ) ;
private :
void MakeCurrent ( void ) ;
void InitCurrent ( void ) ;
bool Inhibited ( void ) ;
void AdjustAngles ( void ) ;
void KeyMove ( void ) ;
2024-01-07 00:26:45 +00:00
void CircleToSquare ( float & axis_x , float & axis_y ) const ;
void HandleJoystickAxis ( int keyNum , float unclampedValue , float threshold , bool positive ) ;
2011-11-22 21:28:15 +00:00
void JoystickMove ( void ) ;
2024-01-17 05:33:06 +00:00
void JoystickFakeMouse ( float axis_x , float axis_y , float deadzone ) ;
2011-11-22 21:28:15 +00:00
void MouseMove ( void ) ;
void CmdButtons ( void ) ;
void Mouse ( void ) ;
void Keyboard ( void ) ;
void Joystick ( void ) ;
void Key ( int keyNum , bool down ) ;
2024-06-02 05:16:44 +00:00
// DG: if in_allowAlwaysRunInSP is set, you can use always run or toggle run even in SP.
// Why not, we're all adults here, if you run out of stamina it's your problem
// (though I'll probably add another CVar to disable stamina in SP)
inline bool AlwaysRunAllowed ( ) const
{
return in_allowAlwaysRunInSP . GetBool ( ) | | idAsyncNetwork : : IsActive ( ) ;
}
2011-11-22 21:28:15 +00:00
idVec3 viewangles ;
int flags ;
int impulse ;
buttonState_t toggled_crouch ;
buttonState_t toggled_run ;
buttonState_t toggled_zoom ;
int buttonState [ UB_MAX_BUTTONS ] ;
bool keyState [ K_LAST_KEY ] ;
int inhibitCommands ; // true when in console or menu locally
int lastCommandTime ;
bool initialized ;
usercmd_t cmd ; // the current cmd being built
usercmd_t buffered [ MAX_BUFFERED_USERCMD ] ;
int continuousMouseX , continuousMouseY ; // for gui event generatioin, never zerod
int mouseButton ; // for gui event generatioin
bool mouseDown ;
int mouseDx , mouseDy ; // added to by mouse events
2024-01-07 00:26:45 +00:00
float joystickAxis [ MAX_JOYSTICK_AXIS ] ; // set by joystick events
int pollTime ;
int lastPollTime ;
float lastLookValuePitch ;
float lastLookValueYaw ;
bool heldJump ; // TODO: ???
2011-11-22 21:28:15 +00:00
static idCVar in_yawSpeed ;
static idCVar in_pitchSpeed ;
static idCVar in_angleSpeedKey ;
static idCVar in_freeLook ;
2024-06-02 05:16:44 +00:00
static idCVar in_allowAlwaysRunInSP ; // DG: I don't care, I'm not a cop
2011-11-22 21:28:15 +00:00
static idCVar in_alwaysRun ;
static idCVar in_toggleRun ;
static idCVar in_toggleCrouch ;
static idCVar in_toggleZoom ;
static idCVar sensitivity ;
static idCVar m_pitch ;
static idCVar m_yaw ;
static idCVar m_strafeScale ;
static idCVar m_smooth ;
static idCVar m_strafeSmooth ;
static idCVar m_showMouseRate ;
2024-06-02 05:16:44 +00:00
static idCVar m_invertLook ; // DG: added this
2011-11-22 21:28:15 +00:00
} ;
idCVar idUsercmdGenLocal : : in_yawSpeed ( " in_yawspeed " , " 140 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT , " yaw change speed when holding down _left or _right button " ) ;
idCVar idUsercmdGenLocal : : in_pitchSpeed ( " in_pitchspeed " , " 140 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT , " pitch change speed when holding down look _lookUp or _lookDown button " ) ;
idCVar idUsercmdGenLocal : : in_angleSpeedKey ( " in_anglespeedkey " , " 1.5 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT , " angle change scale when holding down _speed button " ) ;
idCVar idUsercmdGenLocal : : in_freeLook ( " in_freeLook " , " 1 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL , " look around with mouse (reverse _mlook button) " ) ;
2024-06-02 05:16:44 +00:00
idCVar idUsercmdGenLocal : : in_allowAlwaysRunInSP ( " in_allowAlwaysRunInSP " , " 0 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL , " Allow always run and toggle run in Single Player as well - keep in mind you may run out of stamina! " ) ;
idCVar idUsercmdGenLocal : : in_alwaysRun ( " in_alwaysRun " , " 0 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL , " always run (reverse _speed button) - only in MP, unless in_allowAlwaysRunInSP is set " ) ;
idCVar idUsercmdGenLocal : : in_toggleRun ( " in_toggleRun " , " 0 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL , " pressing _speed button toggles run on/off - only in MP, unless in_allowAlwaysRunInSP is set " ) ;
2011-11-22 21:28:15 +00:00
idCVar idUsercmdGenLocal : : in_toggleCrouch ( " in_toggleCrouch " , " 0 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL , " pressing _movedown button toggles player crouching/standing " ) ;
idCVar idUsercmdGenLocal : : in_toggleZoom ( " in_toggleZoom " , " 0 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL , " pressing _zoom button toggles zoom on/off " ) ;
idCVar idUsercmdGenLocal : : sensitivity ( " sensitivity " , " 5 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT , " mouse view sensitivity " ) ;
idCVar idUsercmdGenLocal : : m_pitch ( " m_pitch " , " 0.022 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT , " mouse pitch scale " ) ;
idCVar idUsercmdGenLocal : : m_yaw ( " m_yaw " , " 0.022 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT , " mouse yaw scale " ) ;
idCVar idUsercmdGenLocal : : m_strafeScale ( " m_strafeScale " , " 6.25 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT , " mouse strafe movement scale " ) ;
idCVar idUsercmdGenLocal : : m_smooth ( " m_smooth " , " 1 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER , " number of samples blended for mouse viewing " , 1 , 8 , idCmdSystem : : ArgCompletion_Integer < 1 , 8 > ) ;
idCVar idUsercmdGenLocal : : m_strafeSmooth ( " m_strafeSmooth " , " 4 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER , " number of samples blended for mouse moving " , 1 , 8 , idCmdSystem : : ArgCompletion_Integer < 1 , 8 > ) ;
idCVar idUsercmdGenLocal : : m_showMouseRate ( " m_showMouseRate " , " 0 " , CVAR_SYSTEM | CVAR_BOOL , " shows mouse movement " ) ;
2024-06-02 05:16:44 +00:00
idCVar idUsercmdGenLocal : : m_invertLook ( " m_invertLook " , " 0 " , CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER , " invert mouse look 0: don't invert, 1: invert up/down (flight controls), 2: invert left/right, 3: invert both " , 0 , 3 , idCmdSystem : : ArgCompletion_Integer < 0 , 3 > ) ;
2011-11-22 21:28:15 +00:00
2024-01-07 00:26:45 +00:00
idCVar joy_triggerThreshold ( " joy_triggerThreshold " , " 0.05 " , CVAR_FLOAT | CVAR_ARCHIVE , " how far the joystick triggers have to be pressed before they register as down " ) ;
2024-01-17 05:33:06 +00:00
idCVar joy_deadZone ( " joy_deadZone " , " 0.25 " , CVAR_FLOAT | CVAR_ARCHIVE , " specifies how large the dead-zone is on the joystick " ) ;
2024-01-07 00:26:45 +00:00
idCVar joy_gammaLook ( " joy_gammaLook " , " 1 " , CVAR_INTEGER | CVAR_ARCHIVE , " use a log curve instead of a power curve for movement " ) ;
idCVar joy_powerScale ( " joy_powerScale " , " 2 " , CVAR_FLOAT | CVAR_ARCHIVE , " Raise joystick values to this power " ) ;
idCVar joy_pitchSpeed ( " joy_pitchSpeed " , " 130 " , CVAR_ARCHIVE | CVAR_FLOAT , " pitch speed when pressing up or down on the joystick " , 60 , 600 ) ;
idCVar joy_yawSpeed ( " joy_yawSpeed " , " 240 " , CVAR_ARCHIVE | CVAR_FLOAT , " pitch speed when pressing left or right on the joystick " , 60 , 600 ) ;
2024-01-16 16:26:45 +00:00
idCVar joy_invertLook ( " joy_invertLook " , " 0 " , CVAR_ARCHIVE | CVAR_BOOL , " inverts the look controls so the forward looks up (flight controls) - the proper way to play games ! " ) ;
2024-01-07 00:26:45 +00:00
// these were a bad idea!
idCVar joy_dampenLook ( " joy_dampenLook " , " 1 " , CVAR_BOOL | CVAR_ARCHIVE , " Do not allow full acceleration on look " ) ;
idCVar joy_deltaPerMSLook ( " joy_deltaPerMSLook " , " 0.003 " , CVAR_FLOAT | CVAR_ARCHIVE , " Max amount to be added on look per MS " ) ;
2024-01-16 16:26:45 +00:00
idCVar in_useGamepad ( " in_useGamepad " , " 1 " , CVAR_ARCHIVE | CVAR_BOOL , " enables/disables the gamepad for PC use " ) ;
// TODO idCVar in_mouseInvertLook( "in_mouseInvertLook", "0", CVAR_ARCHIVE | CVAR_BOOL, "inverts the look controls so the forward looks up (flight controls) - the proper way to play games!" );
2024-01-07 00:26:45 +00:00
2011-11-22 21:28:15 +00:00
static idUsercmdGenLocal localUsercmdGen ;
idUsercmdGen * usercmdGen = & localUsercmdGen ;
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : idUsercmdGenLocal
= = = = = = = = = = = = = = = =
*/
idUsercmdGenLocal : : idUsercmdGenLocal ( void ) {
lastCommandTime = 0 ;
initialized = false ;
flags = 0 ;
impulse = 0 ;
toggled_crouch . Clear ( ) ;
toggled_run . Clear ( ) ;
toggled_zoom . Clear ( ) ;
toggled_run . on = in_alwaysRun . GetBool ( ) ;
2024-01-22 04:50:45 +00:00
lastLookValuePitch = lastLookValueYaw = 0.0f ;
2011-11-22 21:28:15 +00:00
ClearAngles ( ) ;
Clear ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : InhibitUsercmd
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : InhibitUsercmd ( inhibit_t subsystem , bool inhibit ) {
if ( inhibit ) {
inhibitCommands | = 1 < < subsystem ;
} else {
inhibitCommands & = ( 0xffffffff ^ ( 1 < < subsystem ) ) ;
}
}
/*
= = = = = = = = = = = = = = =
idUsercmdGenLocal : : ButtonState
Returns ( the fraction of the frame ) that the key was down
= = = = = = = = = = = = = = =
*/
int idUsercmdGenLocal : : ButtonState ( int key ) {
if ( key < 0 | | key > = UB_MAX_BUTTONS ) {
return - 1 ;
}
return ( buttonState [ key ] > 0 ) ? 1 : 0 ;
}
/*
= = = = = = = = = = = = = = =
idUsercmdGenLocal : : KeyState
Returns ( the fraction of the frame ) that the key was down
bk20060111
= = = = = = = = = = = = = = =
*/
int idUsercmdGenLocal : : KeyState ( int key ) {
if ( key < 0 | | key > = K_LAST_KEY ) {
return - 1 ;
}
return ( keyState [ key ] ) ? 1 : 0 ;
}
//=====================================================================
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : GetNumUserCommands
= = = = = = = = = = = = = = = =
*/
int idUsercmdGenLocal : : GetNumUserCommands ( void ) {
return NUM_USER_COMMANDS ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : GetNumUserCommands
= = = = = = = = = = = = = = = =
*/
const char * idUsercmdGenLocal : : GetUserCommandName ( int index ) {
if ( index > = 0 & & index < NUM_USER_COMMANDS ) {
return userCmdStrings [ index ] . string ;
}
return " " ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : Inhibited
is user cmd generation inhibited
= = = = = = = = = = = = = = = =
*/
bool idUsercmdGenLocal : : Inhibited ( void ) {
return ( inhibitCommands ! = 0 ) ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : AdjustAngles
Moves the local angle positions
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : AdjustAngles ( void ) {
float speed ;
2011-12-06 18:20:15 +00:00
2024-06-02 05:16:44 +00:00
if ( toggled_run . on ^ ( in_alwaysRun . GetBool ( ) & & AlwaysRunAllowed ( ) ) ) { // DG: always run in SP
2011-11-22 21:28:15 +00:00
speed = idMath : : M_MS2SEC * USERCMD_MSEC * in_angleSpeedKey . GetFloat ( ) ;
} else {
speed = idMath : : M_MS2SEC * USERCMD_MSEC ;
}
if ( ! ButtonState ( UB_STRAFE ) ) {
viewangles [ YAW ] - = speed * in_yawSpeed . GetFloat ( ) * ButtonState ( UB_RIGHT ) ;
viewangles [ YAW ] + = speed * in_yawSpeed . GetFloat ( ) * ButtonState ( UB_LEFT ) ;
}
viewangles [ PITCH ] - = speed * in_pitchSpeed . GetFloat ( ) * ButtonState ( UB_LOOKUP ) ;
viewangles [ PITCH ] + = speed * in_pitchSpeed . GetFloat ( ) * ButtonState ( UB_LOOKDOWN ) ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : KeyMove
Sets the usercmd_t based on key states
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : KeyMove ( void ) {
int forward , side , up ;
forward = 0 ;
side = 0 ;
up = 0 ;
if ( ButtonState ( UB_STRAFE ) ) {
side + = KEY_MOVESPEED * ButtonState ( UB_RIGHT ) ;
side - = KEY_MOVESPEED * ButtonState ( UB_LEFT ) ;
}
side + = KEY_MOVESPEED * ButtonState ( UB_MOVERIGHT ) ;
side - = KEY_MOVESPEED * ButtonState ( UB_MOVELEFT ) ;
up - = KEY_MOVESPEED * toggled_crouch . on ;
up + = KEY_MOVESPEED * ButtonState ( UB_UP ) ;
forward + = KEY_MOVESPEED * ButtonState ( UB_FORWARD ) ;
forward - = KEY_MOVESPEED * ButtonState ( UB_BACK ) ;
2024-01-07 00:26:45 +00:00
// only set each movement variable if its unset at this point.
// NOTE: joystick input happens before this.
if ( cmd . forwardmove = = 0 ) {
cmd . forwardmove = idMath : : ClampChar ( forward ) ;
}
if ( cmd . rightmove = = 0 ) {
cmd . rightmove = idMath : : ClampChar ( side ) ;
}
if ( cmd . upmove = = 0 ) {
cmd . upmove = idMath : : ClampChar ( up ) ;
}
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = = = = =
idUsercmdGenLocal : : MouseMove
= = = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : MouseMove ( void ) {
float mx , my , strafeMx , strafeMy ;
static int history [ 8 ] [ 2 ] ;
static int historyCounter ;
int i ;
history [ historyCounter & 7 ] [ 0 ] = mouseDx ;
history [ historyCounter & 7 ] [ 1 ] = mouseDy ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
// allow mouse movement to be smoothed together
int smooth = m_smooth . GetInteger ( ) ;
if ( smooth < 1 ) {
smooth = 1 ;
}
if ( smooth > 8 ) {
smooth = 8 ;
}
mx = 0 ;
my = 0 ;
for ( i = 0 ; i < smooth ; i + + ) {
mx + = history [ ( historyCounter - i + 8 ) & 7 ] [ 0 ] ;
my + = history [ ( historyCounter - i + 8 ) & 7 ] [ 1 ] ;
}
mx / = smooth ;
my / = smooth ;
// use a larger smoothing for strafing
smooth = m_strafeSmooth . GetInteger ( ) ;
if ( smooth < 1 ) {
smooth = 1 ;
}
if ( smooth > 8 ) {
smooth = 8 ;
}
strafeMx = 0 ;
strafeMy = 0 ;
for ( i = 0 ; i < smooth ; i + + ) {
strafeMx + = history [ ( historyCounter - i + 8 ) & 7 ] [ 0 ] ;
strafeMy + = history [ ( historyCounter - i + 8 ) & 7 ] [ 1 ] ;
}
strafeMx / = smooth ;
strafeMy / = smooth ;
historyCounter + + ;
if ( idMath : : Fabs ( mx ) > 1000 | | idMath : : Fabs ( my ) > 1000 ) {
Sys_DebugPrintf ( " idUsercmdGenLocal::MouseMove: Ignoring ridiculous mouse delta. \n " ) ;
mx = my = 0 ;
}
mx * = sensitivity . GetFloat ( ) ;
my * = sensitivity . GetFloat ( ) ;
if ( m_showMouseRate . GetBool ( ) ) {
Sys_DebugPrintf ( " [%3i %3i = %5.1f %5.1f = %5.1f %5.1f] " , mouseDx , mouseDy , mx , my , strafeMx , strafeMy ) ;
}
mouseDx = 0 ;
mouseDy = 0 ;
if ( ! strafeMx & & ! strafeMy ) {
return ;
}
if ( ButtonState ( UB_STRAFE ) | | ! ( cmd . buttons & BUTTON_MLOOK ) ) {
// add mouse X/Y movement to cmd
strafeMx * = m_strafeScale . GetFloat ( ) ;
strafeMy * = m_strafeScale . GetFloat ( ) ;
// clamp as a vector, instead of separate floats
float len = sqrt ( strafeMx * strafeMx + strafeMy * strafeMy ) ;
if ( len > 127 ) {
strafeMx = strafeMx * 127 / len ;
strafeMy = strafeMy * 127 / len ;
}
}
if ( ! ButtonState ( UB_STRAFE ) ) {
2024-06-02 05:16:44 +00:00
// m_invertLook 2 and 3 invert looking left/right
float invYaw = ( m_invertLook . GetInteger ( ) & 2 ) ? - 1.0f : 1.0f ;
viewangles [ YAW ] - = m_yaw . GetFloat ( ) * mx * invYaw ;
2011-11-22 21:28:15 +00:00
} else {
cmd . rightmove = idMath : : ClampChar ( ( int ) ( cmd . rightmove + strafeMx ) ) ;
}
if ( ! ButtonState ( UB_STRAFE ) & & ( cmd . buttons & BUTTON_MLOOK ) ) {
2024-06-02 05:16:44 +00:00
// m_invertLook 1 and 3 invert looking up/down
float invPitch = ( m_invertLook . GetInteger ( ) & 1 ) ? - 1.0f : 1.0f ;
viewangles [ PITCH ] + = m_pitch . GetFloat ( ) * my * invPitch ;
2011-11-22 21:28:15 +00:00
} else {
cmd . forwardmove = idMath : : ClampChar ( ( int ) ( cmd . forwardmove - strafeMy ) ) ;
}
}
/*
2024-01-07 00:26:45 +00:00
= = = = = = = = = = = = = = = = = = = = = = = =
idUsercmdGenLocal : : CircleToSquare
= = = = = = = = = = = = = = = = = = = = = = = =
2011-11-22 21:28:15 +00:00
*/
2024-01-07 00:26:45 +00:00
void idUsercmdGenLocal : : CircleToSquare ( float & axis_x , float & axis_y ) const {
// bring everything in the first quadrant
bool flip_x = false ;
if ( axis_x < 0.0f ) {
flip_x = true ;
axis_x * = - 1.0f ;
}
bool flip_y = false ;
if ( axis_y < 0.0f ) {
flip_y = true ;
axis_y * = - 1.0f ;
}
2011-11-22 21:28:15 +00:00
2024-01-07 00:26:45 +00:00
// swap the two axes so we project against the vertical line X = 1
bool swap = false ;
if ( axis_y > axis_x ) {
float tmp = axis_x ;
axis_x = axis_y ;
axis_y = tmp ;
swap = true ;
2011-11-22 21:28:15 +00:00
}
2024-01-07 00:26:45 +00:00
if ( axis_x < 0.001f ) {
// on one of the axes where no correction is needed
return ;
}
// length (max 1.0f at the unit circle)
float len = idMath : : Sqrt ( axis_x * axis_x + axis_y * axis_y ) ;
if ( len > 1.0f ) {
len = 1.0f ;
}
// thales
float axis_y_us = axis_y / axis_x ;
// use a power curve to shift the correction to happen closer to the unit circle
float correctionRatio = Square ( len ) ;
axis_x + = correctionRatio * ( len - axis_x ) ;
axis_y + = correctionRatio * ( axis_y_us - axis_y ) ;
// go back through the symmetries
if ( swap ) {
float tmp = axis_x ;
axis_x = axis_y ;
axis_y = tmp ;
}
if ( flip_x ) {
axis_x * = - 1.0f ;
}
if ( flip_y ) {
axis_y * = - 1.0f ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idUsercmdGenLocal : : HandleJoystickAxis
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : HandleJoystickAxis ( int keyNum , float unclampedValue , float threshold , bool positive ) {
if ( ( unclampedValue > 0.0f ) & & ! positive ) {
return ;
}
if ( ( unclampedValue < 0.0f ) & & positive ) {
return ;
}
float value = 0.0f ;
bool pressed = false ;
if ( unclampedValue > threshold ) {
value = idMath : : Fabs ( ( unclampedValue - threshold ) / ( 1.0f - threshold ) ) ;
pressed = true ;
} else if ( unclampedValue < - threshold ) {
value = idMath : : Fabs ( ( unclampedValue + threshold ) / ( 1.0f - threshold ) ) ;
pressed = true ;
}
int action = idKeyInput : : GetUsercmdAction ( keyNum ) ;
if ( action > = UB_ATTACK ) {
Key ( keyNum , pressed ) ;
return ;
}
if ( ! pressed ) {
return ;
}
float lookValue = 0.0f ;
if ( joy_gammaLook . GetBool ( ) ) {
lookValue = idMath : : Pow ( 1.04712854805f , value * 100.0f ) * 0.01f ;
2011-11-22 21:28:15 +00:00
} else {
2024-01-07 00:26:45 +00:00
lookValue = idMath : : Pow ( value , joy_powerScale . GetFloat ( ) ) ;
}
#if 0 // TODO: aim assist maybe.
idGame * game = common - > Game ( ) ;
if ( game ! = NULL ) {
lookValue * = game - > GetAimAssistSensitivity ( ) ;
2011-11-22 21:28:15 +00:00
}
2024-01-07 00:26:45 +00:00
# endif
2011-11-22 21:28:15 +00:00
2024-01-07 00:26:45 +00:00
switch ( action ) {
case UB_FORWARD : {
float move = ( float ) cmd . forwardmove + ( KEY_MOVESPEED * value ) ;
cmd . forwardmove = idMath : : ClampChar ( idMath : : Ftoi ( move ) ) ;
break ;
}
case UB_BACK : {
float move = ( float ) cmd . forwardmove - ( KEY_MOVESPEED * value ) ;
cmd . forwardmove = idMath : : ClampChar ( idMath : : Ftoi ( move ) ) ;
break ;
}
case UB_MOVELEFT : {
float move = ( float ) cmd . rightmove - ( KEY_MOVESPEED * value ) ;
cmd . rightmove = idMath : : ClampChar ( idMath : : Ftoi ( move ) ) ;
break ;
}
case UB_MOVERIGHT : {
float move = ( float ) cmd . rightmove + ( KEY_MOVESPEED * value ) ;
cmd . rightmove = idMath : : ClampChar ( idMath : : Ftoi ( move ) ) ;
break ;
}
case UB_LOOKUP : {
if ( joy_dampenLook . GetBool ( ) ) {
lookValue = Min ( lookValue , ( pollTime - lastPollTime ) * joy_deltaPerMSLook . GetFloat ( ) + lastLookValuePitch ) ;
lastLookValuePitch = lookValue ;
}
2024-01-16 16:26:45 +00:00
float invertPitch = joy_invertLook . GetBool ( ) ? - 1.0f : 1.0f ;
2024-01-07 00:26:45 +00:00
viewangles [ PITCH ] - = MS2SEC ( pollTime - lastPollTime ) * lookValue * joy_pitchSpeed . GetFloat ( ) * invertPitch ;
break ;
}
case UB_LOOKDOWN : {
if ( joy_dampenLook . GetBool ( ) ) {
lookValue = Min ( lookValue , ( pollTime - lastPollTime ) * joy_deltaPerMSLook . GetFloat ( ) + lastLookValuePitch ) ;
lastLookValuePitch = lookValue ;
}
2024-01-16 16:26:45 +00:00
float invertPitch = joy_invertLook . GetBool ( ) ? - 1.0f : 1.0f ;
2024-01-07 00:26:45 +00:00
viewangles [ PITCH ] + = MS2SEC ( pollTime - lastPollTime ) * lookValue * joy_pitchSpeed . GetFloat ( ) * invertPitch ;
break ;
}
case UB_LEFT : {
if ( joy_dampenLook . GetBool ( ) ) {
lookValue = Min ( lookValue , ( pollTime - lastPollTime ) * joy_deltaPerMSLook . GetFloat ( ) + lastLookValueYaw ) ;
lastLookValueYaw = lookValue ;
}
viewangles [ YAW ] + = MS2SEC ( pollTime - lastPollTime ) * lookValue * joy_yawSpeed . GetFloat ( ) ;
break ;
}
case UB_RIGHT : {
if ( joy_dampenLook . GetBool ( ) ) {
lookValue = Min ( lookValue , ( pollTime - lastPollTime ) * joy_deltaPerMSLook . GetFloat ( ) + lastLookValueYaw ) ;
lastLookValueYaw = lookValue ;
}
viewangles [ YAW ] - = MS2SEC ( pollTime - lastPollTime ) * lookValue * joy_yawSpeed . GetFloat ( ) ;
break ;
}
}
}
2024-01-17 05:33:06 +00:00
static float joyAxisToMouseDelta ( float axis , float deadzone )
{
float ret = 0.0f ;
float val = fabsf ( axis ) ; // calculations below require a positive value
if ( val > deadzone ) {
// from deadzone .. 1 to 0 .. 1-deadzone
val - = deadzone ;
// and then to 0..1
val = val * ( 1.0f / ( 1.0f - deadzone ) ) ;
// make it exponential curve - exp(val*3) should return sth between 1 and 20;
// then turning that into 0.5 .. 10
ret = expf ( val * 3.0f ) * 0.5f ;
if ( axis < 0.0f ) // restore sign
ret = - ret ;
}
return ret ;
}
2024-01-17 15:47:21 +00:00
extern bool D3_IN_interactiveIngameGuiActive ; // from sys/events.cpp
2024-01-17 05:33:06 +00:00
void idUsercmdGenLocal : : JoystickFakeMouse ( float axis_x , float axis_y , float deadzone )
{
2024-01-17 15:47:21 +00:00
if ( D3_IN_interactiveIngameGuiActive ) {
float x = joyAxisToMouseDelta ( axis_x , deadzone ) ;
float y = joyAxisToMouseDelta ( axis_y , deadzone ) ;
continuousMouseX + = x ;
continuousMouseY + = y ;
}
2024-01-17 05:33:06 +00:00
}
2024-01-07 00:26:45 +00:00
/*
= = = = = = = = = = = = = = = = =
idUsercmdGenLocal : : JoystickMove
= = = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : JoystickMove ( ) {
float threshold = joy_deadZone . GetFloat ( ) ;
float triggerThreshold = joy_triggerThreshold . GetFloat ( ) ;
float axis_y = joystickAxis [ AXIS_LEFT_Y ] ;
float axis_x = joystickAxis [ AXIS_LEFT_X ] ;
CircleToSquare ( axis_x , axis_y ) ;
HandleJoystickAxis ( K_JOY_STICK1_UP , axis_y , threshold , false ) ;
HandleJoystickAxis ( K_JOY_STICK1_DOWN , axis_y , threshold , true ) ;
HandleJoystickAxis ( K_JOY_STICK1_LEFT , axis_x , threshold , false ) ;
HandleJoystickAxis ( K_JOY_STICK1_RIGHT , axis_x , threshold , true ) ;
2024-01-17 05:33:06 +00:00
JoystickFakeMouse ( axis_x , axis_y , threshold ) ;
2024-01-07 00:26:45 +00:00
axis_y = joystickAxis [ AXIS_RIGHT_Y ] ;
axis_x = joystickAxis [ AXIS_RIGHT_X ] ;
CircleToSquare ( axis_x , axis_y ) ;
HandleJoystickAxis ( K_JOY_STICK2_UP , axis_y , threshold , false ) ;
HandleJoystickAxis ( K_JOY_STICK2_DOWN , axis_y , threshold , true ) ;
HandleJoystickAxis ( K_JOY_STICK2_LEFT , axis_x , threshold , false ) ;
HandleJoystickAxis ( K_JOY_STICK2_RIGHT , axis_x , threshold , true ) ;
2024-01-17 05:33:06 +00:00
JoystickFakeMouse ( axis_x , axis_y , threshold ) ;
2024-01-07 00:26:45 +00:00
HandleJoystickAxis ( K_JOY_TRIGGER1 , joystickAxis [ AXIS_LEFT_TRIG ] , triggerThreshold , true ) ;
HandleJoystickAxis ( K_JOY_TRIGGER2 , joystickAxis [ AXIS_RIGHT_TRIG ] , triggerThreshold , true ) ;
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = =
idUsercmdGenLocal : : CmdButtons
= = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : CmdButtons ( void ) {
int i ;
cmd . buttons = 0 ;
// figure button bits
for ( i = 0 ; i < = 7 ; i + + ) {
if ( ButtonState ( ( usercmdButton_t ) ( UB_BUTTON0 + i ) ) ) {
cmd . buttons | = 1 < < i ;
}
}
// check the attack button
if ( ButtonState ( UB_ATTACK ) ) {
cmd . buttons | = BUTTON_ATTACK ;
}
// check the run button
2024-06-02 05:16:44 +00:00
if ( toggled_run . on ^ ( in_alwaysRun . GetBool ( ) & & AlwaysRunAllowed ( ) ) ) { // DG: always run in SP
2011-11-22 21:28:15 +00:00
cmd . buttons | = BUTTON_RUN ;
}
// check the zoom button
if ( toggled_zoom . on ) {
cmd . buttons | = BUTTON_ZOOM ;
}
// check the scoreboard button
if ( ButtonState ( UB_SHOWSCORES ) | | ButtonState ( UB_IMPULSE19 ) ) {
// the button is toggled in SP mode as well but without effect
cmd . buttons | = BUTTON_SCORES ;
}
// check the mouse look button
if ( ButtonState ( UB_MLOOK ) ^ in_freeLook . GetInteger ( ) ) {
cmd . buttons | = BUTTON_MLOOK ;
}
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : InitCurrent
inits the current command for this frame
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : InitCurrent ( void ) {
memset ( & cmd , 0 , sizeof ( cmd ) ) ;
cmd . flags = flags ;
cmd . impulse = impulse ;
2024-06-02 05:16:44 +00:00
cmd . buttons | = ( in_alwaysRun . GetBool ( ) & & AlwaysRunAllowed ( ) ) ? BUTTON_RUN : 0 ; // DG: always run in SP
2011-11-22 21:28:15 +00:00
cmd . buttons | = in_freeLook . GetBool ( ) ? BUTTON_MLOOK : 0 ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : MakeCurrent
creates the current command for this frame
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : MakeCurrent ( void ) {
idVec3 oldAngles ;
int i ;
oldAngles = viewangles ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( ! Inhibited ( ) ) {
// update toggled key states
toggled_crouch . SetKeyState ( ButtonState ( UB_DOWN ) , in_toggleCrouch . GetBool ( ) ) ;
2024-06-02 05:16:44 +00:00
// DG: allow toggle run in SP (of in_allowAlwaysRun is set)
toggled_run . SetKeyState ( ButtonState ( UB_SPEED ) , in_toggleRun . GetBool ( ) & & AlwaysRunAllowed ( ) ) ;
2011-11-22 21:28:15 +00:00
toggled_zoom . SetKeyState ( ButtonState ( UB_ZOOM ) , in_toggleZoom . GetBool ( ) ) ;
// keyboard angle adjustment
AdjustAngles ( ) ;
2024-01-07 00:26:45 +00:00
// get basic movement from joystick
JoystickMove ( ) ;
2011-11-22 21:28:15 +00:00
// set button bits
CmdButtons ( ) ;
// get basic movement from keyboard
KeyMove ( ) ;
// get basic movement from mouse
MouseMove ( ) ;
// check to make sure the angles haven't wrapped
if ( viewangles [ PITCH ] - oldAngles [ PITCH ] > 90 ) {
viewangles [ PITCH ] = oldAngles [ PITCH ] + 90 ;
} else if ( oldAngles [ PITCH ] - viewangles [ PITCH ] > 90 ) {
viewangles [ PITCH ] = oldAngles [ PITCH ] - 90 ;
2011-12-06 18:20:15 +00:00
}
2011-11-22 21:28:15 +00:00
} else {
mouseDx = 0 ;
mouseDy = 0 ;
}
for ( i = 0 ; i < 3 ; i + + ) {
cmd . angles [ i ] = ANGLE2SHORT ( viewangles [ i ] ) ;
}
cmd . mx = continuousMouseX ;
cmd . my = continuousMouseY ;
flags = cmd . flags ;
impulse = cmd . impulse ;
}
//=====================================================================
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : CommandStringUsercmdData
Returns the button if the command string is used by the async usercmd generator .
= = = = = = = = = = = = = = = =
*/
int idUsercmdGenLocal : : CommandStringUsercmdData ( const char * cmdString ) {
for ( userCmdString_t * ucs = userCmdStrings ; ucs - > string ; ucs + + ) {
if ( idStr : : Icmp ( cmdString , ucs - > string ) = = 0 ) {
return ucs - > button ;
}
}
return UB_NONE ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : Init
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : Init ( void ) {
initialized = true ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : InitForNewMap
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : InitForNewMap ( void ) {
flags = 0 ;
impulse = 0 ;
toggled_crouch . Clear ( ) ;
toggled_run . Clear ( ) ;
toggled_zoom . Clear ( ) ;
toggled_run . on = in_alwaysRun . GetBool ( ) ;
Clear ( ) ;
ClearAngles ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : Shutdown
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : Shutdown ( void ) {
initialized = false ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : Clear
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : Clear ( void ) {
2011-12-06 18:20:15 +00:00
// clears all key states
2011-11-22 21:28:15 +00:00
memset ( buttonState , 0 , sizeof ( buttonState ) ) ;
memset ( keyState , false , sizeof ( keyState ) ) ;
2024-01-07 00:26:45 +00:00
memset ( joystickAxis , 0 , sizeof ( joystickAxis ) ) ;
2011-11-22 21:28:15 +00:00
inhibitCommands = false ;
mouseDx = mouseDy = 0 ;
mouseButton = 0 ;
mouseDown = false ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : ClearAngles
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : ClearAngles ( void ) {
viewangles . Zero ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : TicCmd
Returns a buffered usercmd
= = = = = = = = = = = = = = = =
*/
usercmd_t idUsercmdGenLocal : : TicCmd ( int ticNumber ) {
// the packetClient code can legally ask for com_ticNumber+1, because
// it is in the async code and com_ticNumber hasn't been updated yet,
// but all other code should never ask for anything > com_ticNumber
if ( ticNumber > com_ticNumber + 1 ) {
common - > Error ( " idUsercmdGenLocal::TicCmd ticNumber > com_ticNumber " ) ;
}
if ( ticNumber < = com_ticNumber - MAX_BUFFERED_USERCMD ) {
// this can happen when something in the game code hitches badly, allowing the
// async code to overflow the buffers
//common->Printf( "warning: idUsercmdGenLocal::TicCmd ticNumber <= com_ticNumber - MAX_BUFFERED_USERCMD\n" );
}
return buffered [ ticNumber & ( MAX_BUFFERED_USERCMD - 1 ) ] ;
}
//======================================================================
/*
= = = = = = = = = = = = = = = = = = =
idUsercmdGenLocal : : Key
Handles async mouse / keyboard button actions
= = = = = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : Key ( int keyNum , bool down ) {
// Sanity check, sometimes we get double message :(
if ( keyState [ keyNum ] = = down ) {
return ;
}
keyState [ keyNum ] = down ;
int action = idKeyInput : : GetUsercmdAction ( keyNum ) ;
2024-01-07 00:26:45 +00:00
// TODO: if action == 0 return ?
2011-11-22 21:28:15 +00:00
if ( down ) {
buttonState [ action ] + + ;
if ( ! Inhibited ( ) ) {
if ( action > = UB_IMPULSE0 & & action < = UB_IMPULSE61 ) {
cmd . impulse = action - UB_IMPULSE0 ;
cmd . flags ^ = UCF_IMPULSE_SEQUENCE ;
}
}
} else {
buttonState [ action ] - - ;
// we might have one held down across an app active transition
if ( buttonState [ action ] < 0 ) {
buttonState [ action ] = 0 ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = =
idUsercmdGenLocal : : Mouse
= = = = = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : Mouse ( void ) {
int i , numEvents ;
numEvents = Sys_PollMouseInputEvents ( ) ;
if ( numEvents ) {
//
2011-12-06 18:20:15 +00:00
// Study each of the buffer elements and process them.
2011-11-22 21:28:15 +00:00
//
for ( i = 0 ; i < numEvents ; i + + ) {
int action , value ;
if ( Sys_ReturnMouseInputEvent ( i , action , value ) ) {
if ( action > = M_ACTION1 & & action < = M_ACTION8 ) {
mouseButton = K_MOUSE1 + ( action - M_ACTION1 ) ;
mouseDown = ( value ! = 0 ) ;
Key ( mouseButton , mouseDown ) ;
} else {
switch ( action ) {
case M_DELTAX :
mouseDx + = value ;
continuousMouseX + = value ;
break ;
case M_DELTAY :
mouseDy + = value ;
continuousMouseY + = value ;
break ;
case M_DELTAZ :
int key = value < 0 ? K_MWHEELDOWN : K_MWHEELUP ;
value = abs ( value ) ;
while ( value - - > 0 ) {
Key ( key , true ) ;
Key ( key , false ) ;
mouseButton = key ;
mouseDown = true ;
}
break ;
}
}
}
}
}
Sys_EndMouseInputEvents ( ) ;
}
/*
= = = = = = = = = = = = = = =
idUsercmdGenLocal : : Keyboard
= = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : Keyboard ( void ) {
int numEvents = Sys_PollKeyboardInputEvents ( ) ;
if ( numEvents ) {
//
2011-12-06 18:20:15 +00:00
// Study each of the buffer elements and process them.
2011-11-22 21:28:15 +00:00
//
int key ;
bool state ;
for ( int i = 0 ; i < numEvents ; i + + ) {
if ( Sys_ReturnKeyboardInputEvent ( i , key , state ) ) {
Key ( key , state ) ;
}
}
}
Sys_EndKeyboardInputEvents ( ) ;
}
/*
= = = = = = = = = = = = = = =
idUsercmdGenLocal : : Joystick
= = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : Joystick ( void ) {
2024-01-07 00:26:45 +00:00
int numEvents = Sys_PollJoystickInputEvents ( 0 ) ;
// Study each of the buffer elements and process them.
for ( int i = 0 ; i < numEvents ; i + + ) {
int action ;
int value ;
if ( Sys_ReturnJoystickInputEvent ( i , action , value ) ) {
2024-01-08 04:26:27 +00:00
if ( action > = J_ACTION_FIRST & & action < = J_ACTION_MAX ) {
int joyButton = K_FIRST_JOY + ( action - J_ACTION_FIRST ) ;
2024-01-07 00:26:45 +00:00
Key ( joyButton , ( value ! = 0 ) ) ;
} else if ( ( action > = J_AXIS_MIN ) & & ( action < = J_AXIS_MAX ) ) {
joystickAxis [ action - J_AXIS_MIN ] = static_cast < float > ( value ) / 32767.0f ;
} else {
//assert( !"Unknown joystick event" );
}
}
}
Sys_EndJoystickInputEvents ( ) ;
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : UsercmdInterrupt
Called asyncronously
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : UsercmdInterrupt ( void ) {
// dedicated servers won't create usercmds
if ( ! initialized ) {
return ;
}
// init the usercmd for com_ticNumber+1
InitCurrent ( ) ;
// process the system mouse events
Mouse ( ) ;
// process the system keyboard events
Keyboard ( ) ;
// process the system joystick events
2024-01-16 16:26:45 +00:00
if ( in_useGamepad . GetBool ( ) ) {
2024-01-07 00:26:45 +00:00
Joystick ( ) ;
}
2011-11-22 21:28:15 +00:00
// create the usercmd for com_ticNumber+1
MakeCurrent ( ) ;
// save a number for debugging cmdDemos and networking
cmd . sequence = com_ticNumber + 1 ;
buffered [ ( com_ticNumber + 1 ) & ( MAX_BUFFERED_USERCMD - 1 ) ] = cmd ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : MouseState
= = = = = = = = = = = = = = = =
*/
void idUsercmdGenLocal : : MouseState ( int * x , int * y , int * button , bool * down ) {
* x = continuousMouseX ;
* y = continuousMouseY ;
* button = mouseButton ;
* down = mouseDown ;
}
/*
= = = = = = = = = = = = = = = =
idUsercmdGenLocal : : GetDirectUsercmd
= = = = = = = = = = = = = = = =
*/
usercmd_t idUsercmdGenLocal : : GetDirectUsercmd ( void ) {
2024-01-07 00:26:45 +00:00
pollTime = Sys_Milliseconds ( ) ;
if ( pollTime - lastPollTime > 100 ) {
lastPollTime = pollTime - 100 ;
}
2011-11-22 21:28:15 +00:00
// initialize current usercmd
InitCurrent ( ) ;
// process the system mouse events
Mouse ( ) ;
// process the system keyboard events
Keyboard ( ) ;
// process the system joystick events
2024-01-16 16:26:45 +00:00
if ( in_useGamepad . GetBool ( ) ) {
2024-01-07 00:26:45 +00:00
Joystick ( ) ;
}
2011-11-22 21:28:15 +00:00
// create the usercmd
MakeCurrent ( ) ;
cmd . duplicateCount = 0 ;
2024-01-07 00:26:45 +00:00
lastPollTime = pollTime ;
2011-11-22 21:28:15 +00:00
return cmd ;
}