winDInputDevice.cc 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488
  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( U8 ) * mObjBufferSize );
  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.fValues[0] = 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.fValues[0] = float( newData - objInfo.mMin ) / range;
  805. newEvent.fValues[0] = float( ( 2 * newData ) - objInfo.mMax - objInfo.mMin ) / range;
  806. }
  807. else
  808. newEvent.fValues[0] = (F32)newData;
  809. }
  810. Game->postEvent( newEvent );
  811. break;
  812. case SI_BUTTON:
  813. newEvent.action = ( newData & 0x80 ) ? SI_MAKE : SI_BREAK;
  814. newEvent.fValues[0] = ( 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.fValues[0] = ( 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.fValues[0] = 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_DPOV2;
  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.fValues[0] = 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_DPOV2;
  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. void DInputDevice::rumble(float x, float y)
  897. {
  898. LONG rglDirection[2] = { 0, 0 };
  899. DICONSTANTFORCE cf = { 0 };
  900. HRESULT result;
  901. // Now set the new parameters and start the effect immediately.
  902. if (!mForceFeedbackEffect)
  903. {
  904. DIEFFECT eff;
  905. ZeroMemory( &eff, sizeof(eff) );
  906. eff.dwSize = sizeof(DIEFFECT);
  907. eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
  908. eff.dwDuration = INFINITE;
  909. eff.dwSamplePeriod = 0;
  910. eff.dwGain = DI_FFNOMINALMAX;
  911. eff.dwTriggerButton = DIEB_NOTRIGGER;
  912. eff.dwTriggerRepeatInterval = 0;
  913. eff.cAxes = mNumForceFeedbackAxes;
  914. eff.rgdwAxes = mForceFeedbackAxes;
  915. eff.rglDirection = rglDirection;
  916. eff.lpEnvelope = 0;
  917. eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
  918. eff.lpvTypeSpecificParams = &cf;
  919. eff.dwStartDelay = 0;
  920. // Create the prepared effect
  921. if ( FAILED( result = mDevice->CreateEffect( GUID_ConstantForce, &eff, &mForceFeedbackEffect, NULL ) ) )
  922. {
  923. Con::errorf( "DInputDevice::rumbleJoystick - %s does not support force feedback.\n", mName );
  924. return;
  925. }
  926. else
  927. {
  928. Con::printf( "DInputDevice::rumbleJoystick - %s supports force feedback.\n", mName );
  929. }
  930. }
  931. // Clamp the input floats to [0 - 1]
  932. x = max(0, min(1, x));
  933. y = max(0, min(1, y));
  934. if ( 1 == mNumForceFeedbackAxes )
  935. {
  936. cf.lMagnitude = (DWORD)( x * DI_FFNOMINALMAX );
  937. }
  938. else
  939. {
  940. rglDirection[0] = (DWORD)( x * DI_FFNOMINALMAX );
  941. rglDirection[1] = (DWORD)( y * DI_FFNOMINALMAX );
  942. cf.lMagnitude = (DWORD)sqrt( (double)(x * x * DI_FFNOMINALMAX * DI_FFNOMINALMAX + y * y * DI_FFNOMINALMAX * DI_FFNOMINALMAX) );
  943. }
  944. DIEFFECT eff;
  945. ZeroMemory( &eff, sizeof(eff) );
  946. eff.dwSize = sizeof(DIEFFECT);
  947. eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
  948. eff.dwDuration = INFINITE;
  949. eff.dwSamplePeriod = 0;
  950. eff.dwGain = DI_FFNOMINALMAX;
  951. eff.dwTriggerButton = DIEB_NOTRIGGER;
  952. eff.dwTriggerRepeatInterval = 0;
  953. eff.cAxes = mNumForceFeedbackAxes;
  954. eff.rglDirection = rglDirection;
  955. eff.lpEnvelope = 0;
  956. eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
  957. eff.lpvTypeSpecificParams = &cf;
  958. eff.dwStartDelay = 0;
  959. if ( FAILED( result = mForceFeedbackEffect->SetParameters( &eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START ) ) )
  960. {
  961. const char* errorString = NULL;
  962. switch ( result )
  963. {
  964. case DIERR_INPUTLOST:
  965. errorString = "DIERR_INPUTLOST";
  966. break;
  967. case DIERR_INVALIDPARAM:
  968. errorString = "DIERR_INVALIDPARAM";
  969. break;
  970. case DIERR_NOTACQUIRED:
  971. errorString = "DIERR_NOTACQUIRED";
  972. break;
  973. default:
  974. errorString = "Unknown Error";
  975. }
  976. Con::errorf( "DInputDevice::rumbleJoystick - %s - Failed to start rumble effect\n", errorString );
  977. }
  978. }
  979. //------------------------------------------------------------------------------
  980. //
  981. // This function translates the DirectInput scan code to the associated
  982. // internal key code (as defined in event.h).
  983. //
  984. //------------------------------------------------------------------------------
  985. U16 DIK_to_Key( U8 dikCode )
  986. {
  987. switch ( dikCode )
  988. {
  989. case DIK_ESCAPE: return KEY_ESCAPE;
  990. case DIK_1: return KEY_1;
  991. case DIK_2: return KEY_2;
  992. case DIK_3: return KEY_3;
  993. case DIK_4: return KEY_4;
  994. case DIK_5: return KEY_5;
  995. case DIK_6: return KEY_6;
  996. case DIK_7: return KEY_7;
  997. case DIK_8: return KEY_8;
  998. case DIK_9: return KEY_9;
  999. case DIK_0: return KEY_0;
  1000. case DIK_MINUS: return KEY_MINUS;
  1001. case DIK_EQUALS: return KEY_EQUALS;
  1002. case DIK_BACK: return KEY_BACKSPACE;
  1003. case DIK_TAB: return KEY_TAB;
  1004. case DIK_Q: return KEY_Q;
  1005. case DIK_W: return KEY_W;
  1006. case DIK_E: return KEY_E;
  1007. case DIK_R: return KEY_R;
  1008. case DIK_T: return KEY_T;
  1009. case DIK_Y: return KEY_Y;
  1010. case DIK_U: return KEY_U;
  1011. case DIK_I: return KEY_I;
  1012. case DIK_O: return KEY_O;
  1013. case DIK_P: return KEY_P;
  1014. case DIK_LBRACKET: return KEY_LBRACKET;
  1015. case DIK_RBRACKET: return KEY_RBRACKET;
  1016. case DIK_RETURN: return KEY_RETURN;
  1017. case DIK_LCONTROL: return KEY_LCONTROL;
  1018. case DIK_A: return KEY_A;
  1019. case DIK_S: return KEY_S;
  1020. case DIK_D: return KEY_D;
  1021. case DIK_F: return KEY_F;
  1022. case DIK_G: return KEY_G;
  1023. case DIK_H: return KEY_H;
  1024. case DIK_J: return KEY_J;
  1025. case DIK_K: return KEY_K;
  1026. case DIK_L: return KEY_L;
  1027. case DIK_SEMICOLON: return KEY_SEMICOLON;
  1028. case DIK_APOSTROPHE: return KEY_APOSTROPHE;
  1029. case DIK_GRAVE: return KEY_TILDE;
  1030. case DIK_LSHIFT: return KEY_LSHIFT;
  1031. case DIK_BACKSLASH: return KEY_BACKSLASH;
  1032. case DIK_Z: return KEY_Z;
  1033. case DIK_X: return KEY_X;
  1034. case DIK_C: return KEY_C;
  1035. case DIK_V: return KEY_V;
  1036. case DIK_B: return KEY_B;
  1037. case DIK_N: return KEY_N;
  1038. case DIK_M: return KEY_M;
  1039. case DIK_COMMA: return KEY_COMMA;
  1040. case DIK_PERIOD: return KEY_PERIOD;
  1041. case DIK_SLASH: return KEY_SLASH;
  1042. case DIK_RSHIFT: return KEY_RSHIFT;
  1043. case DIK_MULTIPLY: return KEY_MULTIPLY;
  1044. case DIK_LALT: return KEY_LALT;
  1045. case DIK_SPACE: return KEY_SPACE;
  1046. case DIK_CAPSLOCK: return KEY_CAPSLOCK;
  1047. case DIK_F1: return KEY_F1;
  1048. case DIK_F2: return KEY_F2;
  1049. case DIK_F3: return KEY_F3;
  1050. case DIK_F4: return KEY_F4;
  1051. case DIK_F5: return KEY_F5;
  1052. case DIK_F6: return KEY_F6;
  1053. case DIK_F7: return KEY_F7;
  1054. case DIK_F8: return KEY_F8;
  1055. case DIK_F9: return KEY_F9;
  1056. case DIK_F10: return KEY_F10;
  1057. case DIK_NUMLOCK: return KEY_NUMLOCK;
  1058. case DIK_SCROLL: return KEY_SCROLLLOCK;
  1059. case DIK_NUMPAD7: return KEY_NUMPAD7;
  1060. case DIK_NUMPAD8: return KEY_NUMPAD8;
  1061. case DIK_NUMPAD9: return KEY_NUMPAD9;
  1062. case DIK_SUBTRACT: return KEY_SUBTRACT;
  1063. case DIK_NUMPAD4: return KEY_NUMPAD4;
  1064. case DIK_NUMPAD5: return KEY_NUMPAD5;
  1065. case DIK_NUMPAD6: return KEY_NUMPAD6;
  1066. case DIK_ADD: return KEY_ADD;
  1067. case DIK_NUMPAD1: return KEY_NUMPAD1;
  1068. case DIK_NUMPAD2: return KEY_NUMPAD2;
  1069. case DIK_NUMPAD3: return KEY_NUMPAD3;
  1070. case DIK_NUMPAD0: return KEY_NUMPAD0;
  1071. case DIK_DECIMAL: return KEY_DECIMAL;
  1072. case DIK_F11: return KEY_F11;
  1073. case DIK_F12: return KEY_F12;
  1074. case DIK_F13: return KEY_F13;
  1075. case DIK_F14: return KEY_F14;
  1076. case DIK_F15: return KEY_F15;
  1077. case DIK_KANA: return 0;
  1078. case DIK_CONVERT: return 0;
  1079. case DIK_NOCONVERT: return 0;
  1080. case DIK_YEN: return 0;
  1081. case DIK_NUMPADEQUALS: return 0;
  1082. case DIK_CIRCUMFLEX: return 0;
  1083. case DIK_AT: return 0;
  1084. case DIK_COLON: return 0;
  1085. case DIK_UNDERLINE: return 0;
  1086. case DIK_KANJI: return 0;
  1087. case DIK_STOP: return 0;
  1088. case DIK_AX: return 0;
  1089. case DIK_UNLABELED: return 0;
  1090. case DIK_NUMPADENTER: return KEY_NUMPADENTER;
  1091. case DIK_RCONTROL: return KEY_RCONTROL;
  1092. case DIK_NUMPADCOMMA: return KEY_SEPARATOR;
  1093. case DIK_DIVIDE: return KEY_DIVIDE;
  1094. case DIK_SYSRQ: return KEY_PRINT;
  1095. case DIK_RALT: return KEY_RALT;
  1096. case DIK_PAUSE: return KEY_PAUSE;
  1097. case DIK_HOME: return KEY_HOME;
  1098. case DIK_UP: return KEY_UP;
  1099. case DIK_PGUP: return KEY_PAGE_UP;
  1100. case DIK_LEFT: return KEY_LEFT;
  1101. case DIK_RIGHT: return KEY_RIGHT;
  1102. case DIK_END: return KEY_END;
  1103. case DIK_DOWN: return KEY_DOWN;
  1104. case DIK_PGDN: return KEY_PAGE_DOWN;
  1105. case DIK_INSERT: return KEY_INSERT;
  1106. case DIK_DELETE: return KEY_DELETE;
  1107. case DIK_LWIN: return KEY_WIN_LWINDOW;
  1108. case DIK_RWIN: return KEY_WIN_RWINDOW;
  1109. case DIK_APPS: return KEY_WIN_APPS;
  1110. case DIK_OEM_102: return KEY_OEM_102;
  1111. }
  1112. return KEY_NULL;
  1113. }
  1114. //------------------------------------------------------------------------------
  1115. //
  1116. // This function translates an internal key code to the associated
  1117. // DirectInput scan code
  1118. //
  1119. //------------------------------------------------------------------------------
  1120. U8 Key_to_DIK( U16 keyCode )
  1121. {
  1122. switch ( keyCode )
  1123. {
  1124. case KEY_BACKSPACE: return DIK_BACK;
  1125. case KEY_TAB: return DIK_TAB;
  1126. case KEY_RETURN: return DIK_RETURN;
  1127. //KEY_CONTROL:
  1128. //KEY_ALT:
  1129. //KEY_SHIFT:
  1130. case KEY_PAUSE: return DIK_PAUSE;
  1131. case KEY_CAPSLOCK: return DIK_CAPSLOCK;
  1132. case KEY_ESCAPE: return DIK_ESCAPE;
  1133. case KEY_SPACE: return DIK_SPACE;
  1134. case KEY_PAGE_DOWN: return DIK_PGDN;
  1135. case KEY_PAGE_UP: return DIK_PGUP;
  1136. case KEY_END: return DIK_END;
  1137. case KEY_HOME: return DIK_HOME;
  1138. case KEY_LEFT: return DIK_LEFT;
  1139. case KEY_UP: return DIK_UP;
  1140. case KEY_RIGHT: return DIK_RIGHT;
  1141. case KEY_DOWN: return DIK_DOWN;
  1142. case KEY_PRINT: return DIK_SYSRQ;
  1143. case KEY_INSERT: return DIK_INSERT;
  1144. case KEY_DELETE: return DIK_DELETE;
  1145. case KEY_HELP: return 0;
  1146. case KEY_0: return DIK_0;
  1147. case KEY_1: return DIK_1;
  1148. case KEY_2: return DIK_2;
  1149. case KEY_3: return DIK_3;
  1150. case KEY_4: return DIK_4;
  1151. case KEY_5: return DIK_5;
  1152. case KEY_6: return DIK_6;
  1153. case KEY_7: return DIK_7;
  1154. case KEY_8: return DIK_8;
  1155. case KEY_9: return DIK_9;
  1156. case KEY_A: return DIK_A;
  1157. case KEY_B: return DIK_B;
  1158. case KEY_C: return DIK_C;
  1159. case KEY_D: return DIK_D;
  1160. case KEY_E: return DIK_E;
  1161. case KEY_F: return DIK_F;
  1162. case KEY_G: return DIK_G;
  1163. case KEY_H: return DIK_H;
  1164. case KEY_I: return DIK_I;
  1165. case KEY_J: return DIK_J;
  1166. case KEY_K: return DIK_K;
  1167. case KEY_L: return DIK_L;
  1168. case KEY_M: return DIK_M;
  1169. case KEY_N: return DIK_N;
  1170. case KEY_O: return DIK_O;
  1171. case KEY_P: return DIK_P;
  1172. case KEY_Q: return DIK_Q;
  1173. case KEY_R: return DIK_R;
  1174. case KEY_S: return DIK_S;
  1175. case KEY_T: return DIK_T;
  1176. case KEY_U: return DIK_U;
  1177. case KEY_V: return DIK_V;
  1178. case KEY_W: return DIK_W;
  1179. case KEY_X: return DIK_X;
  1180. case KEY_Y: return DIK_Y;
  1181. case KEY_Z: return DIK_Z;
  1182. case KEY_TILDE: return DIK_GRAVE;
  1183. case KEY_MINUS: return DIK_MINUS;
  1184. case KEY_EQUALS: return DIK_EQUALS;
  1185. case KEY_LBRACKET: return DIK_LBRACKET;
  1186. case KEY_RBRACKET: return DIK_RBRACKET;
  1187. case KEY_BACKSLASH: return DIK_BACKSLASH;
  1188. case KEY_SEMICOLON: return DIK_SEMICOLON;
  1189. case KEY_APOSTROPHE: return DIK_APOSTROPHE;
  1190. case KEY_COMMA: return DIK_COMMA;
  1191. case KEY_PERIOD: return DIK_PERIOD;
  1192. case KEY_SLASH: return DIK_SLASH;
  1193. case KEY_NUMPAD0: return DIK_NUMPAD0;
  1194. case KEY_NUMPAD1: return DIK_NUMPAD1;
  1195. case KEY_NUMPAD2: return DIK_NUMPAD2;
  1196. case KEY_NUMPAD3: return DIK_NUMPAD3;
  1197. case KEY_NUMPAD4: return DIK_NUMPAD4;
  1198. case KEY_NUMPAD5: return DIK_NUMPAD5;
  1199. case KEY_NUMPAD6: return DIK_NUMPAD6;
  1200. case KEY_NUMPAD7: return DIK_NUMPAD7;
  1201. case KEY_NUMPAD8: return DIK_NUMPAD8;
  1202. case KEY_NUMPAD9: return DIK_NUMPAD9;
  1203. case KEY_MULTIPLY: return DIK_MULTIPLY;
  1204. case KEY_ADD: return DIK_ADD;
  1205. case KEY_SEPARATOR: return DIK_NUMPADCOMMA;
  1206. case KEY_SUBTRACT: return DIK_SUBTRACT;
  1207. case KEY_DECIMAL: return DIK_DECIMAL;
  1208. case KEY_DIVIDE: return DIK_DIVIDE;
  1209. case KEY_NUMPADENTER: return DIK_NUMPADENTER;
  1210. case KEY_F1: return DIK_F1;
  1211. case KEY_F2: return DIK_F2;
  1212. case KEY_F3: return DIK_F3;
  1213. case KEY_F4: return DIK_F4;
  1214. case KEY_F5: return DIK_F5;
  1215. case KEY_F6: return DIK_F6;
  1216. case KEY_F7: return DIK_F7;
  1217. case KEY_F8: return DIK_F8;
  1218. case KEY_F9: return DIK_F9;
  1219. case KEY_F10: return DIK_F10;
  1220. case KEY_F11: return DIK_F11;
  1221. case KEY_F12: return DIK_F12;
  1222. case KEY_F13: return DIK_F13;
  1223. case KEY_F14: return DIK_F14;
  1224. case KEY_F15: return DIK_F15;
  1225. case KEY_F16:
  1226. case KEY_F17:
  1227. case KEY_F18:
  1228. case KEY_F19:
  1229. case KEY_F20:
  1230. case KEY_F21:
  1231. case KEY_F22:
  1232. case KEY_F23:
  1233. case KEY_F24: return 0;
  1234. case KEY_NUMLOCK: return DIK_NUMLOCK;
  1235. case KEY_SCROLLLOCK: return DIK_SCROLL;
  1236. case KEY_LCONTROL: return DIK_LCONTROL;
  1237. case KEY_RCONTROL: return DIK_RCONTROL;
  1238. case KEY_LALT: return DIK_LALT;
  1239. case KEY_RALT: return DIK_RALT;
  1240. case KEY_LSHIFT: return DIK_LSHIFT;
  1241. case KEY_RSHIFT: return DIK_RSHIFT;
  1242. case KEY_WIN_LWINDOW: return DIK_LWIN;
  1243. case KEY_WIN_RWINDOW: return DIK_RWIN;
  1244. case KEY_WIN_APPS: return DIK_APPS;
  1245. case KEY_OEM_102: return DIK_OEM_102;
  1246. };
  1247. return 0;
  1248. }
  1249. //------------------------------------------------------------------------------
  1250. const char* DInputDevice::getJoystickAxesString()
  1251. {
  1252. if ( mDeviceType != JoystickDeviceType )
  1253. return( "" );
  1254. U32 axisCount = mDeviceCaps.dwAxes;
  1255. char buf[64];
  1256. dSprintf( buf, sizeof( buf ), "%d", axisCount );
  1257. for ( U32 i = 0; i < mObjCount; i++ )
  1258. {
  1259. switch ( mObjInfo[i].mType )
  1260. {
  1261. case SI_XAXIS:
  1262. dStrcat( buf, "\tX" );
  1263. break;
  1264. case SI_YAXIS:
  1265. dStrcat( buf, "\tY" );
  1266. break;
  1267. case SI_ZAXIS:
  1268. dStrcat( buf, "\tZ" );
  1269. break;
  1270. case SI_RXAXIS:
  1271. dStrcat( buf, "\tR" );
  1272. break;
  1273. case SI_RYAXIS:
  1274. dStrcat( buf, "\tU" );
  1275. break;
  1276. case SI_RZAXIS:
  1277. dStrcat( buf, "\tV" );
  1278. break;
  1279. case SI_SLIDER:
  1280. dStrcat( buf, "\tS" );
  1281. break;
  1282. }
  1283. }
  1284. char* returnString = Con::getReturnBuffer( dStrlen( buf ) + 1 );
  1285. dStrcpy( returnString, buf );
  1286. return( returnString );
  1287. }
  1288. //------------------------------------------------------------------------------
  1289. bool DInputDevice::joystickDetected()
  1290. {
  1291. return( smJoystickCount > 0 );
  1292. }
  1293. U8 DInputDevice::getJoystickCount()
  1294. {
  1295. return(smJoystickCount);
  1296. }