355 lines
16 KiB
C++
355 lines
16 KiB
C++
// Copyright (C) 2007 Id Software, Inc.
|
|
//
|
|
|
|
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#if defined( _DEBUG ) && !defined( ID_REDIRECT_NEWDELETE )
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#include "InputMode.h"
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
sdInputMode
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
/*
|
|
=======================================
|
|
ControllerClampDeadZone
|
|
=======================================
|
|
*/
|
|
float sdInputMode::ControllerClampDeadZone( float position, float threshold ) {
|
|
if ( position > threshold ) {
|
|
return ( position - threshold ) / ( 1.0f - threshold );
|
|
} else if ( position < -threshold ) {
|
|
return ( position + threshold ) / ( 1.0f - threshold );
|
|
} else {
|
|
return 0.0f;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=======================================
|
|
ControllerEvaluateCurve
|
|
=======================================
|
|
*/
|
|
float sdInputMode::ControllerEvaluateCurve( float position, float deadZone, float offset, float power ) {
|
|
const bool negative = position < 0.0f;
|
|
const float x = fabs( position );
|
|
|
|
if ( x < deadZone ) {
|
|
return 0.0f;
|
|
}
|
|
|
|
const float deadZoned = ( x - deadZone ) / ( 1.0f - deadZone );
|
|
const float powered = idMath::Pow( deadZoned, power );
|
|
const float offseted = powered * ( 1.0f - offset ) + offset;
|
|
|
|
if ( negative ) {
|
|
return -offseted;
|
|
}
|
|
|
|
return offseted;
|
|
}
|
|
|
|
/*
|
|
=======================================
|
|
Macros FTW!
|
|
=======================================
|
|
*/
|
|
|
|
//
|
|
// INPUTMODE_AXIS_DECLARE - declares all the parameters needed for one control axis
|
|
//
|
|
#define INPUTMODE_AXIS_DECLARE( className, modeName, axisName ) \
|
|
idCVar className::joy_##axisName( "in_" #modeName "_" #axisName "_joy", "1", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_PROFILE, "the joystick number used" ); \
|
|
idCVar className::axis_##axisName( "in_" #modeName "_" #axisName "_axis", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_PROFILE, "which controller axis is used" ); \
|
|
idCVar className::deadZone_##axisName( "in_" #modeName "_" #axisName "_deadZone", "0.2", CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "specifies how far large the dead-zone is on the controller axis" ); \
|
|
idCVar className::speed_##axisName( "in_" #modeName "_" #axisName "_speed", "140", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT | CVAR_PROFILE, "speed of the controller input" ); \
|
|
idCVar className::invert_##axisName( "in_" #modeName "_" #axisName "_invert", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL | CVAR_PROFILE, "inverts the axis" ); \
|
|
idCVar className::offset_##axisName( "in_" #modeName "_" #axisName "_offset", "0", CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "the step up the dead zone" ); \
|
|
idCVar className::power_##axisName( "in_" #modeName "_" #axisName "_power", "1", CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "the power of the curve after dead zone - ie acceleration" );
|
|
|
|
//
|
|
// INPUTMODE_AXIS_DECLARE_DEF_AXIS - declares all the parameters needed for one control axis,
|
|
// setting up a default axis too
|
|
#define INPUTMODE_AXIS_DECLARE_DEF_AXIS( className, modeName, axisName, defaultAxis ) \
|
|
idCVar className::joy_##axisName( "in_" #modeName "_" #axisName "_joy", "1", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_PROFILE, "the joystick number used" ); \
|
|
idCVar className::axis_##axisName( "in_" #modeName "_" #axisName "_axis", #defaultAxis, CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_PROFILE, "which controller axis is used" ); \
|
|
idCVar className::deadZone_##axisName( "in_" #modeName "_" #axisName "_deadZone", "0.2", CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "specifies how far large the dead-zone is on the controller axis" ); \
|
|
idCVar className::speed_##axisName( "in_" #modeName "_" #axisName "_speed", "140", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT | CVAR_PROFILE, "speed of the controller input" ); \
|
|
idCVar className::invert_##axisName( "in_" #modeName "_" #axisName "_invert", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL | CVAR_PROFILE, "inverts the axis" ); \
|
|
idCVar className::offset_##axisName( "in_" #modeName "_" #axisName "_offset", "0", CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "the step up the dead zone" ); \
|
|
idCVar className::power_##axisName( "in_" #modeName "_" #axisName "_power", "1", CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "the power of the curve after dead zone - ie acceleration" );
|
|
|
|
//
|
|
// INPUTMODE_AXIS_DECLARE_DEF_INVERT - declares all the parameters needed for one control axis,
|
|
// setting up a default axis & invert
|
|
#define INPUTMODE_AXIS_DECLARE_DEF_INVERT( className, modeName, axisName, defaultAxis, defaultInvert ) \
|
|
idCVar className::joy_##axisName( "in_" #modeName "_" #axisName "_joy", "1", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_PROFILE, "the joystick number used" ); \
|
|
idCVar className::axis_##axisName( "in_" #modeName "_" #axisName "_axis", #defaultAxis, CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_PROFILE, "which controller axis is used" ); \
|
|
idCVar className::deadZone_##axisName( "in_" #modeName "_" #axisName "_deadZone", "0.2", CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "specifies how far large the dead-zone is on the controller axis" ); \
|
|
idCVar className::speed_##axisName( "in_" #modeName "_" #axisName "_speed", "140", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT | CVAR_PROFILE, "speed of the controller input" ); \
|
|
idCVar className::invert_##axisName( "in_" #modeName "_" #axisName "_invert", #defaultInvert, CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL | CVAR_PROFILE, "inverts the axis" ); \
|
|
idCVar className::offset_##axisName( "in_" #modeName "_" #axisName "_offset", "0", CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "the step up the dead zone" ); \
|
|
idCVar className::power_##axisName( "in_" #modeName "_" #axisName "_power", "1", CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "the power of the curve after dead zone - ie acceleration" );
|
|
|
|
|
|
//
|
|
// INPUTMODE_AXIS_DECLARE_DEFAULTS - declares all the parameters needed for one control axis,
|
|
// setting up defaults for all values
|
|
#define INPUTMODE_AXIS_DECLARE_DEFAULTS( className, modeName, axisName, defaultAxis, defaultDeadZone, defaultSpeed, defaultInvert, defaultOffset, defaultPower ) \
|
|
idCVar className::joy_##axisName( "in_" #modeName "_" #axisName "_joy", "1", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_PROFILE, "the joystick number used" ); \
|
|
idCVar className::axis_##axisName( "in_" #modeName "_" #axisName "_axis", #defaultAxis, CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_PROFILE, "which controller axis is used" ); \
|
|
idCVar className::deadZone_##axisName( "in_" #modeName "_" #axisName "_deadZone", #defaultDeadZone, CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "specifies how far large the dead-zone is on the controller axis" ); \
|
|
idCVar className::speed_##axisName( "in_" #modeName "_" #axisName "_speed", #defaultSpeed, CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT | CVAR_PROFILE, "speed of the controller input" ); \
|
|
idCVar className::invert_##axisName( "in_" #modeName "_" #axisName "_invert", #defaultInvert, CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL | CVAR_PROFILE, "inverts the axis" ); \
|
|
idCVar className::offset_##axisName( "in_" #modeName "_" #axisName "_offset", #defaultOffset, CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "the step up the dead zone" ); \
|
|
idCVar className::power_##axisName( "in_" #modeName "_" #axisName "_power", #defaultPower, CVAR_SYSTEM | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_PROFILE, "the power of the curve after dead zone - ie acceleration" );
|
|
|
|
//
|
|
// INPUTMODE_AXIS_EVALUATE - Evaulates an axis that has been defined using the above macros
|
|
//
|
|
#define INPUTMODE_AXIS_EVALUATE( className, axisName, axes ) \
|
|
float axisName = 0.0f; \
|
|
{ \
|
|
int joystickNumber = className::joy_##axisName.GetInteger(); \
|
|
if ( joystickNumber == controllerNum ) {\
|
|
const int axisNumber = className::axis_##axisName.GetInteger(); \
|
|
if ( axisNumber != -1 ) { \
|
|
const float deadZone = className::deadZone_##axisName.GetFloat(); \
|
|
const float speed = className::speed_##axisName.GetFloat(); \
|
|
const float offset = className::offset_##axisName.GetFloat(); \
|
|
const float power = className::power_##axisName.GetFloat(); \
|
|
const bool invert = className::invert_##axisName.GetBool(); \
|
|
axisName = invert ? -axes[ axisNumber ] : axes[ axisNumber ]; \
|
|
axisName = ControllerEvaluateCurve( axisName, deadZone, offset, power ); \
|
|
axisName *= speed; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
sdInputModePlayer
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
/*
|
|
=======================================
|
|
CVars
|
|
=======================================
|
|
*/
|
|
|
|
INPUTMODE_AXIS_DECLARE_DEFAULTS( sdInputModePlayer, player, pitch , 3, 0.2, 230, 1, 0, 4 );
|
|
INPUTMODE_AXIS_DECLARE_DEFAULTS( sdInputModePlayer, player, yaw, 2, 0.2, 230, 1, 0, 4 );
|
|
INPUTMODE_AXIS_DECLARE_DEF_INVERT( sdInputModePlayer, player, forward, 1, 1 );
|
|
INPUTMODE_AXIS_DECLARE_DEF_INVERT( sdInputModePlayer, player, side, 0, 0 );
|
|
|
|
/*
|
|
=======================================
|
|
ControllerMove
|
|
=======================================
|
|
*/
|
|
void sdInputModePlayer::ControllerMove( bool doGameCallback, const int controllerNum, const float* controllerAxis, idVec3& viewAngles, usercmd_t& cmd ) {
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModePlayer, pitch, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModePlayer, forward, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModePlayer, yaw, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModePlayer, side, controllerAxis );
|
|
|
|
float angleSpeedYaw;
|
|
float angleSpeedPitch;
|
|
angleSpeedYaw = angleSpeedPitch = MS2SEC( USERCMD_MSEC );
|
|
|
|
if ( doGameCallback ) {
|
|
gameLocal.GetSensitivity( angleSpeedYaw, angleSpeedPitch );
|
|
}
|
|
|
|
yaw *= angleSpeedYaw;
|
|
pitch *= angleSpeedPitch;
|
|
|
|
viewAngles[ ROLL ] = 0.0f;
|
|
viewAngles[ YAW ] += yaw;
|
|
viewAngles[ PITCH ] += pitch;
|
|
|
|
if ( forward || side ) {
|
|
// cmd.buttons.btn.run = true;
|
|
cmd.rightmove = idMath::ClampChar( cmd.rightmove + side );
|
|
cmd.forwardmove = idMath::ClampChar( cmd.forwardmove + forward );
|
|
}
|
|
}
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
sdInputModeCar
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
/*
|
|
=======================================
|
|
CVars
|
|
=======================================
|
|
*/
|
|
|
|
INPUTMODE_AXIS_DECLARE_DEF_INVERT( sdInputModeCar, car, throttle, 1, 1 );
|
|
INPUTMODE_AXIS_DECLARE_DEF_INVERT( sdInputModeCar, car, steering, 0, 0 );
|
|
INPUTMODE_AXIS_DECLARE_DEFAULTS( sdInputModeCar, car, pitch , 3, 0.2, 230, 1, 0, 4 );
|
|
INPUTMODE_AXIS_DECLARE_DEFAULTS( sdInputModeCar, car, yaw, 2, 0.2, 230, 1, 0, 4 );
|
|
|
|
/*
|
|
=======================================
|
|
ControllerMove
|
|
=======================================
|
|
*/
|
|
void sdInputModeCar::ControllerMove( bool doGameCallback, const int controllerNum, const float* controllerAxis, idVec3& viewAngles, usercmd_t& cmd ) {
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeCar, throttle, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeCar, steering, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeCar, pitch, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeCar, yaw, controllerAxis );
|
|
|
|
float angleSpeedYaw;
|
|
float angleSpeedPitch;
|
|
angleSpeedYaw = angleSpeedPitch = MS2SEC( USERCMD_MSEC );
|
|
|
|
if ( doGameCallback ) {
|
|
gameLocal.GetSensitivity( angleSpeedYaw, angleSpeedPitch );
|
|
}
|
|
|
|
yaw *= angleSpeedYaw;
|
|
pitch *= angleSpeedPitch;
|
|
|
|
viewAngles[ ROLL ] = 0.0f;
|
|
viewAngles[ YAW ] += yaw;
|
|
viewAngles[ PITCH ] += pitch;
|
|
|
|
if ( throttle || steering ) {
|
|
// cmd.buttons.btn.run = true;
|
|
cmd.rightmove = idMath::ClampChar( steering );
|
|
cmd.forwardmove = idMath::ClampChar( cmd.forwardmove + throttle );
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
sdInputModeHeli
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
/*
|
|
=======================================
|
|
CVars
|
|
=======================================
|
|
*/
|
|
|
|
INPUTMODE_AXIS_DECLARE_DEF_INVERT( sdInputModeHeli, heli, throttle, 1, 1 );
|
|
INPUTMODE_AXIS_DECLARE_DEF_INVERT( sdInputModeHeli, heli, yaw, 0, 0 );
|
|
INPUTMODE_AXIS_DECLARE_DEF_INVERT( sdInputModeHeli, heli, forward, 3, 0 );
|
|
INPUTMODE_AXIS_DECLARE_DEF_INVERT( sdInputModeHeli, heli, side, 2, 1 );
|
|
|
|
/*
|
|
=======================================
|
|
ControllerMove
|
|
=======================================
|
|
*/
|
|
void sdInputModeHeli::ControllerMove( bool doGameCallback, const int controllerNum, const float* controllerAxis, idVec3& viewAngles, usercmd_t& cmd ) {
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeHeli, throttle, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeHeli, yaw, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeHeli, forward, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeHeli, side, controllerAxis );
|
|
|
|
float angleSpeedYaw;
|
|
float angleSpeedPitch;
|
|
angleSpeedYaw = angleSpeedPitch = MS2SEC( USERCMD_MSEC );
|
|
|
|
if ( doGameCallback ) {
|
|
gameLocal.GetSensitivity( angleSpeedYaw, angleSpeedPitch );
|
|
}
|
|
|
|
side *= angleSpeedYaw;
|
|
forward *= angleSpeedPitch;
|
|
|
|
viewAngles[ ROLL ] = 0.0f;
|
|
viewAngles[ YAW ] += side;
|
|
viewAngles[ PITCH ] += forward;
|
|
|
|
if ( throttle || yaw ) {
|
|
cmd.buttons.btn.run = true;
|
|
cmd.rightmove = idMath::ClampChar( cmd.rightmove + yaw );
|
|
cmd.forwardmove = idMath::ClampChar( cmd.forwardmove + throttle );
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
sdInputModeHovertank
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
/*
|
|
=======================================
|
|
CVars
|
|
=======================================
|
|
*/
|
|
|
|
INPUTMODE_AXIS_DECLARE_DEF_INVERT( sdInputModeHovertank, hovertank, forward, 1, 1 );
|
|
INPUTMODE_AXIS_DECLARE_DEF_INVERT( sdInputModeHovertank, hovertank, turn, 0, 0 );
|
|
INPUTMODE_AXIS_DECLARE_DEFAULTS( sdInputModeHovertank, hovertank, pitch , 3, 0.2, 230, 1, 0, 4 );
|
|
INPUTMODE_AXIS_DECLARE_DEFAULTS( sdInputModeHovertank, hovertank, yaw, 2, 0.2, 230, 1, 0, 4 );
|
|
INPUTMODE_AXIS_DECLARE_DEF_AXIS( sdInputModeHovertank, hovertank, side, -1 );
|
|
|
|
|
|
/*
|
|
=======================================
|
|
ControllerMove
|
|
=======================================
|
|
*/
|
|
void sdInputModeHovertank::ControllerMove( bool doGameCallback, const int controllerNum, const float* controllerAxis, idVec3& viewAngles, usercmd_t& cmd ) {
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeHovertank, forward, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeHovertank, side, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeHovertank, turn, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeHovertank, pitch, controllerAxis );
|
|
INPUTMODE_AXIS_EVALUATE( sdInputModeHovertank, yaw, controllerAxis );
|
|
|
|
float angleSpeedYaw;
|
|
float angleSpeedPitch;
|
|
angleSpeedYaw = angleSpeedPitch = MS2SEC( USERCMD_MSEC );
|
|
|
|
if ( doGameCallback ) {
|
|
gameLocal.GetSensitivity( angleSpeedYaw, angleSpeedPitch );
|
|
}
|
|
|
|
yaw *= angleSpeedYaw;
|
|
pitch *= angleSpeedPitch;
|
|
|
|
viewAngles[ ROLL ] = 0.0f;
|
|
viewAngles[ YAW ] += yaw;
|
|
viewAngles[ PITCH ] += pitch;
|
|
|
|
if ( forward || turn ) {
|
|
cmd.buttons.btn.run = true;
|
|
cmd.rightmove = idMath::ClampChar( cmd.rightmove + turn );
|
|
cmd.forwardmove = idMath::ClampChar( cmd.forwardmove + forward );
|
|
}
|
|
|
|
cmd.buttons.btn.leanLeft |= side < 0.0f;
|
|
cmd.buttons.btn.leanRight |= side > 0.0f;
|
|
}
|
|
|