Commit 9d8e47a7 authored by Phillip Castaneda's avatar Phillip Castaneda
Browse files

Making xinput/xbox support optional (defaults to false)... don't force OIS...

Making xinput/xbox support optional (defaults to false)... don't force OIS users to have to distribute yet another possibly unwanted redistributable.
parent 703d0f3f
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib" AdditionalDependencies="dxguid.lib dinput8.lib"
OutputFile="$(OutDir)/OIS_static_d.lib" OutputFile="$(OutDir)/OIS_static_d.lib"
AdditionalLibraryDirectories="..\src\win32\extras\WiiMote" AdditionalLibraryDirectories="..\src\win32\extras\WiiMote"
/> />
...@@ -142,7 +142,7 @@ ...@@ -142,7 +142,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib" AdditionalDependencies="dxguid.lib dinput8.lib"
OutputFile="$(OutDir)/OIS_static.lib" OutputFile="$(OutDir)/OIS_static.lib"
AdditionalLibraryDirectories="..\src\win32\extras\WiiMote" AdditionalLibraryDirectories="..\src\win32\extras\WiiMote"
/> />
...@@ -215,7 +215,7 @@ ...@@ -215,7 +215,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib" AdditionalDependencies="dxguid.lib dinput8.lib"
AdditionalLibraryDirectories="..\src\win32\extras\WiiMote\" AdditionalLibraryDirectories="..\src\win32\extras\WiiMote\"
GenerateDebugInformation="false" GenerateDebugInformation="false"
OptimizeReferences="2" OptimizeReferences="2"
...@@ -298,7 +298,7 @@ ...@@ -298,7 +298,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib" AdditionalDependencies="dxguid.lib dinput8.lib"
OutputFile="$(OutDir)/OIS_d.dll" OutputFile="$(OutDir)/OIS_d.dll"
AdditionalLibraryDirectories="..\src\win32\extras\WiiMote\" AdditionalLibraryDirectories="..\src\win32\extras\WiiMote\"
GenerateDebugInformation="true" GenerateDebugInformation="true"
......
...@@ -69,9 +69,7 @@ restrictions: ...@@ -69,9 +69,7 @@ restrictions:
/** /**
@remarks @remarks
Build in support for Win32 XInput (Xbox 360 Controller) Build in support for Win32 XInput (Xbox 360 Controller)
@notes
Not Yet Implemented
*/ */
//#define OIS_WIN32_XINPUT_SUPPORT #define OIS_WIN32_XINPUT_SUPPORT
#endif #endif
...@@ -40,6 +40,9 @@ namespace OIS ...@@ -40,6 +40,9 @@ namespace OIS
/** @copydoc Object::capture */ /** @copydoc Object::capture */
virtual void capture(); virtual void capture();
//! hanlde xinput
void captureXInput();
/** @copydoc Object::queryInterface */ /** @copydoc Object::queryInterface */
virtual Interface* queryInterface(Interface::IType type); virtual Interface* queryInterface(Interface::IType type);
......
...@@ -27,12 +27,15 @@ restrictions: ...@@ -27,12 +27,15 @@ restrictions:
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#include <windows.h> #include <windows.h>
#include <dinput.h> #include <dinput.h>
#include <XInput.h>
#ifdef OIS_WIN32_XINPUT_SUPPORT
# include <XInput.h>
#endif
//Max number of elements to collect from buffered DirectInput //Max number of elements to collect from buffered DirectInput
#define KEYBOARD_DX_BUFFERSIZE 17 #define KEYBOARD_DX_BUFFERSIZE 17
#define MOUSE_DX_BUFFERSIZE 64 #define MOUSE_DX_BUFFERSIZE 128
#define JOYSTICK_DX_BUFFERSIZE 124 #define JOYSTICK_DX_BUFFERSIZE 129
//MinGW defines //MinGW defines
#if defined(OIS_MINGW_COMPILER) #if defined(OIS_MINGW_COMPILER)
......
...@@ -119,7 +119,7 @@ void Win32InputManager::_enumerateDevices() ...@@ -119,7 +119,7 @@ void Win32InputManager::_enumerateDevices()
//Enumerate all attached devices //Enumerate all attached devices
mDirectInput->EnumDevices(NULL, _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY); mDirectInput->EnumDevices(NULL, _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY);
int xinputControllers = 0; #ifdef OIS_WIN32_XINPUT_SUPPORT
//let's check how many possible XInput devices we may have (max 4)... //let's check how many possible XInput devices we may have (max 4)...
for(int i = 0; i < 3; ++i) for(int i = 0; i < 3; ++i)
{ {
...@@ -130,6 +130,7 @@ void Win32InputManager::_enumerateDevices() ...@@ -130,6 +130,7 @@ void Win32InputManager::_enumerateDevices()
break; break;
} }
} }
#endif
} }
//--------------------------------------------------------------------------------// //--------------------------------------------------------------------------------//
......
...@@ -39,6 +39,9 @@ restrictions: ...@@ -39,6 +39,9 @@ restrictions:
} }
#endif #endif
#ifdef OIS_WIN32_XINPUT_SUPPORT
# pragma comment(lib, "xinput.lib")
#endif
//DX Only defines macros for the JOYSTICK not JOYSTICK2, so fix it //DX Only defines macros for the JOYSTICK not JOYSTICK2, so fix it
#undef DIJOFS_BUTTON #undef DIJOFS_BUTTON
...@@ -243,243 +246,254 @@ BOOL CALLBACK Win32JoyStick::DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID ...@@ -243,243 +246,254 @@ BOOL CALLBACK Win32JoyStick::DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID
//--------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------//
void Win32JoyStick::capture() void Win32JoyStick::capture()
{ {
#ifdef OIS_WIN32_XINPUT_SUPPORT
//handle xbox controller differently
if (mJoyInfo.isXInput) if (mJoyInfo.isXInput)
{ {
XINPUT_STATE inputState; captureXInput();
if (XInputGetState((DWORD)mJoyInfo.xInputDev, &inputState) != ERROR_SUCCESS) return;
memset(&inputState, 0, sizeof(inputState)); }
#endif
//Sticks and triggers
int value;
bool axisMoved[XINPUT_TRANSLATED_AXIS_COUNT] = {false,false,false,false,false,false};
//LeftY
value = -(int)inputState.Gamepad.sThumbLY;
mState.mAxes[0].rel = value - mState.mAxes[0].abs;
mState.mAxes[0].abs = value;
if(mState.mAxes[0].rel != 0)
axisMoved[0] = true;
//LeftX
mState.mAxes[1].rel = inputState.Gamepad.sThumbLX - mState.mAxes[1].abs;
mState.mAxes[1].abs = inputState.Gamepad.sThumbLX;
if(mState.mAxes[1].rel != 0)
axisMoved[1] = true;
//RightY
value = -(int)inputState.Gamepad.sThumbRY;
mState.mAxes[2].rel = value - mState.mAxes[2].abs;
mState.mAxes[2].abs = value;
if(mState.mAxes[2].rel != 0)
axisMoved[2] = true;
//RightX
mState.mAxes[3].rel = inputState.Gamepad.sThumbRX - mState.mAxes[3].abs;
mState.mAxes[3].abs = inputState.Gamepad.sThumbRX;
if(mState.mAxes[3].rel != 0)
axisMoved[3] = true;
//Left trigger
value = inputState.Gamepad.bLeftTrigger * 129;
if(value > JoyStick::MAX_AXIS)
value = JoyStick::MAX_AXIS;
mState.mAxes[4].rel = value - mState.mAxes[4].abs;
mState.mAxes[4].abs = value;
if(mState.mAxes[4].rel != 0)
axisMoved[4] = true;
//Right trigger
value = (int)inputState.Gamepad.bRightTrigger * 129;
if(value > JoyStick::MAX_AXIS)
value = JoyStick::MAX_AXIS;
mState.mAxes[5].rel = value - mState.mAxes[5].abs;
mState.mAxes[5].abs = value;
if(mState.mAxes[5].rel != 0)
axisMoved[5] = true;
//POV
int previousPov = mState.mPOV[0].direction;
int& pov = mState.mPOV[0].direction;
pov = Pov::Centered;
if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
pov |= Pov::North;
else if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
pov |= Pov::South;
if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
pov |= Pov::West;
else if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
pov |= Pov::East;
//Buttons - The first 4 buttons don't need to be checked since they represent the dpad
bool previousButtons[XINPUT_TRANSLATED_BUTTON_COUNT];
std::copy(mState.mButtons.begin(), mState.mButtons.end(), previousButtons);
for (size_t i = 0; i < XINPUT_TRANSLATED_BUTTON_COUNT; i++)
mState.mButtons[i] = (inputState.Gamepad.wButtons & (1 << (i + 4))) != 0;
//Send events
if (mBuffered && mListener)
{
JoyStickEvent joystickEvent(this, mState);
//Axes
for (int i = 0; i < XINPUT_TRANSLATED_AXIS_COUNT; i++)
{
if (axisMoved[i] && !mListener->axisMoved(joystickEvent, i))
return;
}
//POV //handle directinput based devices
if (previousPov != pov && !mListener->povMoved(joystickEvent, 0)) DIDEVICEOBJECTDATA diBuff[JOYSTICK_DX_BUFFERSIZE];
return; DWORD entries = JOYSTICK_DX_BUFFERSIZE;
//Buttons // Poll the device to read the current state
for (int i = 0; i < XINPUT_TRANSLATED_BUTTON_COUNT; i++) HRESULT hr = mJoyStick->Poll();
{ if( hr == DI_OK )
if (!previousButtons[i] && mState.mButtons[i]) hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
{
if (!mListener->buttonPressed(joystickEvent, i)) if( hr != DI_OK )
return;
}
else if (previousButtons[i] && !mState.mButtons[i])
{
if (!mListener->buttonReleased(joystickEvent, i))
return;
}
}
}
}
else
{ {
DIDEVICEOBJECTDATA diBuff[JOYSTICK_DX_BUFFERSIZE]; hr = mJoyStick->Acquire();
DWORD entries = JOYSTICK_DX_BUFFERSIZE; while( hr == DIERR_INPUTLOST )
hr = mJoyStick->Acquire();
// Poll the device to read the current state // Poll the device to read the current state
HRESULT hr = mJoyStick->Poll(); mJoyStick->Poll();
if( hr == DI_OK ) hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 ); //Perhaps the user just tabbed away
if( FAILED(hr) )
if( hr != DI_OK ) return;
{ }
hr = mJoyStick->Acquire();
while( hr == DIERR_INPUTLOST )
hr = mJoyStick->Acquire();
// Poll the device to read the current state
mJoyStick->Poll();
hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
//Perhaps the user just tabbed away
if( FAILED(hr) )
return;
}
bool axisMoved[24] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false, bool axisMoved[24] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false}; false,false,false,false,false,false,false,false};
bool sliderMoved[4] = {false,false,false,false}; bool sliderMoved[4] = {false,false,false,false};
//Loop through all the events //Loop through all the events
for(unsigned int i = 0; i < entries; ++i) for(unsigned int i = 0; i < entries; ++i)
{
//This may seem outof order, but is in order of the way these variables
//are declared in the JoyStick State 2 structure.
switch(diBuff[i].dwOfs)
{ {
//This may seem outof order, but is in order of the way these variables //------ slider -//
//are declared in the JoyStick State 2 structure. case DIJOFS_SLIDER0(0):
switch(diBuff[i].dwOfs) sliderMoved[0] = true;
mState.mSliders[0].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER0(1):
sliderMoved[0] = true;
mState.mSliders[0].abY = diBuff[i].dwData;
break;
//----- Max 4 POVs Next ---------------//
case DIJOFS_POV(0):
if(!_changePOV(0,diBuff[i]))
return;
break;
case DIJOFS_POV(1):
if(!_changePOV(1,diBuff[i]))
return;
break;
case DIJOFS_POV(2):
if(!_changePOV(2,diBuff[i]))
return;
break;
case DIJOFS_POV(3):
if(!_changePOV(3,diBuff[i]))
return;
break;
case DIJOFS_SLIDER1(0):
sliderMoved[1] = true;
mState.mSliders[1].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER1(1):
sliderMoved[1] = true;
mState.mSliders[1].abY = diBuff[i].dwData;
break;
case DIJOFS_SLIDER2(0):
sliderMoved[2] = true;
mState.mSliders[2].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER2(1):
sliderMoved[2] = true;
mState.mSliders[2].abY = diBuff[i].dwData;
break;
case DIJOFS_SLIDER3(0):
sliderMoved[3] = true;
mState.mSliders[3].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER3(1):
sliderMoved[3] = true;
mState.mSliders[3].abY = diBuff[i].dwData;
break;
//-----------------------------------------//
default:
//Handle Button Events Easily using the DX Offset Macros
if( diBuff[i].dwOfs >= DIJOFS_BUTTON(0) && diBuff[i].dwOfs < DIJOFS_BUTTON(128) )
{ {
//------ slider -// if(!_doButtonClick((diBuff[i].dwOfs - DIJOFS_BUTTON(0)), diBuff[i]))
case DIJOFS_SLIDER0(0):
sliderMoved[0] = true;
mState.mSliders[0].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER0(1):
sliderMoved[0] = true;
mState.mSliders[0].abY = diBuff[i].dwData;
break;
//----- Max 4 POVs Next ---------------//
case DIJOFS_POV(0):
if(!_changePOV(0,diBuff[i]))
return;
break;
case DIJOFS_POV(1):
if(!_changePOV(1,diBuff[i]))
return;
break;
case DIJOFS_POV(2):
if(!_changePOV(2,diBuff[i]))
return; return;
break; }
case DIJOFS_POV(3): else if((short)(diBuff[i].uAppData >> 16) == 0x1313)
if(!_changePOV(3,diBuff[i])) { //If it was nothing else, might be axis enumerated earlier (determined by magic number)
return; int axis = (int)(0x0000FFFF & diBuff[i].uAppData); //Mask out the high bit
break; assert( axis >= 0 && axis < (int)mState.mAxes.size() && "Axis out of range!");
case DIJOFS_SLIDER1(0):
sliderMoved[1] = true; if(axis >= 0 && axis < (int)mState.mAxes.size())
mState.mSliders[1].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER1(1):
sliderMoved[1] = true;
mState.mSliders[1].abY = diBuff[i].dwData;
break;
case DIJOFS_SLIDER2(0):
sliderMoved[2] = true;
mState.mSliders[2].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER2(1):
sliderMoved[2] = true;
mState.mSliders[2].abY = diBuff[i].dwData;
break;
case DIJOFS_SLIDER3(0):
sliderMoved[3] = true;
mState.mSliders[3].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER3(1):
sliderMoved[3] = true;
mState.mSliders[3].abY = diBuff[i].dwData;
break;
//-----------------------------------------//
default:
//Handle Button Events Easily using the DX Offset Macros
if( diBuff[i].dwOfs >= DIJOFS_BUTTON(0) && diBuff[i].dwOfs < DIJOFS_BUTTON(128) )
{ {
if(!_doButtonClick((diBuff[i].dwOfs - DIJOFS_BUTTON(0)), diBuff[i])) mState.mAxes[axis].abs = diBuff[i].dwData;
return; axisMoved[axis] = true;
} }
else if((short)(diBuff[i].uAppData >> 16) == 0x1313) }
{ //If it was nothing else, might be axis enumerated earlier (determined by magic number)
int axis = (int)(0x0000FFFF & diBuff[i].uAppData); //Mask out the high bit
assert( axis >= 0 && axis < (int)mState.mAxes.size() && "Axis out of range!");
if(axis >= 0 && axis < (int)mState.mAxes.size()) break;
{ } //end case
mState.mAxes[axis].abs = diBuff[i].dwData; } //end for
axisMoved[axis] = true;
}
}
break; //Check to see if any of the axes values have changed.. if so send events
} //end case if( mBuffered && mListener && entries > 0 )
} //end for {
JoyStickEvent temp(this, mState);
//Check to see if any of the axes values have changed.. if so send events //Update axes
if( mBuffered && mListener && entries > 0 ) for( int i = 0; i < 24; ++i )
{ if( axisMoved[i] )
JoyStickEvent temp(this, mState); if( mListener->axisMoved( temp, i ) == false )
return;
//Update axes
for( int i = 0; i < 24; ++i ) //Now update sliders
if( axisMoved[i] ) for( int i = 0; i < 4; ++i )
if( mListener->axisMoved( temp, i ) == false ) if( sliderMoved[i] )
return; if( mListener->sliderMoved( temp, i ) == false )
return;
//Now update sliders
for( int i = 0; i < 4; ++i )
if( sliderMoved[i] )
if( mListener->sliderMoved( temp, i ) == false )
return;
}
} }
} }
//--------------------------------------------------------------------------------------------------//
void Win32JoyStick::captureXInput()
{
#ifdef OIS_WIN32_XINPUT_SUPPORT
XINPUT_STATE inputState;
if (XInputGetState((DWORD)mJoyInfo.xInputDev, &inputState) != ERROR_SUCCESS)
memset(&inputState, 0, sizeof(inputState));
//Sticks and triggers
int value;
bool axisMoved[XINPUT_TRANSLATED_AXIS_COUNT] = {false,false,false,false,false,false};
//LeftY
value = -(int)inputState.Gamepad.sThumbLY;
mState.mAxes[0].rel = value - mState.mAxes[0].abs;
mState.mAxes[0].abs = value;
if(mState.mAxes[0].rel != 0)
axisMoved[0] = true;
//LeftX
mState.mAxes[1].rel = inputState.Gamepad.sThumbLX - mState.mAxes[1].abs;
mState.mAxes[1].abs = inputState.Gamepad.sThumbLX;
if(mState.mAxes[1].rel != 0)
axisMoved[1] = true;
//RightY
value = -(int)inputState.Gamepad.sThumbRY;
mState.mAxes[2].rel = value - mState.mAxes[2].abs;
mState.mAxes[2].abs = value;
if(mState.mAxes[2].rel != 0)
axisMoved[2] = true;
//RightX
mState.mAxes[3].rel = inputState.Gamepad.sThumbRX - mState.mAxes[3].abs;
mState.mAxes[3].abs = inputState.Gamepad.sThumbRX;
if(mState.mAxes[3].rel != 0)
axisMoved[3] = true;
//Left trigger
value = inputState.Gamepad.bLeftTrigger * 129;
if(value > JoyStick::MAX_AXIS)
value = JoyStick::MAX_AXIS;
mState.mAxes[4].rel = value - mState.mAxes[4].abs;
mState.mAxes[4].abs = value;
if(mState.mAxes[4].rel != 0)
axisMoved[4] = true;
//Right trigger
value = (int)inputState.Gamepad.bRightTrigger * 129;
if(value > JoyStick::MAX_AXIS)
value = JoyStick::MAX_AXIS;
mState.mAxes[5].rel = value - mState.mAxes[5].abs;
mState.mAxes[5].abs = value;
if(mState.mAxes[5].rel != 0)
axisMoved[5] = true;
//POV
int previousPov = mState.mPOV[0].direction;
int& pov = mState.mPOV[0].direction;
pov = Pov::Centered;
if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
pov |= Pov::North;
else if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
pov |= Pov::South;
if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
pov |= Pov::West;
else if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
pov |= Pov::East;
//Buttons - The first 4 buttons don't need to be checked since they represent the dpad
bool previousButtons[XINPUT_TRANSLATED_BUTTON_COUNT];
std::copy(mState.mButtons.begin(), mState.mButtons.end(), previousButtons);
for (size_t i = 0; i < XINPUT_TRANSLATED_BUTTON_COUNT; i++)
mState.mButtons[i] = (inputState.Gamepad.wButtons & (1 << (i + 4))) != 0;
//Send events
if (mBuffered && mListener)
{
JoyStickEvent joystickEvent(this, mState);
//Axes
for (int i = 0; i < XINPUT_TRANSLATED_AXIS_COUNT; i++)
{
if (axisMoved[i] && !mListener->axisMoved(joystickEvent, i))
return;
}
//POV
if (previousPov != pov && !mListener->povMoved(joystickEvent, 0))
return;
//Buttons
for (int i = 0; i < XINPUT_TRANSLATED_BUTTON_COUNT; i++)
{
if (!previousButtons[i] && mState.mButtons[i])
{
if (!mListener->buttonPressed(joystickEvent, i))
return;
}
else if (previousButtons[i] && !mState.mButtons[i])
{
if (!mListener->buttonReleased(joystickEvent, i))
return;
}
}
}
#endif
}
//--------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------//
bool Win32JoyStick::_doButtonClick( int button, DIDEVICEOBJECTDATA& di ) bool Win32JoyStick::_doButtonClick( int button, DIDEVICEOBJECTDATA& di )
{ {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment