2019-04-13 16:21:56 +00:00
/* Copyright (C) 2019 Mr Goldberg
This file is part of the Goldberg Emulator
The Goldberg Emulator is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 3 of the License , or ( at your option ) any later version .
The Goldberg Emulator 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
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
License along with the Goldberg Emulator ; if not , see
< http : //www.gnu.org/licenses/>. */
# include "base.h"
2019-09-10 18:54:54 +00:00
# include "../controller/gamepad.h"
# include <cctype>
struct Controller_Map {
std : : map < ControllerDigitalActionHandle_t , std : : set < int > > active_digital ;
std : : map < ControllerAnalogActionHandle_t , std : : pair < std : : set < int > , enum EInputSourceMode > > active_analog ;
} ;
struct Controller_Action {
ControllerHandle_t controller_handle ;
struct Controller_Map active_map ;
ControllerDigitalActionHandle_t active_set ;
Controller_Action ( ControllerHandle_t controller_handle ) {
this - > controller_handle = controller_handle ;
}
void activate_action_set ( ControllerDigitalActionHandle_t active_set , std : : map < ControllerActionSetHandle_t , struct Controller_Map > & controller_maps ) {
auto map = controller_maps . find ( active_set ) ;
if ( map = = controller_maps . end ( ) ) return ;
this - > active_set = active_set ;
this - > active_map = map - > second ;
}
std : : set < int > button_id ( ControllerDigitalActionHandle_t handle ) {
auto a = active_map . active_digital . find ( handle ) ;
if ( a = = active_map . active_digital . end ( ) ) return { } ;
return a - > second ;
}
std : : pair < std : : set < int > , enum EInputSourceMode > analog_id ( ControllerAnalogActionHandle_t handle ) {
auto a = active_map . active_analog . find ( handle ) ;
if ( a = = active_map . active_analog . end ( ) ) return std : : pair < std : : set < int > , enum EInputSourceMode > ( { } , k_EInputSourceMode_None ) ;
return a - > second ;
}
} ;
enum EXTRA_GAMEPAD_BUTTONS {
BUTTON_LTRIGGER = BUTTON_COUNT + 1 ,
BUTTON_RTRIGGER = BUTTON_COUNT + 2 ,
BUTTON_STICK_LEFT_UP = BUTTON_COUNT + 3 ,
BUTTON_STICK_LEFT_DOWN = BUTTON_COUNT + 4 ,
BUTTON_STICK_LEFT_LEFT = BUTTON_COUNT + 5 ,
BUTTON_STICK_LEFT_RIGHT = BUTTON_COUNT + 6 ,
BUTTON_STICK_RIGHT_UP = BUTTON_COUNT + 7 ,
BUTTON_STICK_RIGHT_DOWN = BUTTON_COUNT + 8 ,
BUTTON_STICK_RIGHT_LEFT = BUTTON_COUNT + 9 ,
BUTTON_STICK_RIGHT_RIGHT = BUTTON_COUNT + 10 ,
} ;
2019-04-13 16:21:56 +00:00
2019-09-14 21:24:05 +00:00
# define JOY_ID_START 10
2019-04-13 16:21:56 +00:00
class Steam_Controller :
public ISteamController001 ,
public ISteamController003 ,
public ISteamController004 ,
public ISteamController005 ,
public ISteamController006 ,
public ISteamController ,
public ISteamInput
{
2019-09-10 18:54:54 +00:00
class Settings * settings ;
class SteamCallResults * callback_results ;
class SteamCallBacks * callbacks ;
class RunEveryRunCB * run_every_runcb ;
std : : map < std : : string , int > button_strings = {
{ " DUP " , BUTTON_DPAD_UP } ,
{ " DDOWN " , BUTTON_DPAD_DOWN } ,
{ " DLEFT " , BUTTON_DPAD_LEFT } ,
{ " DRIGHT " , BUTTON_DPAD_RIGHT } ,
{ " START " , BUTTON_START } ,
{ " BACK " , BUTTON_BACK } ,
{ " LSTICK " , BUTTON_LEFT_THUMB } ,
{ " RSTICK " , BUTTON_RIGHT_THUMB } ,
{ " LBUMPER " , BUTTON_LEFT_SHOULDER } ,
{ " RBUMPER " , BUTTON_RIGHT_SHOULDER } ,
{ " A " , BUTTON_A } ,
{ " B " , BUTTON_B } ,
{ " X " , BUTTON_X } ,
{ " Y " , BUTTON_Y } ,
{ " DLTRIGGER " , BUTTON_LTRIGGER } ,
{ " DRTRIGGER " , BUTTON_RTRIGGER } ,
{ " DLJOYUP " , BUTTON_STICK_LEFT_UP } ,
{ " DLJOYDOWN " , BUTTON_STICK_LEFT_DOWN } ,
{ " DLJOYLEFT " , BUTTON_STICK_LEFT_LEFT } ,
{ " DLJOYRIGHT " , BUTTON_STICK_LEFT_RIGHT } ,
{ " DRJOYUP " , BUTTON_STICK_RIGHT_UP } ,
{ " DRJOYDOWN " , BUTTON_STICK_RIGHT_DOWN } ,
{ " DRJOYLEFT " , BUTTON_STICK_RIGHT_LEFT } ,
{ " DRJOYRIGHT " , BUTTON_STICK_RIGHT_RIGHT } ,
} ;
std : : map < std : : string , int > analog_strings = {
{ " LTRIGGER " , TRIGGER_LEFT } ,
{ " RTRIGGER " , TRIGGER_RIGHT } ,
2019-09-14 21:24:05 +00:00
{ " LJOY " , STICK_LEFT + JOY_ID_START } ,
{ " RJOY " , STICK_RIGHT + JOY_ID_START } ,
2019-09-10 18:54:54 +00:00
} ;
std : : map < std : : string , enum EInputSourceMode > analog_input_modes = {
{ " joystick_move " , k_EInputSourceMode_JoystickMove } ,
{ " joystick_camera " , k_EInputSourceMode_JoystickCamera } ,
{ " trigger " , k_EInputSourceMode_Trigger } ,
} ;
std : : map < std : : string , ControllerActionSetHandle_t > action_handles ;
std : : map < std : : string , ControllerDigitalActionHandle_t > digital_action_handles ;
std : : map < std : : string , ControllerAnalogActionHandle_t > analog_action_handles ;
std : : map < ControllerActionSetHandle_t , struct Controller_Map > controller_maps ;
std : : map < ControllerHandle_t , struct Controller_Action > controllers ;
bool disabled ;
void set_handles ( std : : map < std : : string , std : : map < std : : string , std : : pair < std : : set < std : : string > , std : : string > > > action_sets ) {
uint64 handle_num = 1 ;
for ( auto & set : action_sets ) {
ControllerActionSetHandle_t action_handle_num = handle_num ;
+ + handle_num ;
action_handles [ set . first ] = action_handle_num ;
for ( auto & config_key : set . second ) {
uint64 current_handle_num = handle_num ;
+ + handle_num ;
for ( auto & button_string : config_key . second . first ) {
auto digital = button_strings . find ( button_string ) ;
if ( digital ! = button_strings . end ( ) ) {
ControllerDigitalActionHandle_t digital_handle_num = current_handle_num ;
2019-09-11 13:08:05 +00:00
if ( digital_action_handles . find ( config_key . first ) = = digital_action_handles . end ( ) ) {
digital_action_handles [ config_key . first ] = digital_handle_num ;
} else {
digital_handle_num = digital_action_handles [ config_key . first ] ;
}
2019-09-10 18:54:54 +00:00
controller_maps [ action_handle_num ] . active_digital [ digital_handle_num ] . insert ( digital - > second ) ;
} else {
auto analog = analog_strings . find ( button_string ) ;
if ( analog ! = analog_strings . end ( ) ) {
ControllerAnalogActionHandle_t analog_handle_num = current_handle_num ;
enum EInputSourceMode source_mode ;
if ( analog - > second = = TRIGGER_LEFT | | analog - > second = = TRIGGER_RIGHT ) {
source_mode = k_EInputSourceMode_Trigger ;
} else {
source_mode = k_EInputSourceMode_JoystickMove ;
}
auto input_mode = analog_input_modes . find ( config_key . second . second ) ;
if ( input_mode ! = analog_input_modes . end ( ) ) {
source_mode = input_mode - > second ;
}
2019-09-11 13:08:05 +00:00
if ( analog_action_handles . find ( config_key . first ) = = analog_action_handles . end ( ) ) {
analog_action_handles [ config_key . first ] = analog_handle_num ;
} else {
analog_handle_num = analog_action_handles [ config_key . first ] ;
}
2019-09-10 18:54:54 +00:00
controller_maps [ action_handle_num ] . active_analog [ analog_handle_num ] . first . insert ( analog - > second ) ;
controller_maps [ action_handle_num ] . active_analog [ analog_handle_num ] . second = source_mode ;
} else {
PRINT_DEBUG ( " Did not recognize controller button %s \n " , button_string . c_str ( ) ) ;
continue ;
}
}
}
}
}
}
2019-04-13 16:21:56 +00:00
public :
2019-09-10 18:54:54 +00:00
static void steam_run_every_runcb ( void * object )
{
PRINT_DEBUG ( " steam_controller_run_every_runcb \n " ) ;
Steam_Controller * steam_controller = ( Steam_Controller * ) object ;
steam_controller - > RunCallbacks ( ) ;
}
Steam_Controller ( class Settings * settings , class SteamCallResults * callback_results , class SteamCallBacks * callbacks , class RunEveryRunCB * run_every_runcb )
{
this - > settings = settings ;
this - > run_every_runcb = run_every_runcb ;
this - > run_every_runcb - > add ( & Steam_Controller : : steam_run_every_runcb , this ) ;
this - > callback_results = callback_results ;
this - > callbacks = callbacks ;
set_handles ( settings - > controller_settings . action_sets ) ;
disabled = ! action_handles . size ( ) ;
}
~ Steam_Controller ( )
{
//TODO rm network callbacks
this - > run_every_runcb - > remove ( & Steam_Controller : : steam_run_every_runcb , this ) ;
}
2019-04-13 16:21:56 +00:00
// Init and Shutdown must be called when starting/ending use of this interface
bool Init ( )
{
PRINT_DEBUG ( " Steam_Controller::Init() \n " ) ;
2019-09-10 18:54:54 +00:00
std : : lock_guard < std : : recursive_mutex > lock ( global_mutex ) ;
if ( disabled ) {
return true ;
}
GamepadInit ( ) ;
GamepadUpdate ( ) ;
for ( int i = 1 ; i < 5 ; + + i ) {
2019-09-14 22:32:26 +00:00
struct Controller_Action cont_action ( i ) ;
//Activate the action set if there is only one present.
//TODO: I don't know if one gets activated by default when there's more than one
if ( action_handles . size ( ) = = 1 ) {
cont_action . activate_action_set ( action_handles . begin ( ) - > second , controller_maps ) ;
}
controllers . insert ( std : : pair < ControllerHandle_t , struct Controller_Action > ( i , cont_action ) ) ;
2019-09-10 18:54:54 +00:00
}
2019-04-13 16:21:56 +00:00
return true ;
}
bool Init ( const char * pchAbsolutePathToControllerConfigVDF )
{
PRINT_DEBUG ( " Steam_Controller::Init() old \n " ) ;
return Init ( ) ;
}
bool Shutdown ( )
{
PRINT_DEBUG ( " Steam_Controller::Shutdown() \n " ) ;
2019-09-10 18:54:54 +00:00
std : : lock_guard < std : : recursive_mutex > lock ( global_mutex ) ;
if ( disabled ) {
return true ;
}
GamepadShutdown ( ) ;
2019-04-13 16:21:56 +00:00
return true ;
}
void SetOverrideMode ( const char * pchMode )
{
PRINT_DEBUG ( " Steam_Controller::SetOverrideMode \n " ) ;
}
// Synchronize API state with the latest Steam Controller inputs available. This
// is performed automatically by SteamAPI_RunCallbacks, but for the absolute lowest
// possible latency, you call this directly before reading controller state.
void RunFrame ( )
{
PRINT_DEBUG ( " Steam_Controller::RunFrame() \n " ) ;
2019-09-10 18:54:54 +00:00
if ( disabled ) {
return ;
}
GamepadUpdate ( ) ;
2019-04-13 16:21:56 +00:00
}
bool GetControllerState ( uint32 unControllerIndex , SteamControllerState001_t * pState )
{
PRINT_DEBUG ( " Steam_Controller::GetControllerState() \n " ) ;
return false ;
}
// Enumerate currently connected controllers
// handlesOut should point to a STEAM_CONTROLLER_MAX_COUNT sized array of ControllerHandle_t handles
// Returns the number of handles written to handlesOut
int GetConnectedControllers ( ControllerHandle_t * handlesOut )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetConnectedControllers \n " ) ;
if ( ! handlesOut ) return 0 ;
if ( disabled ) {
return 0 ;
}
int count = 0 ;
if ( GamepadIsConnected ( GAMEPAD_0 ) ) { * handlesOut = GAMEPAD_0 + 1 ; + + handlesOut ; + + count ; } ;
if ( GamepadIsConnected ( GAMEPAD_1 ) ) { * handlesOut = GAMEPAD_1 + 1 ; + + handlesOut ; + + count ; } ;
if ( GamepadIsConnected ( GAMEPAD_2 ) ) { * handlesOut = GAMEPAD_2 + 1 ; + + handlesOut ; + + count ; } ;
if ( GamepadIsConnected ( GAMEPAD_3 ) ) { * handlesOut = GAMEPAD_3 + 1 ; + + handlesOut ; + + count ; } ;
PRINT_DEBUG ( " returned %i connected controllers \n " , count ) ;
return count ;
2019-04-13 16:21:56 +00:00
}
// Invokes the Steam overlay and brings up the binding screen
// Returns false is overlay is disabled / unavailable, or the user is not in Big Picture mode
bool ShowBindingPanel ( ControllerHandle_t controllerHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::ShowBindingPanel \n " ) ;
2019-04-13 16:21:56 +00:00
return false ;
}
// ACTION SETS
// Lookup the handle for an Action Set. Best to do this once on startup, and store the handles for all future API calls.
ControllerActionSetHandle_t GetActionSetHandle ( const char * pszActionSetName )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetActionSetHandle %s \n " , pszActionSetName ) ;
if ( ! pszActionSetName ) return 0 ;
std : : string upper_action_name ( pszActionSetName ) ;
std : : transform ( upper_action_name . begin ( ) , upper_action_name . end ( ) , upper_action_name . begin ( ) , [ ] ( unsigned char c ) { return std : : toupper ( c ) ; } ) ;
auto set_handle = action_handles . find ( upper_action_name ) ;
if ( set_handle = = action_handles . end ( ) ) return 0 ;
return set_handle - > second ;
2019-04-13 16:21:56 +00:00
}
// Reconfigure the controller to use the specified action set (ie 'Menu', 'Walk' or 'Drive')
// This is cheap, and can be safely called repeatedly. It's often easier to repeatedly call it in
// your state loops, instead of trying to place it in all of your state transitions.
void ActivateActionSet ( ControllerHandle_t controllerHandle , ControllerActionSetHandle_t actionSetHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::ActivateActionSet %llu %llu \n " , controllerHandle , actionSetHandle ) ;
2019-09-14 21:24:05 +00:00
if ( controllerHandle = = STEAM_CONTROLLER_HANDLE_ALL_CONTROLLERS ) {
for ( auto & c : controllers ) {
c . second . activate_action_set ( actionSetHandle , controller_maps ) ;
}
}
2019-09-10 18:54:54 +00:00
auto controller = controllers . find ( controllerHandle ) ;
if ( controller = = controllers . end ( ) ) return ;
controller - > second . activate_action_set ( actionSetHandle , controller_maps ) ;
2019-04-13 16:21:56 +00:00
}
ControllerActionSetHandle_t GetCurrentActionSet ( ControllerHandle_t controllerHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetCurrentActionSet %llu \n " , controllerHandle ) ;
auto controller = controllers . find ( controllerHandle ) ;
if ( controller = = controllers . end ( ) ) return 0 ;
return controller - > second . active_set ;
2019-04-13 16:21:56 +00:00
}
void ActivateActionSetLayer ( ControllerHandle_t controllerHandle , ControllerActionSetHandle_t actionSetLayerHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::ActivateActionSetLayer \n " ) ;
2019-04-13 16:21:56 +00:00
}
void DeactivateActionSetLayer ( ControllerHandle_t controllerHandle , ControllerActionSetHandle_t actionSetLayerHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::DeactivateActionSetLayer \n " ) ;
2019-04-13 16:21:56 +00:00
}
void DeactivateAllActionSetLayers ( ControllerHandle_t controllerHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::DeactivateAllActionSetLayers \n " ) ;
2019-04-13 16:21:56 +00:00
}
int GetActiveActionSetLayers ( ControllerHandle_t controllerHandle , ControllerActionSetHandle_t * handlesOut )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetActiveActionSetLayers \n " ) ;
2019-04-13 16:21:56 +00:00
return 0 ;
}
// ACTIONS
// Lookup the handle for a digital action. Best to do this once on startup, and store the handles for all future API calls.
ControllerDigitalActionHandle_t GetDigitalActionHandle ( const char * pszActionName )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetDigitalActionHandle %s \n " , pszActionName ) ;
if ( ! pszActionName ) return 0 ;
std : : string upper_action_name ( pszActionName ) ;
std : : transform ( upper_action_name . begin ( ) , upper_action_name . end ( ) , upper_action_name . begin ( ) , [ ] ( unsigned char c ) { return std : : toupper ( c ) ; } ) ;
auto handle = digital_action_handles . find ( upper_action_name ) ;
if ( handle = = digital_action_handles . end ( ) ) return 0 ;
return handle - > second ;
2019-04-13 16:21:56 +00:00
}
// Returns the current state of the supplied digital game action
ControllerDigitalActionData_t GetDigitalActionData ( ControllerHandle_t controllerHandle , ControllerDigitalActionHandle_t digitalActionHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetDigitalActionData %llu %llu \n " , controllerHandle , digitalActionHandle ) ;
2019-04-13 16:21:56 +00:00
ControllerDigitalActionData_t digitalData ;
digitalData . bActive = false ;
2019-09-10 18:54:54 +00:00
digitalData . bState = false ;
auto controller = controllers . find ( controllerHandle ) ;
if ( controller = = controllers . end ( ) ) return digitalData ;
std : : set < int > buttons = controller - > second . button_id ( digitalActionHandle ) ;
if ( ! buttons . size ( ) ) return digitalData ;
digitalData . bActive = true ;
GAMEPAD_DEVICE device = ( GAMEPAD_DEVICE ) ( controllerHandle - 1 ) ;
for ( auto button : buttons ) {
bool pressed = false ;
if ( button < BUTTON_COUNT ) {
pressed = GamepadButtonDown ( device , ( GAMEPAD_BUTTON ) button ) ;
} else {
switch ( button ) {
case BUTTON_LTRIGGER :
pressed = GamepadTriggerLength ( device , TRIGGER_LEFT ) > 0.8 ;
break ;
case BUTTON_RTRIGGER :
pressed = GamepadTriggerLength ( device , TRIGGER_RIGHT ) > 0.8 ;
break ;
case BUTTON_STICK_LEFT_UP :
case BUTTON_STICK_LEFT_DOWN :
case BUTTON_STICK_LEFT_LEFT :
case BUTTON_STICK_LEFT_RIGHT :
pressed = GamepadStickLength ( device , STICK_LEFT ) > 0.1 & &
( ( int ) GamepadStickDir ( device , STICK_LEFT ) = = ( ( button - BUTTON_STICK_LEFT_UP ) + 1 ) ) ;
break ;
case BUTTON_STICK_RIGHT_UP :
case BUTTON_STICK_RIGHT_DOWN :
case BUTTON_STICK_RIGHT_LEFT :
case BUTTON_STICK_RIGHT_RIGHT :
pressed = GamepadStickLength ( device , STICK_RIGHT ) > 0.1 & &
( ( int ) GamepadStickDir ( device , STICK_RIGHT ) = = ( ( button - BUTTON_STICK_RIGHT_UP ) + 1 ) ) ;
break ;
default :
break ;
}
}
if ( pressed ) {
digitalData . bState = true ;
break ;
}
}
2019-04-13 16:21:56 +00:00
return digitalData ;
}
// Get the origin(s) for a digital action within an action set. Returns the number of origins supplied in originsOut. Use this to display the appropriate on-screen prompt for the action.
// originsOut should point to a STEAM_CONTROLLER_MAX_ORIGINS sized array of EControllerActionOrigin handles
int GetDigitalActionOrigins ( ControllerHandle_t controllerHandle , ControllerActionSetHandle_t actionSetHandle , ControllerDigitalActionHandle_t digitalActionHandle , EControllerActionOrigin * originsOut )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetDigitalActionOrigins \n " ) ;
2019-09-14 21:24:05 +00:00
EInputActionOrigin origins [ STEAM_CONTROLLER_MAX_ORIGINS ] ;
int ret = GetDigitalActionOrigins ( controllerHandle , actionSetHandle , digitalActionHandle , origins ) ;
for ( int i = 0 ; i < ret ; + + i ) {
2019-09-20 10:14:08 +00:00
originsOut [ i ] = ( EControllerActionOrigin ) ( origins [ i ] - ( k_EInputActionOrigin_XBox360_A - k_EControllerActionOrigin_XBox360_A ) ) ;
2019-09-14 21:24:05 +00:00
}
return ret ;
2019-04-13 16:21:56 +00:00
}
int GetDigitalActionOrigins ( InputHandle_t inputHandle , InputActionSetHandle_t actionSetHandle , InputDigitalActionHandle_t digitalActionHandle , EInputActionOrigin * originsOut )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetDigitalActionOrigins steaminput \n " ) ;
2019-09-14 21:24:05 +00:00
auto controller = controllers . find ( inputHandle ) ;
if ( controller = = controllers . end ( ) ) return 0 ;
auto map = controller_maps . find ( actionSetHandle ) ;
if ( map = = controller_maps . end ( ) ) return 0 ;
auto a = map - > second . active_digital . find ( digitalActionHandle ) ;
if ( a = = map - > second . active_digital . end ( ) ) return 0 ;
int count = 0 ;
for ( auto button : a - > second ) {
switch ( button ) {
case BUTTON_A :
originsOut [ count ] = k_EInputActionOrigin_XBox360_A ;
break ;
case BUTTON_B :
originsOut [ count ] = k_EInputActionOrigin_XBox360_B ;
break ;
case BUTTON_X :
originsOut [ count ] = k_EInputActionOrigin_XBox360_X ;
break ;
case BUTTON_Y :
originsOut [ count ] = k_EInputActionOrigin_XBox360_Y ;
break ;
case BUTTON_LEFT_SHOULDER :
originsOut [ count ] = k_EInputActionOrigin_XBox360_LeftBumper ;
break ;
case BUTTON_RIGHT_SHOULDER :
originsOut [ count ] = k_EInputActionOrigin_XBox360_RightBumper ;
break ;
case BUTTON_START :
originsOut [ count ] = k_EInputActionOrigin_XBox360_Start ;
break ;
case BUTTON_BACK :
originsOut [ count ] = k_EInputActionOrigin_XBox360_Back ;
break ;
case BUTTON_LTRIGGER :
originsOut [ count ] = k_EInputActionOrigin_XBox360_LeftTrigger_Click ;
break ;
case BUTTON_RTRIGGER :
originsOut [ count ] = k_EInputActionOrigin_XBox360_RightTrigger_Click ;
break ;
case BUTTON_LEFT_THUMB :
originsOut [ count ] = k_EInputActionOrigin_XBox360_LeftStick_Click ;
break ;
case BUTTON_RIGHT_THUMB :
originsOut [ count ] = k_EInputActionOrigin_XBox360_RightStick_Click ;
break ;
case BUTTON_STICK_LEFT_UP :
originsOut [ count ] = k_EInputActionOrigin_XBox360_LeftStick_DPadNorth ;
break ;
case BUTTON_STICK_LEFT_DOWN :
originsOut [ count ] = k_EInputActionOrigin_XBox360_LeftStick_DPadSouth ;
break ;
case BUTTON_STICK_LEFT_LEFT :
originsOut [ count ] = k_EInputActionOrigin_XBox360_LeftStick_DPadWest ;
break ;
case BUTTON_STICK_LEFT_RIGHT :
originsOut [ count ] = k_EInputActionOrigin_XBox360_LeftStick_DPadEast ;
break ;
case BUTTON_STICK_RIGHT_UP :
originsOut [ count ] = k_EInputActionOrigin_XBox360_RightStick_DPadNorth ;
break ;
case BUTTON_STICK_RIGHT_DOWN :
originsOut [ count ] = k_EInputActionOrigin_XBox360_RightStick_DPadSouth ;
break ;
case BUTTON_STICK_RIGHT_LEFT :
originsOut [ count ] = k_EInputActionOrigin_XBox360_RightStick_DPadWest ;
break ;
case BUTTON_STICK_RIGHT_RIGHT :
originsOut [ count ] = k_EInputActionOrigin_XBox360_RightStick_DPadEast ;
break ;
case BUTTON_DPAD_UP :
originsOut [ count ] = k_EInputActionOrigin_XBox360_DPad_North ;
break ;
case BUTTON_DPAD_DOWN :
originsOut [ count ] = k_EInputActionOrigin_XBox360_DPad_South ;
break ;
case BUTTON_DPAD_LEFT :
originsOut [ count ] = k_EInputActionOrigin_XBox360_DPad_West ;
break ;
case BUTTON_DPAD_RIGHT :
originsOut [ count ] = k_EInputActionOrigin_XBox360_DPad_East ;
break ;
default :
originsOut [ count ] = k_EInputActionOrigin_None ;
break ;
}
+ + count ;
if ( count > = STEAM_INPUT_MAX_ORIGINS ) {
break ;
}
}
return count ;
2019-04-13 16:21:56 +00:00
}
// Lookup the handle for an analog action. Best to do this once on startup, and store the handles for all future API calls.
ControllerAnalogActionHandle_t GetAnalogActionHandle ( const char * pszActionName )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetAnalogActionHandle %s \n " , pszActionName ) ;
if ( ! pszActionName ) return 0 ;
std : : string upper_action_name ( pszActionName ) ;
std : : transform ( upper_action_name . begin ( ) , upper_action_name . end ( ) , upper_action_name . begin ( ) , [ ] ( unsigned char c ) { return std : : toupper ( c ) ; } ) ;
auto handle = analog_action_handles . find ( upper_action_name ) ;
if ( handle = = analog_action_handles . end ( ) ) return 0 ;
return handle - > second ;
2019-04-13 16:21:56 +00:00
}
// Returns the current state of these supplied analog game action
ControllerAnalogActionData_t GetAnalogActionData ( ControllerHandle_t controllerHandle , ControllerAnalogActionHandle_t analogActionHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetAnalogActionData %llu %llu \n " , controllerHandle , analogActionHandle ) ;
2019-04-13 16:21:56 +00:00
ControllerAnalogActionData_t data ;
data . eMode = k_EInputSourceMode_None ;
data . x = data . y = 0 ;
data . bActive = false ;
2019-09-10 18:54:54 +00:00
auto controller = controllers . find ( controllerHandle ) ;
if ( controller = = controllers . end ( ) ) return data ;
auto analog = controller - > second . analog_id ( analogActionHandle ) ;
if ( ! analog . first . size ( ) ) return data ;
data . bActive = true ;
data . eMode = analog . second ;
for ( auto a : analog . first ) {
2019-09-14 21:24:05 +00:00
if ( a > = JOY_ID_START ) {
int joystick_id = a - JOY_ID_START ;
2019-09-10 18:54:54 +00:00
GamepadStickNormXY ( ( GAMEPAD_DEVICE ) ( controllerHandle - 1 ) , ( GAMEPAD_STICK ) joystick_id , & data . x , & data . y ) ;
2019-09-12 11:21:11 +00:00
float length = GamepadStickLength ( ( GAMEPAD_DEVICE ) ( controllerHandle - 1 ) , ( GAMEPAD_STICK ) joystick_id ) ;
data . x = data . x * length ;
data . y = data . y * length ;
2019-09-10 18:54:54 +00:00
} else {
data . x = GamepadTriggerLength ( ( GAMEPAD_DEVICE ) ( controllerHandle - 1 ) , ( GAMEPAD_TRIGGER ) a ) ;
}
2019-09-12 11:21:11 +00:00
if ( data . x | | data . y ) {
break ;
}
2019-09-10 18:54:54 +00:00
}
2019-04-13 16:21:56 +00:00
return data ;
}
// Get the origin(s) for an analog action within an action set. Returns the number of origins supplied in originsOut. Use this to display the appropriate on-screen prompt for the action.
// originsOut should point to a STEAM_CONTROLLER_MAX_ORIGINS sized array of EControllerActionOrigin handles
int GetAnalogActionOrigins ( ControllerHandle_t controllerHandle , ControllerActionSetHandle_t actionSetHandle , ControllerAnalogActionHandle_t analogActionHandle , EControllerActionOrigin * originsOut )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetAnalogActionOrigins \n " ) ;
2019-09-14 21:24:05 +00:00
EInputActionOrigin origins [ STEAM_CONTROLLER_MAX_ORIGINS ] ;
int ret = GetAnalogActionOrigins ( controllerHandle , actionSetHandle , analogActionHandle , origins ) ;
for ( int i = 0 ; i < ret ; + + i ) {
2019-09-20 10:14:08 +00:00
originsOut [ i ] = ( EControllerActionOrigin ) ( origins [ i ] - ( k_EInputActionOrigin_XBox360_A - k_EControllerActionOrigin_XBox360_A ) ) ;
2019-09-14 21:24:05 +00:00
}
return ret ;
2019-04-13 16:21:56 +00:00
}
int GetAnalogActionOrigins ( InputHandle_t inputHandle , InputActionSetHandle_t actionSetHandle , InputAnalogActionHandle_t analogActionHandle , EInputActionOrigin * originsOut )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetAnalogActionOrigins steaminput \n " ) ;
2019-09-14 21:24:05 +00:00
auto controller = controllers . find ( inputHandle ) ;
if ( controller = = controllers . end ( ) ) return 0 ;
auto map = controller_maps . find ( actionSetHandle ) ;
if ( map = = controller_maps . end ( ) ) return 0 ;
auto a = map - > second . active_analog . find ( analogActionHandle ) ;
if ( a = = map - > second . active_analog . end ( ) ) return 0 ;
int count = 0 ;
for ( auto a : a - > second . first ) {
switch ( a ) {
case TRIGGER_LEFT :
originsOut [ count ] = k_EInputActionOrigin_XBox360_LeftTrigger_Pull ;
break ;
case TRIGGER_RIGHT :
originsOut [ count ] = k_EInputActionOrigin_XBox360_RightTrigger_Pull ;
break ;
case STICK_LEFT + JOY_ID_START :
originsOut [ count ] = k_EInputActionOrigin_XBox360_LeftStick_Move ;
break ;
case STICK_RIGHT + JOY_ID_START :
originsOut [ count ] = k_EInputActionOrigin_XBox360_RightStick_Move ;
break ;
default :
originsOut [ count ] = k_EInputActionOrigin_None ;
break ;
}
+ + count ;
if ( count > = STEAM_INPUT_MAX_ORIGINS ) {
break ;
}
}
2019-09-20 15:04:04 +00:00
return count ;
2019-04-13 16:21:56 +00:00
}
void StopAnalogActionMomentum ( ControllerHandle_t controllerHandle , ControllerAnalogActionHandle_t eAction )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::StopAnalogActionMomentum \n " ) ;
2019-04-13 16:21:56 +00:00
}
// Trigger a haptic pulse on a controller
void TriggerHapticPulse ( ControllerHandle_t controllerHandle , ESteamControllerPad eTargetPad , unsigned short usDurationMicroSec )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::TriggerHapticPulse \n " ) ;
2019-04-13 16:21:56 +00:00
}
void TriggerHapticPulse ( uint32 unControllerIndex , ESteamControllerPad eTargetPad , unsigned short usDurationMicroSec )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::TriggerHapticPulse old \n " ) ;
2019-04-13 16:21:56 +00:00
TriggerHapticPulse ( unControllerIndex , eTargetPad , usDurationMicroSec ) ;
}
// Trigger a pulse with a duty cycle of usDurationMicroSec / usOffMicroSec, unRepeat times.
// nFlags is currently unused and reserved for future use.
void TriggerRepeatedHapticPulse ( ControllerHandle_t controllerHandle , ESteamControllerPad eTargetPad , unsigned short usDurationMicroSec , unsigned short usOffMicroSec , unsigned short unRepeat , unsigned int nFlags )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::TriggerRepeatedHapticPulse \n " ) ;
2019-04-13 16:21:56 +00:00
}
// Tigger a vibration event on supported controllers.
void TriggerVibration ( ControllerHandle_t controllerHandle , unsigned short usLeftSpeed , unsigned short usRightSpeed )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::TriggerVibration %hu %hu \n " , usLeftSpeed , usRightSpeed ) ;
auto controller = controllers . find ( controllerHandle ) ;
if ( controller = = controllers . end ( ) ) return ;
GamepadSetRumble ( ( GAMEPAD_DEVICE ) ( controllerHandle - 1 ) , ( ( double ) usLeftSpeed ) / 65535.0 , ( ( double ) usRightSpeed ) / 65535.0 ) ;
2019-04-13 16:21:56 +00:00
}
// Set the controller LED color on supported controllers.
void SetLEDColor ( ControllerHandle_t controllerHandle , uint8 nColorR , uint8 nColorG , uint8 nColorB , unsigned int nFlags )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::SetLEDColor \n " ) ;
2019-04-13 16:21:56 +00:00
}
// Returns the associated gamepad index for the specified controller, if emulating a gamepad
int GetGamepadIndexForController ( ControllerHandle_t ulControllerHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetGamepadIndexForController \n " ) ;
2019-04-13 16:21:56 +00:00
return 0 ;
}
// Returns the associated controller handle for the specified emulated gamepad
ControllerHandle_t GetControllerForGamepadIndex ( int nIndex )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetControllerForGamepadIndex \n " ) ;
2019-04-13 16:21:56 +00:00
return 0 ;
}
// Returns raw motion data from the specified controller
ControllerMotionData_t GetMotionData ( ControllerHandle_t controllerHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetMotionData \n " ) ;
2019-04-13 16:21:56 +00:00
ControllerMotionData_t data = { } ;
return data ;
}
// Attempt to display origins of given action in the controller HUD, for the currently active action set
// Returns false is overlay is disabled / unavailable, or the user is not in Big Picture mode
bool ShowDigitalActionOrigins ( ControllerHandle_t controllerHandle , ControllerDigitalActionHandle_t digitalActionHandle , float flScale , float flXPosition , float flYPosition )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::ShowDigitalActionOrigins \n " ) ;
2019-04-13 16:21:56 +00:00
return true ;
}
bool ShowAnalogActionOrigins ( ControllerHandle_t controllerHandle , ControllerAnalogActionHandle_t analogActionHandle , float flScale , float flXPosition , float flYPosition )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::ShowAnalogActionOrigins \n " ) ;
2019-04-13 16:21:56 +00:00
return true ;
}
// Returns a localized string (from Steam's language setting) for the specified origin
const char * GetStringForActionOrigin ( EControllerActionOrigin eOrigin )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetStringForActionOrigin \n " ) ;
2019-04-13 16:21:56 +00:00
return " Button String " ;
}
const char * GetStringForActionOrigin ( EInputActionOrigin eOrigin )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetStringForActionOrigin steaminput \n " ) ;
2019-04-13 16:21:56 +00:00
return " Button String " ;
}
// Get a local path to art for on-screen glyph for a particular origin
const char * GetGlyphForActionOrigin ( EControllerActionOrigin eOrigin )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetGlyphForActionOrigin \n " ) ;
2019-04-13 16:21:56 +00:00
return " " ;
}
const char * GetGlyphForActionOrigin ( EInputActionOrigin eOrigin )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetGlyphForActionOrigin steaminput \n " ) ;
2019-04-13 16:21:56 +00:00
return " " ;
}
// Returns the input type for a particular handle
ESteamInputType GetInputTypeForHandle ( ControllerHandle_t controllerHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetInputTypeForHandle \n " ) ;
auto controller = controllers . find ( controllerHandle ) ;
if ( controller = = controllers . end ( ) ) return k_ESteamInputType_Unknown ;
return k_ESteamInputType_XBox360Controller ;
2019-04-13 16:21:56 +00:00
}
const char * GetStringForXboxOrigin ( EXboxOrigin eOrigin )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetStringForXboxOrigin \n " ) ;
2019-04-13 16:21:56 +00:00
return " " ;
}
const char * GetGlyphForXboxOrigin ( EXboxOrigin eOrigin )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetGlyphForXboxOrigin \n " ) ;
2019-04-13 16:21:56 +00:00
return " " ;
}
EControllerActionOrigin GetActionOriginFromXboxOrigin_ ( ControllerHandle_t controllerHandle , EXboxOrigin eOrigin )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetActionOriginFromXboxOrigin \n " ) ;
2019-04-13 16:21:56 +00:00
return k_EControllerActionOrigin_None ;
}
EInputActionOrigin GetActionOriginFromXboxOrigin ( InputHandle_t inputHandle , EXboxOrigin eOrigin )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetActionOriginFromXboxOrigin steaminput \n " ) ;
2019-04-13 16:21:56 +00:00
return k_EInputActionOrigin_None ;
}
EControllerActionOrigin TranslateActionOrigin ( ESteamInputType eDestinationInputType , EControllerActionOrigin eSourceOrigin )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::TranslateActionOrigin \n " ) ;
2019-04-13 16:21:56 +00:00
return k_EControllerActionOrigin_None ;
}
EInputActionOrigin TranslateActionOrigin ( ESteamInputType eDestinationInputType , EInputActionOrigin eSourceOrigin )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::TranslateActionOrigin steaminput \n " ) ;
2019-04-13 16:21:56 +00:00
return k_EInputActionOrigin_None ;
}
2019-07-28 13:02:09 +00:00
bool GetControllerBindingRevision ( ControllerHandle_t controllerHandle , int * pMajor , int * pMinor )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetControllerBindingRevision \n " ) ;
2019-07-28 13:02:09 +00:00
return false ;
}
bool GetDeviceBindingRevision ( InputHandle_t inputHandle , int * pMajor , int * pMinor )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetDeviceBindingRevision \n " ) ;
2019-07-28 13:02:09 +00:00
return false ;
}
uint32 GetRemotePlaySessionID ( InputHandle_t inputHandle )
{
2019-09-10 18:54:54 +00:00
PRINT_DEBUG ( " Steam_Controller::GetRemotePlaySessionID \n " ) ;
2019-07-28 13:02:09 +00:00
return 0 ;
}
2019-04-13 16:21:56 +00:00
2019-09-10 18:54:54 +00:00
void RunCallbacks ( )
{
RunFrame ( ) ;
}
2019-04-13 16:21:56 +00:00
} ;