winDInputDevice.cc 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393
  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. #ifndef INITGUID
  23. #define INITGUID
  24. #endif
  25. #include "math/mMath.h"
  26. #include "platformWin32/winDInputDevice.h"
  27. #include "console/console.h"
  28. #include "game/gameInterface.h"
  29. #include "string/unicode.h"
  30. // Static class data:
  31. LPDIRECTINPUT8 DInputDevice::smDInputInterface;
  32. U8 DInputDevice::smKeyboardCount;
  33. U8 DInputDevice::smMouseCount;
  34. U8 DInputDevice::smJoystickCount;
  35. U8 DInputDevice::smUnknownCount;
  36. U8 DInputDevice::smModifierKeys;
  37. bool DInputDevice::smKeyStates[256];
  38. bool DInputDevice::smInitialized = false;
  39. //------------------------------------------------------------------------------
  40. DInputDevice::DInputDevice( const DIDEVICEINSTANCE* dii )
  41. {
  42. mDeviceInstance = *dii;
  43. mDevice = NULL;
  44. mAcquired = false;
  45. mNeedSync = false;
  46. mObjInstance = NULL;
  47. mObjFormat = NULL;
  48. mObjInfo = NULL;
  49. mObjBuffer1 = NULL;
  50. mObjBuffer2 = NULL;
  51. mPrevObjBuffer = NULL;
  52. mPrevPOVPos = 0;
  53. switch ( GET_DIDEVICE_TYPE( mDeviceInstance.dwDevType ) )
  54. {
  55. case DI8DEVTYPE_KEYBOARD:
  56. mDeviceType = KeyboardDeviceType;
  57. mDeviceID = smKeyboardCount++;
  58. dSprintf( mName, 29, "keyboard%d", mDeviceID );
  59. break;
  60. case DI8DEVTYPE_MOUSE:
  61. mDeviceType = MouseDeviceType;
  62. mDeviceID = smMouseCount++;
  63. dSprintf( mName, 29, "mouse%d", mDeviceID );
  64. break;
  65. case DI8DEVTYPE_JOYSTICK:
  66. case DI8DEVTYPE_GAMEPAD:
  67. mDeviceType = JoystickDeviceType;
  68. mDeviceID = smJoystickCount++;
  69. dSprintf( mName, 29, "joystick%d", mDeviceID );
  70. break;
  71. default:
  72. mDeviceType = UnknownDeviceType;
  73. mDeviceID = smUnknownCount++;
  74. dSprintf( mName, 29, "unknown%d", mDeviceID );
  75. break;
  76. }
  77. }
  78. //------------------------------------------------------------------------------
  79. DInputDevice::~DInputDevice()
  80. {
  81. destroy();
  82. }
  83. //------------------------------------------------------------------------------
  84. void DInputDevice::init()
  85. {
  86. if ( !smInitialized )
  87. {
  88. dMemset( smKeyStates, 0, sizeof( smKeyStates ) );
  89. smInitialized = true;
  90. }
  91. // Reset all of the static variables:
  92. smDInputInterface = NULL;
  93. smKeyboardCount = 0;
  94. smMouseCount = 0;
  95. smJoystickCount = 0;
  96. smUnknownCount = 0;
  97. smModifierKeys = 0;
  98. }
  99. //------------------------------------------------------------------------------
  100. void DInputDevice::resetModifierKeys()
  101. {
  102. smModifierKeys = 0;
  103. setModifierKeys( 0 );
  104. }
  105. //------------------------------------------------------------------------------
  106. bool DInputDevice::create()
  107. {
  108. HRESULT result;
  109. if ( smDInputInterface )
  110. {
  111. result = smDInputInterface->CreateDevice( mDeviceInstance.guidInstance, &mDevice, NULL );
  112. if ( result == DI_OK )
  113. {
  114. mDeviceCaps.dwSize = sizeof( DIDEVCAPS );
  115. if ( FAILED( mDevice->GetCapabilities( &mDeviceCaps ) ) )
  116. {
  117. Con::errorf( " Failed to get the capabilities of the %s input device.", mName );
  118. return false;
  119. }
  120. if ( enumerateObjects() )
  121. {
  122. // Set the device's data format:
  123. DIDATAFORMAT dataFormat;
  124. dMemset( &dataFormat, 0, sizeof( DIDATAFORMAT ) );
  125. dataFormat.dwSize = sizeof( DIDATAFORMAT );
  126. dataFormat.dwObjSize = sizeof( DIOBJECTDATAFORMAT );
  127. dataFormat.dwFlags = ( mDeviceType == MouseDeviceType ) ? DIDF_RELAXIS : DIDF_ABSAXIS;
  128. dataFormat.dwDataSize = mObjBufferSize;
  129. dataFormat.dwNumObjs = mObjCount;
  130. dataFormat.rgodf = mObjFormat;
  131. result = mDevice->SetDataFormat( &dataFormat );
  132. if ( FAILED( result ) )
  133. {
  134. Con::errorf( " Failed to set the data format for the %s input device.", mName );
  135. return false;
  136. }
  137. // Set up the data buffer for buffered input:
  138. DIPROPDWORD prop;
  139. prop.diph.dwSize = sizeof( DIPROPDWORD );
  140. prop.diph.dwHeaderSize = sizeof( DIPROPHEADER );
  141. prop.diph.dwObj = 0;
  142. prop.diph.dwHow = DIPH_DEVICE;
  143. if ( isPolled() )
  144. prop.dwData = mObjBufferSize;
  145. else
  146. prop.dwData = QUEUED_BUFFER_SIZE;
  147. result = mDevice->SetProperty( DIPROP_BUFFERSIZE, &prop.diph );
  148. if ( FAILED( result ) )
  149. {
  150. Con::errorf( " Failed to set the buffer size property for the %s input device.", mName );
  151. return false;
  152. }
  153. // If this device is a mouse, set it to relative axis mode:
  154. if ( mDeviceType == MouseDeviceType )
  155. {
  156. prop.diph.dwObj = 0;
  157. prop.diph.dwHow = DIPH_DEVICE;
  158. prop.dwData = DIPROPAXISMODE_REL;
  159. result = mDevice->SetProperty( DIPROP_AXISMODE, &prop.diph );
  160. if ( FAILED( result ) )
  161. {
  162. Con::errorf( " Failed to set relative axis mode for the %s input device.", mName );
  163. return false;
  164. }
  165. }
  166. }
  167. }
  168. else
  169. {
  170. Con::printf( " CreateDevice failed for the %s input device!", mName );
  171. return false;
  172. }
  173. }
  174. //Con::printf( " %s input device created.", mName );
  175. return true;
  176. }
  177. //------------------------------------------------------------------------------
  178. void DInputDevice::destroy()
  179. {
  180. if ( mDevice )
  181. {
  182. unacquire();
  183. mDevice->Release();
  184. mDevice = NULL;
  185. delete [] mObjInstance;
  186. delete [] mObjFormat;
  187. delete [] mObjInfo;
  188. delete [] mObjBuffer1;
  189. delete [] mObjBuffer2;
  190. mObjInstance = NULL;
  191. mObjFormat = NULL;
  192. mObjInfo = NULL;
  193. mObjBuffer1 = NULL;
  194. mObjBuffer2 = NULL;
  195. mPrevObjBuffer = NULL;
  196. mName[0] = 0;
  197. }
  198. }
  199. //------------------------------------------------------------------------------
  200. bool DInputDevice::acquire()
  201. {
  202. if ( mDevice )
  203. {
  204. if ( mAcquired )
  205. return( true );
  206. bool result = false;
  207. // Set the cooperative level:
  208. // (do this here so that we have a valid app window)
  209. DWORD coopLevel = DISCL_BACKGROUND;
  210. if ( mDeviceType == JoystickDeviceType)
  211. coopLevel |= DISCL_EXCLUSIVE;
  212. else
  213. coopLevel |= DISCL_NONEXCLUSIVE;
  214. result = mDevice->SetCooperativeLevel( winState.appWindow, coopLevel );
  215. if ( FAILED( result ) )
  216. {
  217. Con::errorf( "Failed to set the cooperative level for the %s input device.", mName );
  218. return false;
  219. }
  220. S32 code = mDevice->Acquire();
  221. result = SUCCEEDED( code );
  222. if ( result )
  223. {
  224. #ifdef TORQUE_DEBUG
  225. Con::printf( "%s input device acquired.", mName );
  226. #endif
  227. mAcquired = true;
  228. // Update all of the key states:
  229. if ( !isPolled() )
  230. mNeedSync = true;
  231. }
  232. else
  233. {
  234. const char* reason;
  235. switch ( code )
  236. {
  237. case DIERR_INVALIDPARAM: reason = "Invalid parameter" ; break;
  238. case DIERR_NOTINITIALIZED: reason = "Not initialized"; break;
  239. case DIERR_OTHERAPPHASPRIO: reason = "Other app has priority"; break;
  240. case S_FALSE: reason = "Already acquired"; break;
  241. default: reason = "Unknown error"; break;
  242. }
  243. Con::warnf( "%s input device NOT acquired: %s", mName, reason );
  244. }
  245. return( result );
  246. }
  247. return( false );
  248. }
  249. //------------------------------------------------------------------------------
  250. bool DInputDevice::unacquire()
  251. {
  252. if ( mDevice )
  253. {
  254. if ( !mAcquired )
  255. return( true );
  256. bool result = false;
  257. result = SUCCEEDED( mDevice->Unacquire() );
  258. if ( result )
  259. {
  260. #ifdef TORQUE_DEBUG
  261. Con::printf( "%s input device unacquired.", mName );
  262. #endif
  263. mAcquired = false;
  264. }
  265. else
  266. {
  267. Con::warnf( ConsoleLogEntry::General, "%s input device NOT unacquired.", mName );
  268. }
  269. return( result );
  270. }
  271. return( false );
  272. }
  273. //------------------------------------------------------------------------------
  274. BOOL CALLBACK DInputDevice::EnumObjectsProc( const DIDEVICEOBJECTINSTANCE* doi, LPVOID pvRef )
  275. {
  276. // Don't enumerate unknown types:
  277. if ( doi->guidType == GUID_Unknown )
  278. return (DIENUM_CONTINUE);
  279. // Reduce a couple pointers:
  280. DInputDevice* diDevice = (DInputDevice*) pvRef;
  281. DIDEVICEOBJECTINSTANCE* objInstance = &diDevice->mObjInstance[diDevice->mObjEnumCount];
  282. DIOBJECTDATAFORMAT* objFormat = &diDevice->mObjFormat[diDevice->mObjEnumCount];
  283. // Fill in the object instance structure:
  284. *objInstance = *doi;
  285. // DWORD objects must be DWORD aligned:
  286. if ( !(objInstance->dwType & DIDFT_BUTTON ) )
  287. diDevice->mObjBufferOfs = ( diDevice->mObjBufferOfs + 3 ) & ~3;
  288. objInstance->dwOfs = diDevice->mObjBufferOfs;
  289. // Fill in the object data format structure:
  290. objFormat->pguid = &objInstance->guidType;
  291. objFormat->dwType = objInstance->dwType;
  292. objFormat->dwFlags= 0;
  293. objFormat->dwOfs = diDevice->mObjBufferOfs;
  294. // Advance the enumeration counters:
  295. if ( objFormat->dwType & DIDFT_BUTTON )
  296. diDevice->mObjBufferOfs += SIZEOF_BUTTON;
  297. else
  298. diDevice->mObjBufferOfs += SIZEOF_AXIS;
  299. diDevice->mObjEnumCount++;
  300. return (DIENUM_CONTINUE);
  301. }
  302. //------------------------------------------------------------------------------
  303. bool DInputDevice::enumerateObjects()
  304. {
  305. if ( !mDevice )
  306. return false;
  307. // Calculate the needed buffer sizes and allocate them:
  308. mObjCount = ( mDeviceCaps.dwAxes + mDeviceCaps.dwButtons + mDeviceCaps.dwPOVs );
  309. mObjBufferSize = mObjCount * sizeof( DWORD );
  310. mObjInstance = new DIDEVICEOBJECTINSTANCE[mObjCount];
  311. mObjFormat = new DIOBJECTDATAFORMAT[mObjCount];
  312. mObjInfo = new ObjInfo[mObjCount];
  313. if ( isPolled() )
  314. {
  315. mObjBuffer1 = new U8[mObjBufferSize];
  316. dMemset( mObjBuffer1, 0, mObjBufferSize );
  317. mObjBuffer2 = new U8[mObjBufferSize];
  318. dMemset( mObjBuffer2, 0, mObjBufferSize );
  319. }
  320. mObjEnumCount = 0;
  321. mObjBufferOfs = 0;
  322. // Enumerate all of the 'objects' detected on the device:
  323. if ( FAILED( mDevice->EnumObjects( EnumObjectsProc, this, DIDFT_ALL ) ) )
  324. return false;
  325. // if we enumerated fewer objects that are supposedly available, reset the
  326. // object count
  327. if (mObjEnumCount < mObjCount)
  328. mObjCount = mObjEnumCount;
  329. mObjBufferSize = ( mObjBufferSize + 3 ) & ~3; // Fill in the actual size to nearest DWORD
  330. U32 buttonCount = 0;
  331. U32 povCount = 0;
  332. U32 xAxisCount = 0;
  333. U32 yAxisCount = 0;
  334. U32 zAxisCount = 0;
  335. U32 rAxisCount = 0;
  336. U32 uAxisCount = 0;
  337. U32 vAxisCount = 0;
  338. U32 sliderCount = 0;
  339. U32 keyCount = 0;
  340. U32 unknownCount = 0;
  341. // Fill in the device object's info structure:
  342. for ( U32 i = 0; i < mObjCount; i++ )
  343. {
  344. if ( mObjInstance[i].guidType == GUID_Button )
  345. {
  346. mObjInfo[i].mType = SI_BUTTON;
  347. mObjInfo[i].mInst = KEY_BUTTON0 + buttonCount++;
  348. }
  349. else if ( mObjInstance[i].guidType == GUID_POV )
  350. {
  351. mObjInfo[i].mType = SI_POV;
  352. mObjInfo[i].mInst = povCount++;
  353. }
  354. else if ( mObjInstance[i].guidType == GUID_XAxis )
  355. {
  356. mObjInfo[i].mType = SI_XAXIS;
  357. mObjInfo[i].mInst = xAxisCount++;
  358. }
  359. else if ( mObjInstance[i].guidType == GUID_YAxis )
  360. {
  361. mObjInfo[i].mType = SI_YAXIS;
  362. mObjInfo[i].mInst = yAxisCount++;
  363. }
  364. else if ( mObjInstance[i].guidType == GUID_ZAxis )
  365. {
  366. mObjInfo[i].mType = SI_ZAXIS;
  367. mObjInfo[i].mInst = zAxisCount++;
  368. }
  369. else if ( mObjInstance[i].guidType == GUID_RxAxis )
  370. {
  371. mObjInfo[i].mType = SI_RXAXIS;
  372. mObjInfo[i].mInst = rAxisCount++;
  373. }
  374. else if ( mObjInstance[i].guidType == GUID_RyAxis )
  375. {
  376. mObjInfo[i].mType = SI_RYAXIS;
  377. mObjInfo[i].mInst = uAxisCount++;
  378. }
  379. else if ( mObjInstance[i].guidType == GUID_RzAxis )
  380. {
  381. mObjInfo[i].mType = SI_RZAXIS;
  382. mObjInfo[i].mInst = vAxisCount++;
  383. }
  384. else if ( mObjInstance[i].guidType == GUID_Slider )
  385. {
  386. mObjInfo[i].mType = SI_SLIDER;
  387. mObjInfo[i].mInst = sliderCount++;
  388. }
  389. else if ( mObjInstance[i].guidType == GUID_Key )
  390. {
  391. mObjInfo[i].mType = SI_KEY;
  392. mObjInfo[i].mInst = DIK_to_Key( (U8)DIDFT_GETINSTANCE( mObjFormat[i].dwType ) );
  393. keyCount++;
  394. }
  395. else
  396. {
  397. mObjInfo[i].mType = SI_UNKNOWN;
  398. mObjInfo[i].mInst = unknownCount++;
  399. }
  400. // Set the device object's min and max values:
  401. if ( mObjInstance[i].guidType == GUID_Button
  402. || mObjInstance[i].guidType == GUID_Key
  403. || mObjInstance[i].guidType == GUID_POV )
  404. {
  405. mObjInfo[i].mMin = DIPROPRANGE_NOMIN;
  406. mObjInfo[i].mMax = DIPROPRANGE_NOMAX;
  407. }
  408. else
  409. {
  410. // This is an axis or a slider, so find out its range:
  411. DIPROPRANGE pr;
  412. pr.diph.dwSize = sizeof( pr );
  413. pr.diph.dwHeaderSize = sizeof( pr.diph );
  414. pr.diph.dwHow = DIPH_BYID;
  415. pr.diph.dwObj = mObjFormat[i].dwType;
  416. if ( SUCCEEDED( mDevice->GetProperty( DIPROP_RANGE, &pr.diph ) ) )
  417. {
  418. mObjInfo[i].mMin = pr.lMin;
  419. mObjInfo[i].mMax = pr.lMax;
  420. }
  421. else
  422. {
  423. mObjInfo[i].mMin = DIPROPRANGE_NOMIN;
  424. mObjInfo[i].mMax = DIPROPRANGE_NOMAX;
  425. }
  426. }
  427. }
  428. return true;
  429. }
  430. //------------------------------------------------------------------------------
  431. const char* DInputDevice::getName()
  432. {
  433. #ifdef UNICODE
  434. static UTF8 buf[512];
  435. convertUTF16toUTF8(mDeviceInstance.tszInstanceName, buf, sizeof(buf));
  436. return (const char *)buf;
  437. #else
  438. return mDeviceInstance.tszInstanceName;
  439. #endif
  440. }
  441. //------------------------------------------------------------------------------
  442. const char* DInputDevice::getProductName()
  443. {
  444. #ifdef UNICODE
  445. static UTF8 buf[512];
  446. convertUTF16toUTF8(mDeviceInstance.tszProductName, buf, sizeof(buf));
  447. return (const char *)buf;
  448. #else
  449. return mDeviceInstance.tszProductName;
  450. #endif
  451. }
  452. //------------------------------------------------------------------------------
  453. bool DInputDevice::process()
  454. {
  455. if ( mAcquired )
  456. {
  457. if ( isPolled() )
  458. return processImmediate();
  459. else
  460. return processAsync();
  461. }
  462. return false;
  463. }
  464. //------------------------------------------------------------------------------
  465. bool DInputDevice::processAsync()
  466. {
  467. DIDEVICEOBJECTDATA eventBuffer[QUEUED_BUFFER_SIZE];
  468. DWORD numEvents = QUEUED_BUFFER_SIZE;
  469. HRESULT result;
  470. if ( !mDevice )
  471. return false;
  472. // Test for the "need sync" flag:
  473. if ( mNeedSync )
  474. {
  475. // For now, only sync the keyboard:
  476. if ( mDeviceType == KeyboardDeviceType )
  477. syncKeyboardState();
  478. mNeedSync = false;
  479. }
  480. do
  481. {
  482. result = mDevice->GetDeviceData( sizeof( DIDEVICEOBJECTDATA ), eventBuffer, &numEvents, 0 );
  483. if ( !SUCCEEDED( result ) )
  484. {
  485. switch ( result )
  486. {
  487. case DIERR_INPUTLOST:
  488. // Data stream was interrupted, so try to reacquire the device:
  489. mAcquired = false;
  490. acquire();
  491. break;
  492. case DIERR_INVALIDPARAM:
  493. Con::errorf( "DInputDevice::processAsync -- Invalid parameter passed to GetDeviceData of the %s input device!", mName );
  494. break;
  495. case DIERR_NOTACQUIRED:
  496. // We can't get the device, so quit:
  497. mAcquired = false;
  498. // Don't error out - this is actually a natural occurrence...
  499. break;
  500. }
  501. return false;
  502. }
  503. // We have buffered input, so act on it:
  504. for ( DWORD i = 0; i < numEvents; i++ )
  505. buildEvent( findObjInstance( eventBuffer[i].dwOfs ), eventBuffer[i].dwData, eventBuffer[i].dwData );
  506. // Check for buffer overflow:
  507. if ( result == DI_BUFFEROVERFLOW )
  508. {
  509. // This is a problem, but we can keep going...
  510. Con::errorf( "DInputDevice::processAsync -- %s input device's event buffer overflowed!", mName );
  511. mNeedSync = true; // Let it know to resync next time through...
  512. }
  513. }
  514. while ( numEvents );
  515. return true;
  516. }
  517. //------------------------------------------------------------------------------
  518. bool DInputDevice::processImmediate()
  519. {
  520. if ( !mDevice )
  521. return false;
  522. mDevice->Poll();
  523. U8* buffer = ( mPrevObjBuffer == mObjBuffer1 ) ? mObjBuffer2 : mObjBuffer1;
  524. HRESULT result = mDevice->GetDeviceState( mObjBufferSize, buffer );
  525. if ( !SUCCEEDED( result ) )
  526. {
  527. switch ( result )
  528. {
  529. case DIERR_INPUTLOST:
  530. // Data stream was interrupted, so try to reacquire the device:
  531. mAcquired = false;
  532. acquire();
  533. break;
  534. case DIERR_INVALIDPARAM:
  535. Con::errorf( "DInputDevice::processPolled -- invalid parameter passed to GetDeviceState on %s input device!", mName );
  536. break;
  537. case DIERR_NOTACQUIRED:
  538. Con::errorf( "DInputDevice::processPolled -- GetDeviceState called when %s input device is not acquired!", mName );
  539. break;
  540. case E_PENDING:
  541. Con::warnf( "DInputDevice::processPolled -- Data not yet available for the %s input device!", mName );
  542. break;
  543. }
  544. return false;
  545. }
  546. // Loop through all of the objects and produce events where
  547. // the states have changed:
  548. S32 newData, oldData;
  549. for ( DWORD i = 0; i < mObjCount; i++ )
  550. {
  551. if ( mObjFormat[i].dwType & DIDFT_BUTTON )
  552. {
  553. if ( mPrevObjBuffer )
  554. {
  555. newData = *( (U8*) ( buffer + mObjFormat[i].dwOfs ) );
  556. oldData = *( (U8*) ( mPrevObjBuffer + mObjFormat[i].dwOfs ) );
  557. if ( newData == oldData )
  558. continue;
  559. }
  560. else
  561. continue;
  562. }
  563. else if ( mObjFormat[i].dwType & DIDFT_POV )
  564. {
  565. if ( mPrevObjBuffer )
  566. {
  567. newData = *( (S32*) ( buffer + mObjFormat[i].dwOfs ) );
  568. oldData = *( (S32*) ( mPrevObjBuffer + mObjFormat[i].dwOfs ) );
  569. if ( LOWORD( newData ) == LOWORD( oldData ) )
  570. continue;
  571. }
  572. else
  573. continue;
  574. }
  575. else
  576. {
  577. // report normal axes every time through the loop:
  578. newData = *( (S32*) ( buffer + mObjFormat[i].dwOfs ) );
  579. }
  580. // Build an event:
  581. buildEvent( i, newData, oldData );
  582. }
  583. mPrevObjBuffer = buffer;
  584. return true;
  585. }
  586. //------------------------------------------------------------------------------
  587. bool DInputDevice::processKeyEvent( InputEvent &event )
  588. {
  589. if ( event.deviceType != KeyboardDeviceType || event.objType != SI_KEY )
  590. return false;
  591. bool modKey = false;
  592. U8 DIKeyCode = Key_to_DIK( event.objInst );
  593. if ( event.action == SI_MAKE )
  594. {
  595. // Maintain the key structure:
  596. smKeyStates[DIKeyCode] = true;
  597. switch ( event.objInst )
  598. {
  599. case KEY_LSHIFT:
  600. smModifierKeys |= SI_LSHIFT;
  601. modKey = true;
  602. break;
  603. case KEY_RSHIFT:
  604. smModifierKeys |= SI_RSHIFT;
  605. modKey = true;
  606. break;
  607. case KEY_LCONTROL:
  608. smModifierKeys |= SI_LCTRL;
  609. modKey = true;
  610. break;
  611. case KEY_RCONTROL:
  612. smModifierKeys |= SI_RCTRL;
  613. modKey = true;
  614. break;
  615. case KEY_LALT:
  616. smModifierKeys |= SI_LALT;
  617. modKey = true;
  618. break;
  619. case KEY_RALT:
  620. smModifierKeys |= SI_RALT;
  621. modKey = true;
  622. break;
  623. }
  624. }
  625. else
  626. {
  627. // Maintain the keys structure:
  628. smKeyStates[DIKeyCode] = false;
  629. switch ( event.objInst )
  630. {
  631. case KEY_LSHIFT:
  632. smModifierKeys &= ~SI_LSHIFT;
  633. modKey = true;
  634. break;
  635. case KEY_RSHIFT:
  636. smModifierKeys &= ~SI_RSHIFT;
  637. modKey = true;
  638. break;
  639. case KEY_LCONTROL:
  640. smModifierKeys &= ~SI_LCTRL;
  641. modKey = true;
  642. break;
  643. case KEY_RCONTROL:
  644. smModifierKeys &= ~SI_RCTRL;
  645. modKey = true;
  646. break;
  647. case KEY_LALT:
  648. smModifierKeys &= ~SI_LALT;
  649. modKey = true;
  650. break;
  651. case KEY_RALT:
  652. smModifierKeys &= ~SI_RALT;
  653. modKey = true;
  654. break;
  655. }
  656. }
  657. if ( modKey )
  658. {
  659. setModifierKeys( smModifierKeys );
  660. event.modifier = 0;
  661. }
  662. else
  663. event.modifier = smModifierKeys;
  664. // TODO: alter this getAscii call
  665. KEY_STATE state = STATE_LOWER;
  666. if (event.modifier & (SI_CTRL|SI_ALT) )
  667. {
  668. state = STATE_GOOFY;
  669. }
  670. // else if ( event.modifier & SI_SHIFT )
  671. if ( event.modifier & SI_SHIFT )
  672. {
  673. state = STATE_UPPER;
  674. }
  675. event.ascii = Input::getAscii( event.objInst, state );
  676. return modKey;
  677. }
  678. //------------------------------------------------------------------------------
  679. void DInputDevice::syncKeyboardState()
  680. {
  681. AssertFatal( mDeviceType == KeyboardDeviceType, "DInputDevice::syncKeyboardState - device is not a keyboard!" );
  682. U8* keyBuffer = new U8[mObjBufferSize];
  683. dMemset( keyBuffer, 0, sizeof( keyBuffer ) );
  684. HRESULT result = mDevice->GetDeviceState( mObjBufferSize, keyBuffer );
  685. if ( SUCCEEDED( result ) )
  686. {
  687. S32 keyState;
  688. bool keyIsDown, keyWasDown;
  689. for ( DWORD i = 1; i < mObjCount; i++ ) // Valid key codes start at 1
  690. {
  691. keyState = *( (U8*) ( keyBuffer + mObjFormat[i].dwOfs ) );
  692. keyWasDown = smKeyStates[i];
  693. keyIsDown = bool( keyState & 0x80 );
  694. if ( keyWasDown != keyIsDown )
  695. buildEvent( i - 1, ( keyState & 0x80 ), ( keyWasDown ? 0x80 : 0 ) );
  696. }
  697. }
  698. else
  699. {
  700. const char* errorString = NULL;
  701. switch ( result )
  702. {
  703. case DIERR_INPUTLOST:
  704. errorString = "DIERR_INPUTLOST";
  705. break;
  706. case DIERR_INVALIDPARAM:
  707. errorString = "DIERR_INVALIDPARAM";
  708. break;
  709. case DIERR_NOTACQUIRED:
  710. errorString = "DIERR_NOTACQUIRED";
  711. break;
  712. case E_PENDING:
  713. errorString = "E_PENDING";
  714. break;
  715. default:
  716. errorString = "Unknown Error";
  717. }
  718. }
  719. delete [] keyBuffer;
  720. }
  721. //------------------------------------------------------------------------------
  722. DWORD DInputDevice::findObjInstance( DWORD offset )
  723. {
  724. DIDEVICEOBJECTINSTANCE *inst = mObjInstance;
  725. for ( U32 i = 0; i < mObjCount; i++, inst++ )
  726. {
  727. if ( inst->dwOfs == offset )
  728. return i;
  729. }
  730. AssertFatal( false, "DInputDevice::findObjInstance -- failed to locate object instance." );
  731. return 0;
  732. }
  733. //------------------------------------------------------------------------------
  734. enum Win32POVDirBits
  735. {
  736. POV_up = 1 << 0,
  737. POV_right = 1 << 1,
  738. POV_down = 1 << 2,
  739. POV_left = 1 << 3,
  740. };
  741. enum Win32POVDirsInQuadrant
  742. {
  743. POVq_center = 0,
  744. POVq_up = POV_up,
  745. POVq_upright = POV_up | POV_right,
  746. POVq_right = POV_right,
  747. POVq_downright = POV_down | POV_right,
  748. POVq_down = POV_down,
  749. POVq_downleft = POV_down | POV_left,
  750. POVq_left = POV_left,
  751. POVq_upleft = POV_up | POV_left,
  752. };
  753. static const U32 Win32POVQuadrantMap[] =
  754. {
  755. POVq_up, POVq_upright, POVq_right, POVq_downright, POVq_down, POVq_downleft,
  756. POVq_left, POVq_upleft
  757. };
  758. static U32 _Win32GetPOVDirs(U32 data)
  759. {
  760. U32 quadrant = (data / 4500) % 8;
  761. U32 dirs = (data == 0xffff) ? POVq_center : Win32POVQuadrantMap[quadrant];
  762. return dirs;
  763. }
  764. #define _Win32LogPOVInput (a)
  765. //------------------------------------------------------------------------------
  766. bool DInputDevice::buildEvent( DWORD offset, S32 newData, S32 oldData )
  767. {
  768. DIDEVICEOBJECTINSTANCE &objInstance = mObjInstance[offset];
  769. ObjInfo &objInfo = mObjInfo[offset];
  770. if ( objInfo.mType == SI_UNKNOWN )
  771. return false;
  772. InputEvent newEvent;
  773. newEvent.deviceType = mDeviceType;
  774. newEvent.deviceInst = mDeviceID;
  775. newEvent.objType = objInfo.mType;
  776. newEvent.objInst = objInfo.mInst;
  777. newEvent.modifier = smModifierKeys;
  778. InputEvent newEvent2;
  779. newEvent2.deviceType = mDeviceType;
  780. newEvent2.deviceInst = mDeviceID;
  781. newEvent2.objType = objInfo.mType;
  782. newEvent2.objInst = objInfo.mInst;
  783. newEvent2.modifier = smModifierKeys;
  784. switch ( newEvent.objType )
  785. {
  786. case SI_XAXIS:
  787. case SI_YAXIS:
  788. case SI_ZAXIS:
  789. case SI_RXAXIS:
  790. case SI_RYAXIS:
  791. case SI_RZAXIS:
  792. case SI_SLIDER:
  793. newEvent.action = SI_MOVE;
  794. if ( newEvent.deviceType == MouseDeviceType )
  795. {
  796. newEvent.fValue = float( newData );
  797. }
  798. else // Joystick or other device:
  799. {
  800. // Scale to the range -1.0 to 1.0:
  801. if ( objInfo.mMin != DIPROPRANGE_NOMIN && objInfo.mMax != DIPROPRANGE_NOMAX )
  802. {
  803. float range = float( objInfo.mMax - objInfo.mMin );
  804. //newEvent.fValue = float( newData - objInfo.mMin ) / range;
  805. newEvent.fValue = float( ( 2 * newData ) - objInfo.mMax - objInfo.mMin ) / range;
  806. }
  807. else
  808. newEvent.fValue = (F32)newData;
  809. }
  810. Game->postEvent( newEvent );
  811. break;
  812. case SI_BUTTON:
  813. newEvent.action = ( newData & 0x80 ) ? SI_MAKE : SI_BREAK;
  814. newEvent.fValue = ( newEvent.action == SI_MAKE ) ? 1.0f : 0.0f;
  815. Game->postEvent( newEvent );
  816. break;
  817. case SI_KEY:
  818. newEvent.action = ( newData & 0x80 ) ? SI_MAKE : SI_BREAK;
  819. newEvent.fValue = ( newEvent.action == SI_MAKE ) ? 1.0f : 0.0f;
  820. processKeyEvent( newEvent );
  821. Game->postEvent( newEvent );
  822. break;
  823. case SI_POV:
  824. // Handle artificial POV up/down/left/right buttons
  825. // If we're not a polling device, oldData and newData are the same, so "fake" transitions
  826. if(!isPolled()) {
  827. oldData = mPrevPOVPos;
  828. mPrevPOVPos = newData;
  829. }
  830. newData = LOWORD( newData );
  831. oldData = LOWORD( oldData );
  832. newData = _Win32GetPOVDirs(newData);
  833. oldData = _Win32GetPOVDirs(oldData);
  834. U32 setkeys = newData & (~oldData);
  835. U32 clearkeys = oldData & (~newData);
  836. U32 objInst = newEvent.objInst;
  837. if ( setkeys || clearkeys )
  838. {
  839. if ( clearkeys )
  840. {
  841. newEvent.action = SI_BREAK;
  842. newEvent.fValue = 0.0f;
  843. // post events for all buttons that need to be cleared.
  844. if( clearkeys & POV_up)
  845. {
  846. newEvent.objInst = ( objInst == 0 ) ? SI_UPOV : SI_UPOV2;
  847. Game->postEvent(newEvent);
  848. }
  849. if( clearkeys & POV_right)
  850. {
  851. newEvent.objInst = ( objInst == 0 ) ? SI_RPOV : SI_RPOV2;
  852. Game->postEvent(newEvent);
  853. }
  854. if( clearkeys & POV_down)
  855. {
  856. newEvent.objInst = ( objInst == 0 ) ? SI_DPOV : SI_DPOV;
  857. Game->postEvent(newEvent);
  858. }
  859. if( clearkeys & POV_left)
  860. {
  861. newEvent.objInst = ( objInst == 0 ) ? SI_LPOV : SI_LPOV2;
  862. Game->postEvent(newEvent);
  863. }
  864. } // clear keys
  865. if ( setkeys )
  866. {
  867. newEvent.action = SI_MAKE;
  868. newEvent.fValue = 1.0f;
  869. // post events for all buttons that need to be set.
  870. if( setkeys & POV_up)
  871. {
  872. newEvent.objInst = ( objInst == 0 ) ? SI_UPOV : SI_UPOV2;
  873. Game->postEvent(newEvent);
  874. }
  875. if( setkeys & POV_right)
  876. {
  877. newEvent.objInst = ( objInst == 0 ) ? SI_RPOV : SI_RPOV2;
  878. Game->postEvent(newEvent);
  879. }
  880. if( setkeys & POV_down)
  881. {
  882. newEvent.objInst = ( objInst == 0 ) ? SI_DPOV : SI_DPOV;
  883. Game->postEvent(newEvent);
  884. }
  885. if( setkeys & POV_left)
  886. {
  887. newEvent.objInst = ( objInst == 0 ) ? SI_LPOV : SI_LPOV2;
  888. Game->postEvent(newEvent);
  889. }
  890. } // set keys
  891. }
  892. break;
  893. }
  894. return true;
  895. }
  896. //------------------------------------------------------------------------------
  897. //
  898. // This function translates the DirectInput scan code to the associated
  899. // internal key code (as defined in event.h).
  900. //
  901. //------------------------------------------------------------------------------
  902. U16 DIK_to_Key( U8 dikCode )
  903. {
  904. switch ( dikCode )
  905. {
  906. case DIK_ESCAPE: return KEY_ESCAPE;
  907. case DIK_1: return KEY_1;
  908. case DIK_2: return KEY_2;
  909. case DIK_3: return KEY_3;
  910. case DIK_4: return KEY_4;
  911. case DIK_5: return KEY_5;
  912. case DIK_6: return KEY_6;
  913. case DIK_7: return KEY_7;
  914. case DIK_8: return KEY_8;
  915. case DIK_9: return KEY_9;
  916. case DIK_0: return KEY_0;
  917. case DIK_MINUS: return KEY_MINUS;
  918. case DIK_EQUALS: return KEY_EQUALS;
  919. case DIK_BACK: return KEY_BACKSPACE;
  920. case DIK_TAB: return KEY_TAB;
  921. case DIK_Q: return KEY_Q;
  922. case DIK_W: return KEY_W;
  923. case DIK_E: return KEY_E;
  924. case DIK_R: return KEY_R;
  925. case DIK_T: return KEY_T;
  926. case DIK_Y: return KEY_Y;
  927. case DIK_U: return KEY_U;
  928. case DIK_I: return KEY_I;
  929. case DIK_O: return KEY_O;
  930. case DIK_P: return KEY_P;
  931. case DIK_LBRACKET: return KEY_LBRACKET;
  932. case DIK_RBRACKET: return KEY_RBRACKET;
  933. case DIK_RETURN: return KEY_RETURN;
  934. case DIK_LCONTROL: return KEY_LCONTROL;
  935. case DIK_A: return KEY_A;
  936. case DIK_S: return KEY_S;
  937. case DIK_D: return KEY_D;
  938. case DIK_F: return KEY_F;
  939. case DIK_G: return KEY_G;
  940. case DIK_H: return KEY_H;
  941. case DIK_J: return KEY_J;
  942. case DIK_K: return KEY_K;
  943. case DIK_L: return KEY_L;
  944. case DIK_SEMICOLON: return KEY_SEMICOLON;
  945. case DIK_APOSTROPHE: return KEY_APOSTROPHE;
  946. case DIK_GRAVE: return KEY_TILDE;
  947. case DIK_LSHIFT: return KEY_LSHIFT;
  948. case DIK_BACKSLASH: return KEY_BACKSLASH;
  949. case DIK_Z: return KEY_Z;
  950. case DIK_X: return KEY_X;
  951. case DIK_C: return KEY_C;
  952. case DIK_V: return KEY_V;
  953. case DIK_B: return KEY_B;
  954. case DIK_N: return KEY_N;
  955. case DIK_M: return KEY_M;
  956. case DIK_COMMA: return KEY_COMMA;
  957. case DIK_PERIOD: return KEY_PERIOD;
  958. case DIK_SLASH: return KEY_SLASH;
  959. case DIK_RSHIFT: return KEY_RSHIFT;
  960. case DIK_MULTIPLY: return KEY_MULTIPLY;
  961. case DIK_LALT: return KEY_LALT;
  962. case DIK_SPACE: return KEY_SPACE;
  963. case DIK_CAPSLOCK: return KEY_CAPSLOCK;
  964. case DIK_F1: return KEY_F1;
  965. case DIK_F2: return KEY_F2;
  966. case DIK_F3: return KEY_F3;
  967. case DIK_F4: return KEY_F4;
  968. case DIK_F5: return KEY_F5;
  969. case DIK_F6: return KEY_F6;
  970. case DIK_F7: return KEY_F7;
  971. case DIK_F8: return KEY_F8;
  972. case DIK_F9: return KEY_F9;
  973. case DIK_F10: return KEY_F10;
  974. case DIK_NUMLOCK: return KEY_NUMLOCK;
  975. case DIK_SCROLL: return KEY_SCROLLLOCK;
  976. case DIK_NUMPAD7: return KEY_NUMPAD7;
  977. case DIK_NUMPAD8: return KEY_NUMPAD8;
  978. case DIK_NUMPAD9: return KEY_NUMPAD9;
  979. case DIK_SUBTRACT: return KEY_SUBTRACT;
  980. case DIK_NUMPAD4: return KEY_NUMPAD4;
  981. case DIK_NUMPAD5: return KEY_NUMPAD5;
  982. case DIK_NUMPAD6: return KEY_NUMPAD6;
  983. case DIK_ADD: return KEY_ADD;
  984. case DIK_NUMPAD1: return KEY_NUMPAD1;
  985. case DIK_NUMPAD2: return KEY_NUMPAD2;
  986. case DIK_NUMPAD3: return KEY_NUMPAD3;
  987. case DIK_NUMPAD0: return KEY_NUMPAD0;
  988. case DIK_DECIMAL: return KEY_DECIMAL;
  989. case DIK_F11: return KEY_F11;
  990. case DIK_F12: return KEY_F12;
  991. case DIK_F13: return KEY_F13;
  992. case DIK_F14: return KEY_F14;
  993. case DIK_F15: return KEY_F15;
  994. case DIK_KANA: return 0;
  995. case DIK_CONVERT: return 0;
  996. case DIK_NOCONVERT: return 0;
  997. case DIK_YEN: return 0;
  998. case DIK_NUMPADEQUALS: return 0;
  999. case DIK_CIRCUMFLEX: return 0;
  1000. case DIK_AT: return 0;
  1001. case DIK_COLON: return 0;
  1002. case DIK_UNDERLINE: return 0;
  1003. case DIK_KANJI: return 0;
  1004. case DIK_STOP: return 0;
  1005. case DIK_AX: return 0;
  1006. case DIK_UNLABELED: return 0;
  1007. case DIK_NUMPADENTER: return KEY_NUMPADENTER;
  1008. case DIK_RCONTROL: return KEY_RCONTROL;
  1009. case DIK_NUMPADCOMMA: return KEY_SEPARATOR;
  1010. case DIK_DIVIDE: return KEY_DIVIDE;
  1011. case DIK_SYSRQ: return KEY_PRINT;
  1012. case DIK_RALT: return KEY_RALT;
  1013. case DIK_PAUSE: return KEY_PAUSE;
  1014. case DIK_HOME: return KEY_HOME;
  1015. case DIK_UP: return KEY_UP;
  1016. case DIK_PGUP: return KEY_PAGE_UP;
  1017. case DIK_LEFT: return KEY_LEFT;
  1018. case DIK_RIGHT: return KEY_RIGHT;
  1019. case DIK_END: return KEY_END;
  1020. case DIK_DOWN: return KEY_DOWN;
  1021. case DIK_PGDN: return KEY_PAGE_DOWN;
  1022. case DIK_INSERT: return KEY_INSERT;
  1023. case DIK_DELETE: return KEY_DELETE;
  1024. case DIK_LWIN: return KEY_WIN_LWINDOW;
  1025. case DIK_RWIN: return KEY_WIN_RWINDOW;
  1026. case DIK_APPS: return KEY_WIN_APPS;
  1027. case DIK_OEM_102: return KEY_OEM_102;
  1028. }
  1029. return KEY_NULL;
  1030. }
  1031. //------------------------------------------------------------------------------
  1032. //
  1033. // This function translates an internal key code to the associated
  1034. // DirectInput scan code
  1035. //
  1036. //------------------------------------------------------------------------------
  1037. U8 Key_to_DIK( U16 keyCode )
  1038. {
  1039. switch ( keyCode )
  1040. {
  1041. case KEY_BACKSPACE: return DIK_BACK;
  1042. case KEY_TAB: return DIK_TAB;
  1043. case KEY_RETURN: return DIK_RETURN;
  1044. //KEY_CONTROL:
  1045. //KEY_ALT:
  1046. //KEY_SHIFT:
  1047. case KEY_PAUSE: return DIK_PAUSE;
  1048. case KEY_CAPSLOCK: return DIK_CAPSLOCK;
  1049. case KEY_ESCAPE: return DIK_ESCAPE;
  1050. case KEY_SPACE: return DIK_SPACE;
  1051. case KEY_PAGE_DOWN: return DIK_PGDN;
  1052. case KEY_PAGE_UP: return DIK_PGUP;
  1053. case KEY_END: return DIK_END;
  1054. case KEY_HOME: return DIK_HOME;
  1055. case KEY_LEFT: return DIK_LEFT;
  1056. case KEY_UP: return DIK_UP;
  1057. case KEY_RIGHT: return DIK_RIGHT;
  1058. case KEY_DOWN: return DIK_DOWN;
  1059. case KEY_PRINT: return DIK_SYSRQ;
  1060. case KEY_INSERT: return DIK_INSERT;
  1061. case KEY_DELETE: return DIK_DELETE;
  1062. case KEY_HELP: return 0;
  1063. case KEY_0: return DIK_0;
  1064. case KEY_1: return DIK_1;
  1065. case KEY_2: return DIK_2;
  1066. case KEY_3: return DIK_3;
  1067. case KEY_4: return DIK_4;
  1068. case KEY_5: return DIK_5;
  1069. case KEY_6: return DIK_6;
  1070. case KEY_7: return DIK_7;
  1071. case KEY_8: return DIK_8;
  1072. case KEY_9: return DIK_9;
  1073. case KEY_A: return DIK_A;
  1074. case KEY_B: return DIK_B;
  1075. case KEY_C: return DIK_C;
  1076. case KEY_D: return DIK_D;
  1077. case KEY_E: return DIK_E;
  1078. case KEY_F: return DIK_F;
  1079. case KEY_G: return DIK_G;
  1080. case KEY_H: return DIK_H;
  1081. case KEY_I: return DIK_I;
  1082. case KEY_J: return DIK_J;
  1083. case KEY_K: return DIK_K;
  1084. case KEY_L: return DIK_L;
  1085. case KEY_M: return DIK_M;
  1086. case KEY_N: return DIK_N;
  1087. case KEY_O: return DIK_O;
  1088. case KEY_P: return DIK_P;
  1089. case KEY_Q: return DIK_Q;
  1090. case KEY_R: return DIK_R;
  1091. case KEY_S: return DIK_S;
  1092. case KEY_T: return DIK_T;
  1093. case KEY_U: return DIK_U;
  1094. case KEY_V: return DIK_V;
  1095. case KEY_W: return DIK_W;
  1096. case KEY_X: return DIK_X;
  1097. case KEY_Y: return DIK_Y;
  1098. case KEY_Z: return DIK_Z;
  1099. case KEY_TILDE: return DIK_GRAVE;
  1100. case KEY_MINUS: return DIK_MINUS;
  1101. case KEY_EQUALS: return DIK_EQUALS;
  1102. case KEY_LBRACKET: return DIK_LBRACKET;
  1103. case KEY_RBRACKET: return DIK_RBRACKET;
  1104. case KEY_BACKSLASH: return DIK_BACKSLASH;
  1105. case KEY_SEMICOLON: return DIK_SEMICOLON;
  1106. case KEY_APOSTROPHE: return DIK_APOSTROPHE;
  1107. case KEY_COMMA: return DIK_COMMA;
  1108. case KEY_PERIOD: return DIK_PERIOD;
  1109. case KEY_SLASH: return DIK_SLASH;
  1110. case KEY_NUMPAD0: return DIK_NUMPAD0;
  1111. case KEY_NUMPAD1: return DIK_NUMPAD1;
  1112. case KEY_NUMPAD2: return DIK_NUMPAD2;
  1113. case KEY_NUMPAD3: return DIK_NUMPAD3;
  1114. case KEY_NUMPAD4: return DIK_NUMPAD4;
  1115. case KEY_NUMPAD5: return DIK_NUMPAD5;
  1116. case KEY_NUMPAD6: return DIK_NUMPAD6;
  1117. case KEY_NUMPAD7: return DIK_NUMPAD7;
  1118. case KEY_NUMPAD8: return DIK_NUMPAD8;
  1119. case KEY_NUMPAD9: return DIK_NUMPAD9;
  1120. case KEY_MULTIPLY: return DIK_MULTIPLY;
  1121. case KEY_ADD: return DIK_ADD;
  1122. case KEY_SEPARATOR: return DIK_NUMPADCOMMA;
  1123. case KEY_SUBTRACT: return DIK_SUBTRACT;
  1124. case KEY_DECIMAL: return DIK_DECIMAL;
  1125. case KEY_DIVIDE: return DIK_DIVIDE;
  1126. case KEY_NUMPADENTER: return DIK_NUMPADENTER;
  1127. case KEY_F1: return DIK_F1;
  1128. case KEY_F2: return DIK_F2;
  1129. case KEY_F3: return DIK_F3;
  1130. case KEY_F4: return DIK_F4;
  1131. case KEY_F5: return DIK_F5;
  1132. case KEY_F6: return DIK_F6;
  1133. case KEY_F7: return DIK_F7;
  1134. case KEY_F8: return DIK_F8;
  1135. case KEY_F9: return DIK_F9;
  1136. case KEY_F10: return DIK_F10;
  1137. case KEY_F11: return DIK_F11;
  1138. case KEY_F12: return DIK_F12;
  1139. case KEY_F13: return DIK_F13;
  1140. case KEY_F14: return DIK_F14;
  1141. case KEY_F15: return DIK_F15;
  1142. case KEY_F16:
  1143. case KEY_F17:
  1144. case KEY_F18:
  1145. case KEY_F19:
  1146. case KEY_F20:
  1147. case KEY_F21:
  1148. case KEY_F22:
  1149. case KEY_F23:
  1150. case KEY_F24: return 0;
  1151. case KEY_NUMLOCK: return DIK_NUMLOCK;
  1152. case KEY_SCROLLLOCK: return DIK_SCROLL;
  1153. case KEY_LCONTROL: return DIK_LCONTROL;
  1154. case KEY_RCONTROL: return DIK_RCONTROL;
  1155. case KEY_LALT: return DIK_LALT;
  1156. case KEY_RALT: return DIK_RALT;
  1157. case KEY_LSHIFT: return DIK_LSHIFT;
  1158. case KEY_RSHIFT: return DIK_RSHIFT;
  1159. case KEY_WIN_LWINDOW: return DIK_LWIN;
  1160. case KEY_WIN_RWINDOW: return DIK_RWIN;
  1161. case KEY_WIN_APPS: return DIK_APPS;
  1162. case KEY_OEM_102: return DIK_OEM_102;
  1163. };
  1164. return 0;
  1165. }
  1166. //------------------------------------------------------------------------------
  1167. const char* DInputDevice::getJoystickAxesString()
  1168. {
  1169. if ( mDeviceType != JoystickDeviceType )
  1170. return( "" );
  1171. U32 axisCount = mDeviceCaps.dwAxes;
  1172. char buf[64];
  1173. dSprintf( buf, sizeof( buf ), "%d", axisCount );
  1174. for ( U32 i = 0; i < mObjCount; i++ )
  1175. {
  1176. switch ( mObjInfo[i].mType )
  1177. {
  1178. case SI_XAXIS:
  1179. dStrcat( buf, "\tX" );
  1180. break;
  1181. case SI_YAXIS:
  1182. dStrcat( buf, "\tY" );
  1183. break;
  1184. case SI_ZAXIS:
  1185. dStrcat( buf, "\tZ" );
  1186. break;
  1187. case SI_RXAXIS:
  1188. dStrcat( buf, "\tR" );
  1189. break;
  1190. case SI_RYAXIS:
  1191. dStrcat( buf, "\tU" );
  1192. break;
  1193. case SI_RZAXIS:
  1194. dStrcat( buf, "\tV" );
  1195. break;
  1196. case SI_SLIDER:
  1197. dStrcat( buf, "\tS" );
  1198. break;
  1199. }
  1200. }
  1201. char* returnString = Con::getReturnBuffer( dStrlen( buf ) + 1 );
  1202. dStrcpy( returnString, buf );
  1203. return( returnString );
  1204. }
  1205. //------------------------------------------------------------------------------
  1206. bool DInputDevice::joystickDetected()
  1207. {
  1208. return( smJoystickCount > 0 );
  1209. }