winDirectInput.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platformWin32/platformWin32.h"
  23. #include "platform/platformVideo.h"
  24. #include "platformWin32/winDirectInput.h"
  25. #include "platformWin32/winDInputDevice.h"
  26. #include "platform/event.h"
  27. #include "console/console.h"
  28. #include "console/consoleTypes.h"
  29. //------------------------------------------------------------------------------
  30. // Static class variables:
  31. bool DInputManager::smKeyboardEnabled = true;
  32. bool DInputManager::smMouseEnabled = false;
  33. bool DInputManager::smJoystickEnabled = false;
  34. // Type definitions:
  35. typedef HRESULT (WINAPI* FN_DirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter);
  36. //------------------------------------------------------------------------------
  37. DInputManager::DInputManager()
  38. {
  39. mEnabled = false;
  40. mDInputLib = NULL;
  41. mDInputInterface = NULL;
  42. mKeyboardActive = mMouseActive = mJoystickActive = false;
  43. }
  44. //------------------------------------------------------------------------------
  45. void DInputManager::init()
  46. {
  47. Con::addVariable( "pref::Input::KeyboardEnabled", TypeBool, &smKeyboardEnabled );
  48. Con::addVariable( "pref::Input::MouseEnabled", TypeBool, &smMouseEnabled );
  49. Con::addVariable( "pref::Input::JoystickEnabled", TypeBool, &smJoystickEnabled );
  50. }
  51. //------------------------------------------------------------------------------
  52. bool DInputManager::enable()
  53. {
  54. FN_DirectInputCreate fnDInputCreate;
  55. disable();
  56. mDInputLib = LoadLibrary( dT("DInput8.dll") );
  57. if ( mDInputLib )
  58. {
  59. fnDInputCreate = (FN_DirectInputCreate) GetProcAddress( mDInputLib, "DirectInput8Create" );
  60. if ( fnDInputCreate )
  61. {
  62. bool result = SUCCEEDED( fnDInputCreate( winState.appInstance, DIRECTINPUT_VERSION,
  63. IID_IDirectInput8, reinterpret_cast<void**>(&mDInputInterface), NULL ));
  64. if ( result )
  65. {
  66. enumerateDevices();
  67. mEnabled = true;
  68. return true;
  69. }
  70. }
  71. }
  72. disable();
  73. return false;
  74. }
  75. //------------------------------------------------------------------------------
  76. void DInputManager::disable()
  77. {
  78. unacquire( SI_ANY, SI_ANY );
  79. DInputDevice* dptr;
  80. iterator ptr = begin();
  81. while ( ptr != end() )
  82. {
  83. dptr = dynamic_cast<DInputDevice*>( *ptr );
  84. if ( dptr )
  85. {
  86. removeObject( dptr );
  87. //if ( dptr->getManager() )
  88. //dptr->getManager()->unregisterObject( dptr );
  89. delete dptr;
  90. ptr = begin();
  91. }
  92. else
  93. ptr++;
  94. }
  95. if ( mDInputInterface )
  96. {
  97. mDInputInterface->Release();
  98. mDInputInterface = NULL;
  99. }
  100. if ( mDInputLib )
  101. {
  102. FreeLibrary( mDInputLib );
  103. mDInputLib = NULL;
  104. }
  105. mEnabled = false;
  106. }
  107. //------------------------------------------------------------------------------
  108. void DInputManager::onDeleteNotify( SimObject* object )
  109. {
  110. Parent::onDeleteNotify( object );
  111. }
  112. //------------------------------------------------------------------------------
  113. bool DInputManager::onAdd()
  114. {
  115. if ( !Parent::onAdd() )
  116. return false;
  117. acquire( SI_ANY, SI_ANY );
  118. return true;
  119. }
  120. //------------------------------------------------------------------------------
  121. void DInputManager::onRemove()
  122. {
  123. unacquire( SI_ANY, SI_ANY );
  124. Parent::onRemove();
  125. }
  126. //------------------------------------------------------------------------------
  127. bool DInputManager::acquire( U8 deviceType, U8 deviceID )
  128. {
  129. bool anyActive = false;
  130. DInputDevice* dptr;
  131. for ( iterator ptr = begin(); ptr != end(); ptr++ )
  132. {
  133. dptr = dynamic_cast<DInputDevice*>( *ptr );
  134. if ( dptr
  135. && ( ( deviceType == SI_ANY ) || ( dptr->getDeviceType() == deviceType ) )
  136. && ( ( deviceID == SI_ANY ) || ( dptr->getDeviceID() == deviceID ) ) )
  137. {
  138. if ( dptr->acquire() )
  139. anyActive = true;
  140. }
  141. }
  142. return anyActive;
  143. }
  144. //------------------------------------------------------------------------------
  145. void DInputManager::unacquire( U8 deviceType, U8 deviceID )
  146. {
  147. DInputDevice* dptr;
  148. for ( iterator ptr = begin(); ptr != end(); ptr++ )
  149. {
  150. dptr = dynamic_cast<DInputDevice*>( *ptr );
  151. if ( dptr
  152. && ( ( deviceType == SI_ANY ) || ( dptr->getDeviceType() == deviceType ) )
  153. && ( ( deviceID == SI_ANY ) || ( dptr->getDeviceID() == deviceID ) ) )
  154. dptr->unacquire();
  155. }
  156. }
  157. //------------------------------------------------------------------------------
  158. void DInputManager::process()
  159. {
  160. DInputDevice* dptr;
  161. for ( iterator ptr = begin(); ptr != end(); ptr++ )
  162. {
  163. dptr = dynamic_cast<DInputDevice*>( *ptr );
  164. if ( dptr )
  165. dptr->process();
  166. }
  167. }
  168. //------------------------------------------------------------------------------
  169. void DInputManager::enumerateDevices()
  170. {
  171. if ( mDInputInterface )
  172. {
  173. DInputDevice::init();
  174. DInputDevice::smDInputInterface = mDInputInterface;
  175. mDInputInterface->EnumDevices( DI8DEVTYPE_KEYBOARD, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY );
  176. mDInputInterface->EnumDevices( DI8DEVTYPE_MOUSE, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY );
  177. mDInputInterface->EnumDevices( DI8DEVTYPE_JOYSTICK, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY );
  178. mDInputInterface->EnumDevices( DI8DEVTYPE_GAMEPAD, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY );
  179. }
  180. }
  181. //------------------------------------------------------------------------------
  182. BOOL CALLBACK DInputManager::EnumDevicesProc( const DIDEVICEINSTANCE* pddi, LPVOID pvRef )
  183. {
  184. DInputManager* manager = (DInputManager*) pvRef;
  185. DInputDevice* newDevice = new DInputDevice( pddi );
  186. manager->addObject( newDevice );
  187. if ( !newDevice->create() )
  188. {
  189. manager->removeObject( newDevice );
  190. delete newDevice;
  191. }
  192. return (DIENUM_CONTINUE);
  193. }
  194. //------------------------------------------------------------------------------
  195. bool DInputManager::enableKeyboard()
  196. {
  197. DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
  198. if ( !mgr || !mgr->isEnabled() )
  199. return( false );
  200. if ( smKeyboardEnabled && mgr->isKeyboardActive() )
  201. return( true );
  202. smKeyboardEnabled = true;
  203. if ( Input::isActive() )
  204. smKeyboardEnabled = mgr->activateKeyboard();
  205. if ( smKeyboardEnabled )
  206. {
  207. Con::printf( "DirectInput keyboard enabled." );
  208. }
  209. else
  210. {
  211. Con::warnf( "DirectInput keyboard failed to enable!" );
  212. }
  213. return( smKeyboardEnabled );
  214. }
  215. //------------------------------------------------------------------------------
  216. void DInputManager::disableKeyboard()
  217. {
  218. DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
  219. if ( !mgr || !mgr->isEnabled() || !smKeyboardEnabled )
  220. return;
  221. mgr->deactivateKeyboard();
  222. smKeyboardEnabled = false;
  223. Con::printf( "DirectInput keyboard disabled." );
  224. }
  225. //------------------------------------------------------------------------------
  226. bool DInputManager::isKeyboardEnabled()
  227. {
  228. return( smKeyboardEnabled );
  229. }
  230. //------------------------------------------------------------------------------
  231. bool DInputManager::activateKeyboard()
  232. {
  233. if ( !mEnabled || !Input::isActive() || !smKeyboardEnabled )
  234. return( false );
  235. // Acquire only one keyboard:
  236. mKeyboardActive = acquire( KeyboardDeviceType, 0 );
  237. return( mKeyboardActive );
  238. }
  239. //------------------------------------------------------------------------------
  240. void DInputManager::deactivateKeyboard()
  241. {
  242. if ( mEnabled && mKeyboardActive )
  243. {
  244. unacquire( KeyboardDeviceType, SI_ANY );
  245. mKeyboardActive = false;
  246. }
  247. }
  248. //------------------------------------------------------------------------------
  249. bool DInputManager::enableMouse()
  250. {
  251. DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
  252. if ( !mgr || !mgr->isEnabled() )
  253. return( false );
  254. if ( smMouseEnabled && mgr->isMouseActive() )
  255. return( true );
  256. smMouseEnabled = true;
  257. if ( Input::isActive() )
  258. smMouseEnabled = mgr->activateMouse();
  259. if ( smMouseEnabled )
  260. {
  261. Con::printf( "DirectInput mouse enabled." );
  262. }
  263. else
  264. {
  265. Con::warnf( "DirectInput mouse failed to enable!" );
  266. }
  267. return( smMouseEnabled );
  268. }
  269. //------------------------------------------------------------------------------
  270. void DInputManager::disableMouse()
  271. {
  272. DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
  273. if ( !mgr || !mgr->isEnabled() || !smMouseEnabled )
  274. return;
  275. mgr->deactivateMouse();
  276. smMouseEnabled = false;
  277. Con::printf( "DirectInput mouse disabled." );
  278. }
  279. //------------------------------------------------------------------------------
  280. bool DInputManager::isMouseEnabled()
  281. {
  282. return( smMouseEnabled );
  283. }
  284. //------------------------------------------------------------------------------
  285. bool DInputManager::activateMouse()
  286. {
  287. if ( !mEnabled || !Input::isActive() || !smMouseEnabled )
  288. return( false );
  289. mMouseActive = acquire( MouseDeviceType, SI_ANY );
  290. return( mMouseActive );
  291. }
  292. //------------------------------------------------------------------------------
  293. void DInputManager::deactivateMouse()
  294. {
  295. if ( mEnabled && mMouseActive )
  296. {
  297. unacquire( MouseDeviceType, SI_ANY );
  298. mMouseActive = false;
  299. }
  300. }
  301. //------------------------------------------------------------------------------
  302. bool DInputManager::enableJoystick()
  303. {
  304. DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
  305. if ( !mgr || !mgr->isEnabled() )
  306. return( false );
  307. if ( smJoystickEnabled && mgr->isJoystickActive() )
  308. return( true );
  309. smJoystickEnabled = true;
  310. if ( Input::isActive() )
  311. smJoystickEnabled = mgr->activateJoystick();
  312. if ( smJoystickEnabled )
  313. {
  314. Con::printf( "DirectInput joystick enabled." );
  315. }
  316. else
  317. {
  318. Con::warnf( "DirectInput joystick failed to enable!" );
  319. }
  320. return( smJoystickEnabled );
  321. }
  322. //------------------------------------------------------------------------------
  323. void DInputManager::disableJoystick()
  324. {
  325. DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
  326. if ( !mgr || !mgr->isEnabled() || !smJoystickEnabled )
  327. return;
  328. mgr->deactivateJoystick();
  329. smJoystickEnabled = false;
  330. Con::printf( "DirectInput joystick disabled." );
  331. }
  332. //------------------------------------------------------------------------------
  333. bool DInputManager::isJoystickEnabled()
  334. {
  335. return( smJoystickEnabled );
  336. }
  337. //------------------------------------------------------------------------------
  338. bool DInputManager::activateJoystick()
  339. {
  340. if ( !mEnabled || !Input::isActive() || !smJoystickEnabled )
  341. return( false );
  342. mJoystickActive = acquire( JoystickDeviceType, SI_ANY );
  343. return( mJoystickActive );
  344. }
  345. //------------------------------------------------------------------------------
  346. void DInputManager::deactivateJoystick()
  347. {
  348. if ( mEnabled && mJoystickActive )
  349. {
  350. unacquire( JoystickDeviceType, SI_ANY );
  351. mJoystickActive = false;
  352. }
  353. }
  354. //------------------------------------------------------------------------------
  355. const char* DInputManager::getJoystickAxesString( U32 deviceID )
  356. {
  357. DInputDevice* dptr;
  358. for ( iterator ptr = begin(); ptr != end(); ptr++ )
  359. {
  360. dptr = dynamic_cast<DInputDevice*>( *ptr );
  361. if ( dptr && ( dptr->getDeviceType() == JoystickDeviceType ) && ( dptr->getDeviceID() == deviceID ) )
  362. return( dptr->getJoystickAxesString() );
  363. }
  364. return( "" );
  365. }