etqw-sdk/source/game/InputMode.cpp

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;
}