1 /*
2 The zlib/libpng License
3
4 Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
5
6 This software is provided 'as-is', without any express or implied warranty. In no event will
7 the authors be held liable for any damages arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose, including commercial
10 applications, and to alter it and redistribute it freely, subject to the following
11 restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not claim that
14 you wrote the original software. If you use this software in a product,
15 an acknowledgment in the product documentation would be appreciated but is
16 not required.
17
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20
21 3. This notice may not be removed or altered from any source distribution.
22 */
23 #include "win32/Win32InputManager.h"
24 #include "win32/Win32KeyBoard.h"
25 #include "win32/Win32Mouse.h"
26 #include "win32/Win32JoyStick.h"
27 #include "OISException.h"
28
29 using namespace OIS;
30
31 //--------------------------------------------------------------------------------//
Win32InputManager()32 Win32InputManager::Win32InputManager() : InputManager("Win32InputManager")
33 {
34 hWnd = 0;
35 mDirectInput = 0;
36
37 kbSettings = 0;
38 mouseSettings = 0;
39 joySettings = 0;
40
41 joySticks = 0;
42 keyboardUsed = mouseUsed = false;
43
44 //Setup our internal factories
45 mFactories.push_back(this);
46 }
47
48 //--------------------------------------------------------------------------------//
~Win32InputManager()49 Win32InputManager::~Win32InputManager()
50 {
51 if( mDirectInput )
52 {
53 mDirectInput->Release();
54 mDirectInput = 0;
55 }
56 }
57
58 //--------------------------------------------------------------------------------//
_initialize(ParamList & paramList)59 void Win32InputManager::_initialize( ParamList ¶mList )
60 {
61 HINSTANCE hInst = 0;
62 HRESULT hr;
63
64
65 //First of all, get the Windows Handle and Instance
66 ParamList::iterator i = paramList.find("WINDOW");
67 if( i == paramList.end() )
68 OIS_EXCEPT( E_InvalidParam, "Win32InputManager::Win32InputManager >> No HWND found!" );
69
70 // Get number as 64 bit and then convert. Handles the case of 32 or 64 bit HWND
71 #ifdef _MSC_VER
72 unsigned __int64 handle = _strtoui64(i->second.c_str(), 0, 10);
73 #else
74 unsigned __int64 handle = strtoull(i->second.c_str(), 0, 10);
75 #endif
76 hWnd = (HWND)handle;
77
78 if( IsWindow(hWnd) == 0 )
79 OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> The sent HWND is not valid!");
80
81 hInst = GetModuleHandle(0);
82
83 //Create the device
84 hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL );
85 if (FAILED(hr))
86 OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> Not able to init DirectX8 Input!");
87
88 //Ok, now we have DirectInput, parse whatever extra settings were sent to us
89 _parseConfigSettings( paramList );
90
91 // Enumerate devices ...
92 _enumerateDevices();
93 }
94
95 //--------------------------------------------------------------------------------//
_parseConfigSettings(ParamList & paramList)96 void Win32InputManager::_parseConfigSettings( ParamList ¶mList )
97 {
98 //Here we pick up settings such as a device's cooperation mode
99 std::map<std::string, DWORD> temp;
100 temp["DISCL_BACKGROUND"] = DISCL_BACKGROUND;
101 temp["DISCL_EXCLUSIVE"] = DISCL_EXCLUSIVE;
102 temp["DISCL_FOREGROUND"] = DISCL_FOREGROUND;
103 temp["DISCL_NONEXCLUSIVE"] = DISCL_NONEXCLUSIVE;
104 temp["DISCL_NOWINKEY"] = DISCL_NOWINKEY;
105
106 //Check for pairs: ie. ("w32_keyboard","DISCL_NOWINKEY")("w32_keyboard","DISCL_FOREGROUND")
107 ParamList::iterator i = paramList.begin(), e = paramList.end();
108 for( ; i != e; ++i )
109 {
110 if( i->first == "w32_keyboard" )
111 kbSettings |= temp[i->second];
112 else if( i->first == "w32_mouse" )
113 mouseSettings |= temp[i->second];
114 else if( i->first == "w32_joystick" )
115 joySettings |= temp[i->second];
116 }
117 if( kbSettings == 0 ) kbSettings = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY;
118 if( mouseSettings == 0 ) mouseSettings = DISCL_FOREGROUND | DISCL_EXCLUSIVE;
119 if( joySettings == 0 ) joySettings = DISCL_FOREGROUND | DISCL_EXCLUSIVE;
120 }
121
122 //--------------------------------------------------------------------------------//
_enumerateDevices()123 void Win32InputManager::_enumerateDevices()
124 {
125 //Enumerate all attached devices
126 mDirectInput->EnumDevices(NULL, _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY);
127
128 #ifdef OIS_WIN32_XINPUT_SUPPORT
129 //let's check how many possible XInput devices we may have (max 4)...
130 for(int i = 0; i < 3; ++i)
131 {
132 XINPUT_STATE state;
133 if(XInputGetState(i, &state) != ERROR_DEVICE_NOT_CONNECTED)
134 { //Once we found 1, just check our whole list against devices
135 Win32JoyStick::CheckXInputDevices(unusedJoyStickList);
136 break;
137 }
138 }
139 #endif
140 }
141
142 //--------------------------------------------------------------------------------//
_DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi,LPVOID pvRef)143 BOOL CALLBACK Win32InputManager::_DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
144 {
145 Win32InputManager *_this_ = static_cast<Win32InputManager*>(pvRef);
146
147 // Register only game devices (keyboard and mouse are managed differently).
148 if( GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK ||
149 GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD ||
150 GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_1STPERSON ||
151 GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_DRIVING ||
152 GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_FLIGHT ||
153 GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_SUPPLEMENTAL)
154 {
155 JoyStickInfo jsInfo;
156 jsInfo.isXInput = false;
157 jsInfo.productGuid = lpddi->guidProduct;
158 jsInfo.deviceID = lpddi->guidInstance;
159 jsInfo.vendor = lpddi->tszInstanceName;
160 jsInfo.devId = _this_->joySticks;
161
162 _this_->joySticks++;
163
164 _this_->unusedJoyStickList.push_back( jsInfo );
165 }
166
167 return DIENUM_CONTINUE;
168 }
169
170 //----------------------------------------------------------------------------//
_returnJoyStick(const JoyStickInfo & joystick)171 void Win32InputManager::_returnJoyStick(const JoyStickInfo& joystick)
172 {
173 unusedJoyStickList.push_back(joystick);
174 }
175
176 //----------------------------------------------------------------------------//
freeDeviceList()177 DeviceList Win32InputManager::freeDeviceList()
178 {
179 DeviceList ret;
180
181 if( keyboardUsed == false )
182 ret.insert(std::make_pair(OISKeyboard, mInputSystemName));
183
184 if( mouseUsed == false )
185 ret.insert(std::make_pair(OISMouse, mInputSystemName));
186
187 for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
188 ret.insert(std::make_pair(OISJoyStick, i->vendor));
189
190 return ret;
191 }
192
193 //----------------------------------------------------------------------------//
totalDevices(Type iType)194 int Win32InputManager::totalDevices(Type iType)
195 {
196 switch(iType)
197 {
198 case OISKeyboard: return 1;
199 case OISMouse: return 1;
200 case OISJoyStick: return joySticks;
201 default: return 0;
202 }
203 }
204
205 //----------------------------------------------------------------------------//
freeDevices(Type iType)206 int Win32InputManager::freeDevices(Type iType)
207 {
208 switch(iType)
209 {
210 case OISKeyboard: return keyboardUsed ? 0 : 1;
211 case OISMouse: return mouseUsed ? 0 : 1;
212 case OISJoyStick: return (int)unusedJoyStickList.size();
213 default: return 0;
214 }
215 }
216
217 //----------------------------------------------------------------------------//
vendorExist(Type iType,const std::string & vendor)218 bool Win32InputManager::vendorExist(Type iType, const std::string & vendor)
219 {
220 if( (iType == OISKeyboard || iType == OISMouse) && vendor == mInputSystemName )
221 {
222 return true;
223 }
224 else if( iType == OISJoyStick )
225 {
226 for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
227 if(i->vendor == vendor)
228 return true;
229 }
230
231 return false;
232 }
233
234 //----------------------------------------------------------------------------//
createObject(InputManager * creator,Type iType,bool bufferMode,const std::string & vendor)235 Object* Win32InputManager::createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor)
236 {
237 Object *obj = 0;
238
239 switch(iType)
240 {
241 case OISKeyboard:
242 {
243 if( keyboardUsed == false )
244 obj = new Win32Keyboard(this, mDirectInput, bufferMode, kbSettings);
245 break;
246 }
247 case OISMouse:
248 {
249 if( mouseUsed == false )
250 obj = new Win32Mouse(this, mDirectInput, bufferMode, mouseSettings);
251 break;
252 }
253 case OISJoyStick:
254 {
255 for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
256 {
257 if(vendor == "" || i->vendor == vendor)
258 {
259 obj = new Win32JoyStick(this, mDirectInput, bufferMode, joySettings, *i);
260 unusedJoyStickList.erase(i);
261 break;
262 }
263 }
264 break;
265 }
266 default:
267 break;
268 }
269
270 if( obj == 0 )
271 OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
272
273 return obj;
274 }
275
276 //----------------------------------------------------------------------------//
destroyObject(Object * obj)277 void Win32InputManager::destroyObject(Object* obj)
278 {
279 delete obj;
280 }
281