summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2010-04-13 05:15:38 +0000
committerJordan Woyak <jordan.woyak@gmail.com>2010-04-13 05:15:38 +0000
commitd8906d2a0ca92b636b2e228da6431621e0cc9479 (patch)
treebc07102268a7af7d6ab987045a0da8db5b861fa4 /Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp
parent9592da1a9ba32d5574e210df93c36a5913ee0427 (diff)
Commited my new wiimote plugin work so far. Some code was copied from the current wiimote plugin. I have cleaned up most of the functions, but there are still a bunch of unused structs and stuff that I need to clean up.
Moved ControllerInterface to InputCommon. Moved GCPadNew GUI/Config code to a new project, InputPluginCommon. It is used by both GCPadNew and WiimoteNew. I hope that I included everyone's fixes to GCPadNew and ControllerInterface. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5355 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp')
-rw-r--r--Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp222
1 files changed, 222 insertions, 0 deletions
diff --git a/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp b/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp
new file mode 100644
index 0000000000..16d39289c0
--- /dev/null
+++ b/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp
@@ -0,0 +1,222 @@
+#include "../ControllerInterface.h"
+
+#ifdef CIFACE_USE_XINPUT
+
+#include "XInput.h"
+
+namespace ciface
+{
+namespace XInput
+{
+
+struct
+{
+ const char* const name;
+ const WORD bitmask;
+} named_buttons[] =
+{
+ { "Button A", XINPUT_GAMEPAD_A },
+ { "Button B", XINPUT_GAMEPAD_B },
+ { "Button X", XINPUT_GAMEPAD_X },
+ { "Button Y", XINPUT_GAMEPAD_Y },
+ { "Pad N", XINPUT_GAMEPAD_DPAD_UP },
+ { "Pad S", XINPUT_GAMEPAD_DPAD_DOWN },
+ { "Pad W", XINPUT_GAMEPAD_DPAD_LEFT },
+ { "Pad E", XINPUT_GAMEPAD_DPAD_RIGHT },
+ { "Start", XINPUT_GAMEPAD_START },
+ { "Back", XINPUT_GAMEPAD_BACK },
+ { "Shoulder L", XINPUT_GAMEPAD_LEFT_SHOULDER },
+ { "Shoulder R", XINPUT_GAMEPAD_RIGHT_SHOULDER },
+ { "Thumb L", XINPUT_GAMEPAD_LEFT_THUMB },
+ { "Thumb R", XINPUT_GAMEPAD_RIGHT_THUMB }
+};
+
+const char* named_triggers[] =
+{
+ "Trigger L",
+ "Trigger R"
+};
+
+const char* named_axes[] =
+{
+ "Left X",
+ "Left Y",
+ "Right X",
+ "Right Y"
+};
+
+const char* named_motors[] =
+{
+ "Motor L",
+ "Motor R"
+};
+
+void Init( std::vector<ControllerInterface::Device*>& devices )
+{
+ XINPUT_CAPABILITIES caps;
+ for ( int i = 0; i < 4; ++i )
+ if ( ERROR_SUCCESS == XInputGetCapabilities( i, 0, &caps ) )
+ devices.push_back( new Device( &caps, i ) );
+
+}
+
+Device::Device( const XINPUT_CAPABILITIES* const caps, const unsigned int index )
+: m_index(index), m_subtype(caps->SubType)
+{
+ ZeroMemory( &m_state_out, sizeof(m_state_out) );
+
+ // XInputGetCaps seems to always claim all capabilities are supported
+ // but i will leave all this stuff in, incase m$ fixes xinput up a bit
+
+ // get supported buttons
+ for ( int i = 0; i < sizeof(named_buttons)/sizeof(*named_buttons); ++i )
+ if ( named_buttons[i].bitmask & caps->Gamepad.wButtons )
+ inputs.push_back( new Button( /*xinput_named_buttons[i].bitmask, */i ) );
+
+ // get supported triggers
+ for ( int i = 0; i < sizeof(named_triggers)/sizeof(*named_triggers); ++i )
+ {
+ //BYTE val = (&caps->Gamepad.bLeftTrigger)[i]; // should be max value / msdn lies
+ if ( (&caps->Gamepad.bLeftTrigger)[i] )
+ inputs.push_back( new Trigger( i, 255 ) );
+ }
+
+ // get supported axes
+ for ( int i = 0; i < sizeof(named_axes)/sizeof(*named_axes); ++i )
+ {
+ //SHORT val = (&caps->Gamepad.sThumbLX)[i]; // xinput doesnt give the range / msdn is lier
+ if ( (&caps->Gamepad.sThumbLX)[i] )
+ {
+ // each axis gets a negative and a positive input instance associated with it
+ inputs.push_back( new Axis( i, -32768 ) );
+ inputs.push_back( new Axis( i, 32767 ) );
+ }
+ }
+
+ // get supported motors
+ for ( int i = 0; i < sizeof(named_motors)/sizeof(*named_motors); ++i )
+ {
+ //WORD val = (&caps->Vibration.wLeftMotorSpeed)[i]; // should be max value / nope, more lies
+ if ( (&caps->Vibration.wLeftMotorSpeed)[i] )
+ outputs.push_back( new Motor(i, 65535 ) );
+ }
+
+ ClearInputState();
+
+}
+
+void Device::ClearInputState()
+{
+ ZeroMemory( &m_state_in, sizeof(m_state_in) );
+}
+
+std::string Device::GetName() const
+{
+ // why aren't these defined
+ // subtype doesn't seem to work, i tested with 2 diff arcade sticks, both were shown as gamepad
+ // ill leave it in anyway, maybe m$ will fix it
+
+ switch ( m_subtype )
+ {
+ case XINPUT_DEVSUBTYPE_GAMEPAD : return "Gamepad"; break;
+ case 0x02 /*XINPUT_DEVSUBTYPE_WHEEL*/ : return "Wheel"; break;
+ case 0x03 /*XINPUT_DEVSUBTYPE_ARCADE_STICK*/ : return "Arcade Stick"; break;
+ case 0x04 /*XINPUT_DEVSUBTYPE_FLIGHT_STICK*/ : return "Flight Stick"; break;
+ case 0x05 /*XINPUT_DEVSUBTYPE_DANCE_PAD*/ : return "Dance Pad"; break;
+ case 0x06 /*XINPUT_DEVSUBTYPE_GUITAR*/ : return "Guitar"; break;
+ case 0x08 /*XINPUT_DEVSUBTYPE_DRUM_KIT*/ : return "Drum Kit"; break;
+ default : return "Device"; break;
+ }
+}
+
+int Device::GetId() const
+{
+ return m_index;
+}
+
+std::string Device::GetSource() const
+{
+ return "XInput";
+}
+
+// update i/o
+
+bool Device::UpdateInput()
+{
+ return ( ERROR_SUCCESS == XInputGetState( m_index, &m_state_in ) );
+}
+
+bool Device::UpdateOutput()
+{
+ // this if statement is to make rumble work better when multiple ControllerInterfaces are using the device
+ static XINPUT_VIBRATION current_state_out = {0,0};
+ if ( memcmp( &m_state_out, &current_state_out, sizeof(m_state_out) ) )
+ {
+ current_state_out = m_state_out;
+ return ( ERROR_SUCCESS == XInputSetState( m_index, &m_state_out ) );
+ }
+ else
+ return true;
+}
+
+// GET name/source/id
+
+
+std::string Device::Button::GetName() const
+{
+ return named_buttons[m_index].name;
+}
+
+std::string Device::Axis::GetName() const
+{
+ return std::string(named_axes[m_index]) + ( m_range>0 ? '+' : '-' );
+}
+
+std::string Device::Trigger::GetName() const
+{
+ return named_triggers[m_index];
+}
+
+std::string Device::Motor::GetName() const
+{
+ return named_motors[m_index];
+}
+
+// get/set control state
+
+ControlState Device::GetInputState( const ControllerInterface::Device::Input* const input )
+{
+ return ((Input*)input)->GetState( &m_state_in.Gamepad );
+}
+
+void Device::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state )
+{
+ return ((Output*)output)->SetState( state, &m_state_out );
+}
+
+// GET / SET STATES
+
+ControlState Device::Button::GetState( const XINPUT_GAMEPAD* const gamepad )
+{
+ return (gamepad->wButtons & named_buttons[m_index].bitmask) > 0;
+}
+
+ControlState Device::Trigger::GetState( const XINPUT_GAMEPAD* const gamepad )
+{
+ return ControlState((&gamepad->bLeftTrigger)[m_index]) / m_range;
+}
+
+ControlState Device::Axis::GetState( const XINPUT_GAMEPAD* const gamepad )
+{
+ return std::max( 0.0f, ControlState((&gamepad->sThumbLX)[m_index]) / m_range );
+}
+
+void Device::Motor::SetState( const ControlState state, XINPUT_VIBRATION* const vibration )
+{
+ (&vibration->wLeftMotorSpeed)[m_index] = (WORD)(state * m_range);
+}
+
+}
+}
+
+#endif