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 //--------------------------------------------------------------------------------// 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 //--------------------------------------------------------------------------------// 49 Win32InputManager::~Win32InputManager() 50 { 51 if( mDirectInput ) 52 { 53 mDirectInput->Release(); 54 mDirectInput = 0; 55 } 56 } 57 58 //--------------------------------------------------------------------------------// 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 //--------------------------------------------------------------------------------// 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 //--------------------------------------------------------------------------------// 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 //--------------------------------------------------------------------------------// 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 //----------------------------------------------------------------------------// 171 void Win32InputManager::_returnJoyStick(const JoyStickInfo& joystick) 172 { 173 unusedJoyStickList.push_back(joystick); 174 } 175 176 //----------------------------------------------------------------------------// 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 //----------------------------------------------------------------------------// 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 //----------------------------------------------------------------------------// 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 //----------------------------------------------------------------------------// 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 //----------------------------------------------------------------------------// 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 //----------------------------------------------------------------------------// 277 void Win32InputManager::destroyObject(Object* obj) 278 { 279 delete obj; 280 } 281