Commit d9b8990a authored by Phillip Castaneda's avatar Phillip Castaneda
Browse files

Adding XInput support for win32. Not currently an option to compile out - todo.

parent 6a6c0c87
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
The zlib/libpng License The zlib/libpng License
Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com) Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this event will the authors be held liable for any damages arising from the use of this
...@@ -45,21 +45,16 @@ compatiable with many systems and operating systems ...@@ -45,21 +45,16 @@ compatiable with many systems and operating systems
Win32/ Win32/
Contains Visual Studio .Net Solution Files Contains Visual Studio .Net Solution Files
Contains CodeBlocks + MinGW + StlPort project files for OIS Contains CodeBlocks project files for OIS
---- Dependencies ------------------------------------------------------ ---- Dependencies ------------------------------------------------------
DirectInput 8 DirectInput 8
Ogre & CEGUI 0.4.0 If building CEGUIOgre OIS Demo
SDL/
A test bed for an OIS InputManager with SDL as the backend. Not recommended;
however, useful for platforms with non-native OIS ports for temporary use.
Linux/ Linux/
---- Dependencies ------------------------------------------------------ ---- Dependencies ------------------------------------------------------
X11 X11
Ogre (GLX Platform) & CEGUI 0.4.0 If building CEGUIOgre OIS Demo Newer Linux Kernel (2.6+ ?) for Event API
Newer Linux Kernel (2.6+ ?) for Event API - else, use --disable-joyevents
Steps to build on Linux: Steps to build on Linux:
./bootstrap ./bootstrap
...@@ -68,9 +63,7 @@ Linux/ ...@@ -68,9 +63,7 @@ Linux/
---- Configure build options -------------------------------------------- ---- Configure build options --------------------------------------------
./configure --help --- List all configure options ./configure --help --- List all configure options
./configure --disable-ogre --- Disables CEGUIOgre ActionMapping Demo
./configure --disable-joyevents --- Uses /dev/input/jsX instead of
/dev/input/eventX
LinuxCB/ LinuxCB/
Contains CodeBlock files for building OIS and Demos with codeblocks Contains CodeBlock files for building OIS and Demos with codeblocks
...@@ -79,9 +72,5 @@ LinuxCB/ ...@@ -79,9 +72,5 @@ LinuxCB/
settings. It also installs libOIS to ~/libs settings. It also installs libOIS to ~/libs
Mac/ Mac/
XCode-1.5/
Non-complete native OIS port.
XCode-2.2/ XCode-2.2/
Working, complete, OIS port to OSX using SDL as a backend. Working, mostly complete OSX vackend.
\ No newline at end of file \ No newline at end of file
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="ois_static_d.lib" AdditionalDependencies="ois_static_d.lib xinput.lib"
OutputFile="$(OutDir)/CommandLine.exe" OutputFile="$(OutDir)/CommandLine.exe"
LinkIncremental="2" LinkIncremental="2"
AdditionalLibraryDirectories="..\..\lib;..\..\src\win32\extras\WiiMote" AdditionalLibraryDirectories="..\..\lib;..\..\src\win32\extras\WiiMote"
...@@ -99,9 +99,9 @@ ...@@ -99,9 +99,9 @@
/> />
</Configuration> </Configuration>
<Configuration <Configuration
Name="Debug|x64" Name="Release|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)" OutputDirectory="Release"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" IntermediateDirectory="Release"
ConfigurationType="1" ConfigurationType="1"
CharacterSet="2" CharacterSet="2"
> >
...@@ -119,16 +119,17 @@ ...@@ -119,16 +119,17 @@
/> />
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
TargetEnvironment="3"
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="..\..\includes;..\CommandLine\" AdditionalIncludeDirectories="..\..\includes;..\CommandLine\"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_STLP_DEBUG" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
MinimalRebuild="true" StringPooling="true"
BasicRuntimeChecks="3" RuntimeLibrary="2"
RuntimeLibrary="3" EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="3" WarningLevel="3"
Detect64BitPortabilityProblems="true" Detect64BitPortabilityProblems="true"
...@@ -145,16 +146,17 @@ ...@@ -145,16 +146,17 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="ois_d.lib" AdditionalDependencies="ois_static.lib xinput.lib"
OutputFile="$(OutDir)/CommandLine.exe" OutputFile="$(OutDir)/CommandLine.exe"
LinkIncremental="2" LinkIncremental="1"
AdditionalLibraryDirectories="..\..\lib64" AdditionalLibraryDirectories="..\..\lib;..\..\src\win32\extras\WiiMote"
GenerateDebugInformation="true" GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/CommandLine.pdb"
SubSystem="1" SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1" RandomizedBaseAddress="1"
DataExecutionPrevention="0" DataExecutionPrevention="0"
TargetMachine="17" TargetMachine="1"
/> />
<Tool <Tool
Name="VCALinkTool" Name="VCALinkTool"
...@@ -180,9 +182,9 @@ ...@@ -180,9 +182,9 @@
/> />
</Configuration> </Configuration>
<Configuration <Configuration
Name="Release|Win32" Name="Debug|x64"
OutputDirectory="Release" OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="Release" IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1" ConfigurationType="1"
CharacterSet="2" CharacterSet="2"
> >
...@@ -200,17 +202,16 @@ ...@@ -200,17 +202,16 @@
/> />
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
TargetEnvironment="3"
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="0"
InlineFunctionExpansion="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="..\..\includes;..\CommandLine\" AdditionalIncludeDirectories="..\..\includes;..\CommandLine\"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_STLP_DEBUG"
StringPooling="true" MinimalRebuild="true"
RuntimeLibrary="2" BasicRuntimeChecks="3"
EnableFunctionLevelLinking="true" RuntimeLibrary="3"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="3" WarningLevel="3"
Detect64BitPortabilityProblems="true" Detect64BitPortabilityProblems="true"
...@@ -227,17 +228,16 @@ ...@@ -227,17 +228,16 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="ois_static.lib" AdditionalDependencies="ois_d.lib"
OutputFile="$(OutDir)/CommandLine.exe" OutputFile="$(OutDir)/CommandLine.exe"
LinkIncremental="1" LinkIncremental="2"
AdditionalLibraryDirectories="..\..\lib;..\..\src\win32\extras\WiiMote" AdditionalLibraryDirectories="..\..\lib64"
GenerateDebugInformation="true" GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/CommandLine.pdb"
SubSystem="1" SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1" RandomizedBaseAddress="1"
DataExecutionPrevention="0" DataExecutionPrevention="0"
TargetMachine="1" TargetMachine="17"
/> />
<Tool <Tool
Name="VCALinkTool" Name="VCALinkTool"
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="ois_static_d.lib" AdditionalDependencies="ois_static_d.lib xinput.lib"
OutputFile="$(OutDir)/DemoFFTest.exe" OutputFile="$(OutDir)/DemoFFTest.exe"
LinkIncremental="2" LinkIncremental="2"
AdditionalLibraryDirectories="..\..\lib;..\..\src\win32\extras\WiiMote" AdditionalLibraryDirectories="..\..\lib;..\..\src\win32\extras\WiiMote"
...@@ -146,7 +146,7 @@ ...@@ -146,7 +146,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="ois_static.lib" AdditionalDependencies="ois_static.lib xinput.lib"
OutputFile="$(OutDir)/DemoFFTest.exe" OutputFile="$(OutDir)/DemoFFTest.exe"
LinkIncremental="1" LinkIncremental="1"
AdditionalLibraryDirectories="..\..\lib;..\..\src\win32\extras\WiiMote" AdditionalLibraryDirectories="..\..\lib;..\..\src\win32\extras\WiiMote"
......
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
OutputFile="$(OutDir)/OIS_static_d.lib" OutputFile="$(OutDir)/OIS_static_d.lib"
AdditionalLibraryDirectories="..\src\win32\extras\WiiMote" AdditionalLibraryDirectories="..\src\win32\extras\WiiMote"
/> />
...@@ -140,7 +140,7 @@ ...@@ -140,7 +140,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
OutputFile="$(OutDir)/OIS_d.lib" OutputFile="$(OutDir)/OIS_d.lib"
/> />
<Tool <Tool
...@@ -212,7 +212,7 @@ ...@@ -212,7 +212,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
OutputFile="$(OutDir)/OIS_static.lib" OutputFile="$(OutDir)/OIS_static.lib"
AdditionalLibraryDirectories="..\src\win32\extras\WiiMote" AdditionalLibraryDirectories="..\src\win32\extras\WiiMote"
/> />
...@@ -289,7 +289,7 @@ ...@@ -289,7 +289,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
OutputFile="$(OutDir)/OIS.lib" OutputFile="$(OutDir)/OIS.lib"
/> />
<Tool <Tool
...@@ -361,7 +361,7 @@ ...@@ -361,7 +361,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
AdditionalLibraryDirectories="..\src\win32\extras\WiiMote\" AdditionalLibraryDirectories="..\src\win32\extras\WiiMote\"
GenerateDebugInformation="false" GenerateDebugInformation="false"
OptimizeReferences="2" OptimizeReferences="2"
...@@ -451,7 +451,7 @@ ...@@ -451,7 +451,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
GenerateDebugInformation="true" GenerateDebugInformation="true"
TargetMachine="17" TargetMachine="17"
/> />
...@@ -531,7 +531,7 @@ ...@@ -531,7 +531,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.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"
...@@ -613,7 +613,7 @@ ...@@ -613,7 +613,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
OutputFile="$(OutDir)/OIS_d.dll" OutputFile="$(OutDir)/OIS_d.dll"
TargetMachine="17" TargetMachine="17"
/> />
......
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.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" AdditionalDependencies="dxguid.lib dinput8.lib xinput.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" AdditionalDependencies="dxguid.lib dinput8.lib xinput.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" AdditionalDependencies="dxguid.lib dinput8.lib xinput.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"
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
OutputFile="$(OutDir)/OIS_d.lib" OutputFile="$(OutDir)/OIS_d.lib"
/> />
<Tool <Tool
...@@ -455,7 +455,7 @@ ...@@ -455,7 +455,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
OutputFile="$(OutDir)/OIS.lib" OutputFile="$(OutDir)/OIS.lib"
/> />
<Tool <Tool
...@@ -531,7 +531,7 @@ ...@@ -531,7 +531,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
GenerateDebugInformation="true" GenerateDebugInformation="true"
RandomizedBaseAddress="1" RandomizedBaseAddress="1"
DataExecutionPrevention="0" DataExecutionPrevention="0"
...@@ -611,7 +611,7 @@ ...@@ -611,7 +611,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib" AdditionalDependencies="dxguid.lib dinput8.lib xinput.lib"
OutputFile="$(OutDir)/OIS_d.dll" OutputFile="$(OutDir)/OIS_d.dll"
RandomizedBaseAddress="1" RandomizedBaseAddress="1"
DataExecutionPrevention="0" DataExecutionPrevention="0"
...@@ -897,13 +897,6 @@ ...@@ -897,13 +897,6 @@
Name="VCResourceCompilerTool" Name="VCResourceCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="OIS_ReleaseDll|Win32"
>
<Tool
Name="VCResourceCompilerTool"
/>
</FileConfiguration>
<FileConfiguration <FileConfiguration
Name="OIS_DebugDll|Win32" Name="OIS_DebugDll|Win32"
ExcludedFromBuild="true" ExcludedFromBuild="true"
......
...@@ -46,6 +46,14 @@ namespace OIS ...@@ -46,6 +46,14 @@ namespace OIS
/** @copydoc Object::_initialize */ /** @copydoc Object::_initialize */
virtual void _initialize(); virtual void _initialize();
/**
@remarks
Enum each PNP device using WMI and check each device ID to see if it contains
"IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device
Unfortunately this information can not be found by just using DirectInput
*/
static void CheckXInputDevices(JoyStickInfoList &joys);
protected: protected:
//! Enumerates all things //! Enumerates all things
void _enumerate(); void _enumerate();
...@@ -60,12 +68,12 @@ namespace OIS ...@@ -60,12 +68,12 @@ namespace OIS
IDirectInput8* mDirectInput; IDirectInput8* mDirectInput;
IDirectInputDevice8* mJoyStick; IDirectInputDevice8* mJoyStick;
DIDEVCAPS mDIJoyCaps; DIDEVCAPS mDIJoyCaps;
DWORD coopSetting; DWORD coopSetting;
GUID deviceGuid;
JoyStickInfo mJoyInfo;
//! A force feedback device //! A force feedback device
Win32ForceFeedback* ff_device; Win32ForceFeedback* mFfDevice;
//! Mapping //! Mapping
int _AxisNumber; int _AxisNumber;
......
...@@ -27,6 +27,7 @@ restrictions: ...@@ -27,6 +27,7 @@ restrictions:
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#include <windows.h> #include <windows.h>
#include <dinput.h> #include <dinput.h>
#include <XInput.h>
//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
...@@ -54,10 +55,13 @@ namespace OIS ...@@ -54,10 +55,13 @@ namespace OIS
public: public:
int devId; int devId;
GUID deviceID; GUID deviceID;
GUID productGuid;
std::string vendor; std::string vendor;
bool isXInput;
int xInputDev;
}; };
typedef std::vector< JoyStickInfo > JoyStickInfoList; typedef std::vector<JoyStickInfo> JoyStickInfoList;
} }
#endif //_WIN32_INPUTSYSTEM_PREREQS_H #endif //_WIN32_INPUTSYSTEM_PREREQS_H
...@@ -74,7 +74,7 @@ void Win32InputManager::_initialize( ParamList &paramList ) ...@@ -74,7 +74,7 @@ void Win32InputManager::_initialize( ParamList &paramList )
hInst = GetModuleHandle(0); hInst = GetModuleHandle(0);
//Create the input system //Create the device
hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL ); hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL );
if (FAILED(hr)) if (FAILED(hr))
OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> Not able to init DirectX8 Input!"); OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> Not able to init DirectX8 Input!");
...@@ -117,7 +117,19 @@ void Win32InputManager::_parseConfigSettings( ParamList &paramList ) ...@@ -117,7 +117,19 @@ void Win32InputManager::_parseConfigSettings( ParamList &paramList )
void Win32InputManager::_enumerateDevices() 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;
//let's check how many possible XInput devices we may have (max 4)...
for(int i = 0; i < 3; ++i)
{
XINPUT_STATE state;
if(XInputGetState(i, &state) != ERROR_DEVICE_NOT_CONNECTED)
{ //Once we found 1, just check our whole list against devices
Win32JoyStick::CheckXInputDevices(unusedJoyStickList);
break;
}
}
} }
//--------------------------------------------------------------------------------// //--------------------------------------------------------------------------------//
...@@ -133,6 +145,8 @@ BOOL CALLBACK Win32InputManager::_DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, L ...@@ -133,6 +145,8 @@ BOOL CALLBACK Win32InputManager::_DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, L
GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_FLIGHT) GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_FLIGHT)
{ {
JoyStickInfo jsInfo; JoyStickInfo jsInfo;
jsInfo.isXInput = false;
jsInfo.productGuid = lpddi->guidProduct;
jsInfo.deviceID = lpddi->guidInstance; jsInfo.deviceID = lpddi->guidInstance;
jsInfo.vendor = lpddi->tszInstanceName; jsInfo.vendor = lpddi->tszInstanceName;
jsInfo.devId = _this_->joySticks; jsInfo.devId = _this_->joySticks;
......
...@@ -27,6 +27,18 @@ restrictions: ...@@ -27,6 +27,18 @@ restrictions:
#include "OISException.h" #include "OISException.h"
#include <cassert> #include <cassert>
#include <wbemidl.h>
#include <oleauto.h>
//#include <wmsstd.h>
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(x) \
if(x != NULL) \
{ \
x->Release(); \
x = NULL; \
}
#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
...@@ -39,26 +51,26 @@ restrictions: ...@@ -39,26 +51,26 @@ restrictions:
#define DIJOFS_SLIDER2(n) (FIELD_OFFSET(DIJOYSTATE2, rglASlider)+(n) * sizeof(LONG)) #define DIJOFS_SLIDER2(n) (FIELD_OFFSET(DIJOYSTATE2, rglASlider)+(n) * sizeof(LONG))
#define DIJOFS_SLIDER3(n) (FIELD_OFFSET(DIJOYSTATE2, rglFSlider)+(n) * sizeof(LONG)) #define DIJOFS_SLIDER3(n) (FIELD_OFFSET(DIJOYSTATE2, rglFSlider)+(n) * sizeof(LONG))
#define XINPUT_TRANSLATED_BUTTON_COUNT 12
#define XINPUT_TRANSLATED_AXIS_COUNT 6
using namespace OIS; using namespace OIS;
//--------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------//
Win32JoyStick::Win32JoyStick( InputManager* creator, IDirectInput8* pDI, Win32JoyStick::Win32JoyStick( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings, const JoyStickInfo &info ) :
bool buffered, DWORD coopSettings, const JoyStickInfo &info ) JoyStick(info.vendor, buffered, info.devId, creator),
: JoyStick(info.vendor, buffered, info.devId, creator) mDirectInput(pDI),
coopSetting(coopSettings),
mJoyStick(0),
mJoyInfo(info),
mFfDevice(0)
{ {
mDirectInput = pDI;
coopSetting = coopSettings;
mJoyStick = 0;
deviceGuid = info.deviceID;
ff_device = 0;
} }
//--------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------//
Win32JoyStick::~Win32JoyStick() Win32JoyStick::~Win32JoyStick()
{ {
delete ff_device; delete mFfDevice;
if(mJoyStick) if(mJoyStick)
{ {
...@@ -68,80 +80,86 @@ Win32JoyStick::~Win32JoyStick() ...@@ -68,80 +80,86 @@ Win32JoyStick::~Win32JoyStick()
} }
//Return joystick to pool //Return joystick to pool
JoyStickInfo js; static_cast<Win32InputManager*>(mCreator)->_returnJoyStick(mJoyInfo);
js.deviceID = deviceGuid;
js.devId = mDevID;
js.vendor = mVendor;
static_cast<Win32InputManager*>(mCreator)->_returnJoyStick(js);
} }
//--------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------//
void Win32JoyStick::_initialize() void Win32JoyStick::_initialize()
{ {
if (mJoyInfo.isXInput)
{
_enumerate();
}
else
{
//Clear old state //Clear old state
mState.mAxes.clear(); mState.mAxes.clear();
if (ff_device) delete mFfDevice;
{ mFfDevice = 0;
delete ff_device;
ff_device = 0;
}
// Create direct input joystick device. DIPROPDWORD dipdw;
if(FAILED(mDirectInput->CreateDevice(deviceGuid, &mJoyStick, NULL)))
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = JOYSTICK_DX_BUFFERSIZE;
if(FAILED(mDirectInput->CreateDevice(mJoyInfo.deviceID, &mJoyStick, NULL)))
OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not initialize joy device!"); OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not initialize joy device!");
// Set DIJoystick2 data format.
if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2))) if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2)))
OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> data format error!"); OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> data format error!");
// Set cooperative level as specified when creating input manager.
HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle(); HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle();
if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting))) if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting)))
OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> failed to set cooperation level!"); OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> failed to set cooperation level!");
// Set buffer size.
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = JOYSTICK_DX_BUFFERSIZE;
if( FAILED(mJoyStick->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) ) if( FAILED(mJoyStick->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) )
OIS_EXCEPT( E_General, "Win32JoyStick::_initialize >> Failed to set buffer size property" ); OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set buffer size property" );
// Enumerate all axes/buttons/sliders/force feedback/etc before aquiring //Enumerate all axes/buttons/sliders/etc before aquiring
_enumerate(); _enumerate();
mState.clear(); mState.clear();
capture(); capture();
}
} }
//--------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------//
void Win32JoyStick::_enumerate() void Win32JoyStick::_enumerate()
{ {
if (mJoyInfo.isXInput)
{
mPOVs = 1;
mState.mButtons.resize(XINPUT_TRANSLATED_BUTTON_COUNT);
mState.mAxes.resize(XINPUT_TRANSLATED_AXIS_COUNT);
}
else
{
// Get joystick capabilities. // Get joystick capabilities.
mDIJoyCaps.dwSize = sizeof(DIDEVCAPS); mDIJoyCaps.dwSize = sizeof(DIDEVCAPS);
if( FAILED(mJoyStick->GetCapabilities(&mDIJoyCaps)) ) if( FAILED(mJoyStick->GetCapabilities(&mDIJoyCaps)) )
OIS_EXCEPT( E_General, "Win32JoyStick::_enumerate >> Failed to get capabilities" ); OIS_EXCEPT( E_General, "Win32JoyStick::_enumerate >> Failed to get capabilities" );
// => Number of POVs
mPOVs = (short)mDIJoyCaps.dwPOVs; mPOVs = (short)mDIJoyCaps.dwPOVs;
// => Number of buttons and axes.
mState.mButtons.resize(mDIJoyCaps.dwButtons); mState.mButtons.resize(mDIJoyCaps.dwButtons);
mState.mAxes.resize(mDIJoyCaps.dwAxes); mState.mAxes.resize(mDIJoyCaps.dwAxes);
// Enumerate all Force Feedback effects (if any)
mJoyStick->EnumEffects(DIEnumEffectsCallback, this, DIEFT_ALL);
//Reset the axis mapping enumeration value //Reset the axis mapping enumeration value
_AxisNumber = 0; _AxisNumber = 0;
// Enumerate and set axis constraints (and check FF Axes) //Enumerate Force Feedback (if any)
mJoyStick->EnumEffects(DIEnumEffectsCallback, this, DIEFT_ALL);
//Enumerate and set axis constraints (and check FF Axes)
mJoyStick->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_AXIS); mJoyStick->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_AXIS);
}
} }
//--------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------//
...@@ -190,19 +208,19 @@ BOOL CALLBACK Win32JoyStick::DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTAN ...@@ -190,19 +208,19 @@ BOOL CALLBACK Win32JoyStick::DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTAN
//Check if FF Axes, and if so, increment counter //Check if FF Axes, and if so, increment counter
if((lpddoi->dwFlags & DIDOI_FFACTUATOR) != 0 ) if((lpddoi->dwFlags & DIDOI_FFACTUATOR) != 0 )
{ {
if( _this->ff_device ) if( _this->mFfDevice )
{ {
_this->ff_device->_addFFAxis(); _this->mFfDevice->_addFFAxis();
} }
} }
//Force the flags for gain and auto-center support to true, //Force the flags for gain and auto-center support to true,
//as DInput has no API to query the device for these capabilities //as DInput has no API to query the device for these capabilities
//(the only way to know is to try them ...) //(the only way to know is to try them ...)
if( _this->ff_device ) if( _this->mFfDevice )
{ {
_this->ff_device->_setGainSupport(true); _this->mFfDevice->_setGainSupport(true);
_this->ff_device->_setAutoCenterSupport(true); _this->mFfDevice->_setAutoCenterSupport(true);
} }
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
...@@ -214,10 +232,10 @@ BOOL CALLBACK Win32JoyStick::DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID ...@@ -214,10 +232,10 @@ BOOL CALLBACK Win32JoyStick::DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID
Win32JoyStick* _this = (Win32JoyStick*)pvRef; Win32JoyStick* _this = (Win32JoyStick*)pvRef;
//Create the FF instance only after we know there is at least one effect type //Create the FF instance only after we know there is at least one effect type
if( _this->ff_device == 0 ) if( _this->mFfDevice == 0 )
_this->ff_device = new Win32ForceFeedback(_this->mJoyStick, &_this->mDIJoyCaps); _this->mFfDevice = new Win32ForceFeedback(_this->mJoyStick, &_this->mDIJoyCaps);
_this->ff_device->_addEffectSupport( pdei ); _this->mFfDevice->_addEffectSupport(pdei);
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
...@@ -225,6 +243,147 @@ BOOL CALLBACK Win32JoyStick::DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID ...@@ -225,6 +243,147 @@ BOOL CALLBACK Win32JoyStick::DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID
//--------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------//
void Win32JoyStick::capture() void Win32JoyStick::capture()
{ {
if (mJoyInfo.isXInput)
{
XINPUT_STATE inputState;
if (XInputGetState((DWORD)mJoyInfo.xInputDev, &inputState) != ERROR_SUCCESS)
memset(&inputState, 0, sizeof(inputState));
//Sticks and triggers
bool axisMoved[XINPUT_TRANSLATED_AXIS_COUNT] = {false,false,false,false,false,false};
if (std::abs(inputState.Gamepad.sThumbLY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
{
int value = -(int)inputState.Gamepad.sThumbLY;
mState.mAxes[0].rel = value - mState.mAxes[0].abs;
mState.mAxes[0].abs = value;
axisMoved[0] = mState.mAxes[0].rel != 0;
}
else
{
mState.mAxes[0].rel = 0;
mState.mAxes[0].abs = 0;
}
if (std::abs(inputState.Gamepad.sThumbLX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
{
mState.mAxes[1].rel = inputState.Gamepad.sThumbLX - mState.mAxes[1].abs;
mState.mAxes[1].abs = inputState.Gamepad.sThumbLX;
axisMoved[1] = mState.mAxes[1].rel != 0;
}
else
{
mState.mAxes[1].rel = 0;
mState.mAxes[1].abs = 0;
}
if (std::abs(inputState.Gamepad.sThumbRY) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
{
int value = -(int)inputState.Gamepad.sThumbRY;
mState.mAxes[2].rel = value - mState.mAxes[2].abs;
mState.mAxes[2].abs = value;
axisMoved[2] = mState.mAxes[2].rel != 0;
}
else
{
mState.mAxes[2].rel = 0;
mState.mAxes[2].abs = 0;
}
if (std::abs(inputState.Gamepad.sThumbRX) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
{
mState.mAxes[3].rel = inputState.Gamepad.sThumbRX - mState.mAxes[3].abs;
mState.mAxes[3].abs = inputState.Gamepad.sThumbRX;
axisMoved[3] = mState.mAxes[3].rel != 0;
}
else
{
mState.mAxes[3].rel = 0;
mState.mAxes[3].abs = 0;
}
if (inputState.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
{
int value = (int)inputState.Gamepad.bLeftTrigger * 128;
if (value > 0)
value = min(value + 128, 32767);
mState.mAxes[4].rel = value - mState.mAxes[4].abs;
mState.mAxes[4].abs = value;
axisMoved[4] = mState.mAxes[4].rel != 0;
}
else
{
mState.mAxes[4].rel = 0;
mState.mAxes[4].abs = 0;
}
if (inputState.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
{
int value = (int)inputState.Gamepad.bRightTrigger * 128;
if (value > 0)
value = min(value + 128, 32767);
mState.mAxes[5].rel = value - mState.mAxes[5].abs;
mState.mAxes[5].abs = value;
axisMoved[5] = mState.mAxes[5].rel != 0;
}
else
{
mState.mAxes[5].rel = 0;
mState.mAxes[5].abs = 0;
}
//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;
}
}
}
}
else
{
DIDEVICEOBJECTDATA diBuff[JOYSTICK_DX_BUFFERSIZE]; DIDEVICEOBJECTDATA diBuff[JOYSTICK_DX_BUFFERSIZE];
DWORD entries = JOYSTICK_DX_BUFFERSIZE; DWORD entries = JOYSTICK_DX_BUFFERSIZE;
...@@ -349,6 +508,7 @@ void Win32JoyStick::capture() ...@@ -349,6 +508,7 @@ void Win32JoyStick::capture()
if( mListener->sliderMoved( temp, i ) == false ) if( mListener->sliderMoved( temp, i ) == false )
return; return;
} }
}
} }
//--------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------//
...@@ -409,11 +569,132 @@ void Win32JoyStick::setBuffered(bool buffered) ...@@ -409,11 +569,132 @@ void Win32JoyStick::setBuffered(bool buffered)
//--------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------//
Interface* Win32JoyStick::queryInterface(Interface::IType type) Interface* Win32JoyStick::queryInterface(Interface::IType type)
{ {
//Thought about using covariant return type here.. however, if( mFfDevice && type == Interface::ForceFeedback )
//some devices may allow LED light changing, or other interface stuff return mFfDevice;
if( ff_device && type == Interface::ForceFeedback )
return ff_device;
else else
return 0; return 0;
} }
//--------------------------------------------------------------------------------------------------//
void Win32JoyStick::CheckXInputDevices(JoyStickInfoList &joys)
{
IWbemLocator* pIWbemLocator = NULL;
IEnumWbemClassObject* pEnumDevices = NULL;
IWbemClassObject* pDevices[20] = {0};
IWbemServices* pIWbemServices = NULL;
BSTR bstrNamespace = NULL;
BSTR bstrDeviceID = NULL;
BSTR bstrClassName = NULL;
DWORD uReturned = 0;
bool bIsXinputDevice= false;
DWORD iDevice = 0;
int xDevice = 0;
VARIANT var;
HRESULT hr;
if(joys.size() == 0)
return;
// CoInit if needed
hr = CoInitialize(NULL);
bool bCleanupCOM = SUCCEEDED(hr);
// Create WMI
hr = CoCreateInstance(__uuidof(WbemLocator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator);
if( FAILED(hr) || pIWbemLocator == NULL )
goto LCleanup;
bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );
if( bstrNamespace == NULL )
goto LCleanup;
bstrClassName = SysAllocString( L"Win32_PNPEntity" );
if( bstrClassName == NULL )
goto LCleanup;
bstrDeviceID = SysAllocString( L"DeviceID" );
if( bstrDeviceID == NULL )
goto LCleanup;
// Connect to WMI
hr = pIWbemLocator->ConnectServer( bstrNamespace, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices );
if( FAILED(hr) || pIWbemServices == NULL )
goto LCleanup;
// Switch security level to IMPERSONATE.
CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
hr = pIWbemServices->CreateInstanceEnum( bstrClassName, 0, NULL, &pEnumDevices );
if( FAILED(hr) || pEnumDevices == NULL )
goto LCleanup;
// Loop over all devices
for( ;; )
{
// Get 20 at a time
hr = pEnumDevices->Next(5000, 20, pDevices, &uReturned);
if( FAILED(hr) )
goto LCleanup;
if( uReturned == 0 )
break;
for(iDevice = 0; iDevice < uReturned; iDevice++)
{
// For each device, get its device ID
hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, NULL, NULL);
if(SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL)
{
// Check if the device ID contains "IG_". If it does, then it's an XInput device - This information can not be found from DirectInput
if(wcsstr(var.bstrVal, L"IG_"))
{
// If it does, then get the VID/PID from var.bstrVal
DWORD dwPid = 0, dwVid = 0;
WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" );
if(strVid && swscanf_s( strVid, L"VID_%4X", &dwVid ) != 1)
dwVid = 0;
WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" );
if(strPid && swscanf_s( strPid, L"PID_%4X", &dwPid ) != 1)
dwPid = 0;
// Compare the VID/PID to the DInput device
DWORD dwVidPid = MAKELONG(dwVid, dwPid);
for(JoyStickInfoList::iterator i = joys.begin(); i != joys.end(); ++i)
{
if(dwVidPid == i->productGuid.Data1)
{
i->isXInput = true;
i->xInputDev = xDevice;
}
}
if(joys.size() == 0)
goto LCleanup;
}
}
SAFE_RELEASE(pDevices[iDevice]);
}
}
LCleanup:
if(bstrNamespace)
SysFreeString(bstrNamespace);
if(bstrDeviceID)
SysFreeString(bstrDeviceID);
if(bstrClassName)
SysFreeString(bstrClassName);
for(iDevice=0; iDevice < 20; iDevice++)
SAFE_RELEASE(pDevices[iDevice]);
SAFE_RELEASE(pEnumDevices);
SAFE_RELEASE(pIWbemLocator);
SAFE_RELEASE(pIWbemServices);
if(bCleanupCOM)
CoUninitialize();
}
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