From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_joystick_8cpp_source.html | 1031 +++++++++++++++++++++++++++ 1 file changed, 1031 insertions(+) create mode 100644 Doc/doxygen/html/_joystick_8cpp_source.html (limited to 'Doc/doxygen/html/_joystick_8cpp_source.html') diff --git a/Doc/doxygen/html/_joystick_8cpp_source.html b/Doc/doxygen/html/_joystick_8cpp_source.html new file mode 100644 index 0000000..2cccbee --- /dev/null +++ b/Doc/doxygen/html/_joystick_8cpp_source.html @@ -0,0 +1,1031 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/nGenEx/Joystick.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
Joystick.cpp
+
+
+Go to the documentation of this file.
1 /* Project nGenEx
+
2  Destroyer Studios LLC
+
3  Copyright (C) 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: nGenEx.lib
+
6  FILE: Joystick.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Joystick Input class
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "Joystick.h"
+
17 #include "MachineInfo.h"
+
18 #include "Game.h"
+
19 
+
20 #define DIRECTINPUT_VERSION 0x0700
+
21 
+
22 #include <dinput.h>
+
23 
+
24 #define JOY_POVUPRIGHT 4500
+
25 #define JOY_POVDNRIGHT 13500
+
26 #define JOY_POVDNLEFT 22500
+
27 #define JOY_POVUPLEFT 31500
+
28 
+
29 // +--------------------------------------------------------------------+
+
30 // DIRECT INPUT SUPPORT
+
31 
+
32 const int MAX_DEVICES = 8;
+
33 
+
34 static LPDIRECTINPUT7 pdi = 0;
+
35 static LPDIRECTINPUTDEVICE7 pdev = 0;
+
36 static DIDEVICEINSTANCE devices[MAX_DEVICES];
+
37 static int ndev = 0;
+
38 static int idev = -1;
+
39 static int strikes = 3;
+
40 
+
41 static Joystick* joystick = 0;
+
42 
+
43 void DirectInputError(const char* msg, HRESULT err);
+
44 char* DIErrStr(HRESULT hr);
+
45 void ReleaseDirectInput();
+
46 
+
47 // +--------------------------------------------------------------------+
+
48 
+ +
50 : x(0), y(0), z(0), p(0), r(0), w(0), t(0)
+
51 {
+
52  if (!joystick)
+
53  joystick = this;
+
54 
+
55  select = 1;
+
56  rudder = 0;
+
57  throttle = 1;
+
58  sensitivity = 25;
+
59  dead_zone = 100;
+
60 
+
61  for (int i = 0; i < MotionController::MaxActions; i++)
+
62  action[i] = false;
+
63 
+
64  for (int i = 0; i < KEY_MAP_SIZE; i++)
+
65  map[i] = 0;
+
66 
+
67  for (int i = 0; i < 4; i++) {
+
68  for (int j = 0; j < 4; j++) {
+
69  hat[i][j] = false;
+
70  }
+
71  }
+
72 
+ + + + +
77 
+
78  inv_axis[0] = false;
+
79  inv_axis[1] = false;
+
80  inv_axis[2] = false;
+
81  inv_axis[3] = false;
+
82 
+ +
84  Print("Joystick: DI7 not found, using multimedia library\n");
+
85  pdi = 0;
+
86  pdev = 0;
+
87  }
+
88 
+
89  else if (!pdi) {
+
90  HRESULT hr = DirectInputCreateEx(Game::GetHINST(),
+ +
92  IID_IDirectInput7,
+
93  (void**)&pdi,
+
94  NULL);
+
95  if FAILED(hr) {
+
96  DirectInputError("Failed to initialize DI7", hr);
+
97  pdi = 0;
+
98  pdev = 0;
+
99  }
+
100  else {
+
101  Print("Joystick: initialized DI7 pdi = %08x\n", (DWORD) pdi);
+
102  }
+
103  }
+
104 }
+
105 
+ +
107 {
+ +
109  joystick = 0;
+
110 }
+
111 
+ +
113 {
+
114  if (pdev) {
+
115  pdev->Unacquire();
+
116  pdev->Release();
+
117  pdev = 0;
+
118  }
+
119 
+
120  if (pdi) {
+
121  pdi->Release();
+
122  pdi = 0;
+
123  }
+
124 }
+
125 
+ +
127 {
+
128  return joystick;
+
129 }
+
130 
+
131 // +--------------------------------------------------------------------+
+
132 
+
133 void
+
134 Joystick::MapKeys(KeyMapEntry* mapping, int nkeys)
+
135 {
+
136  ZeroMemory(map, sizeof(map));
+
137 
+
138  for (int i = 0; i < nkeys; i++) {
+
139  KeyMapEntry k = mapping[i];
+
140 
+
141  if (k.act >= KEY_MAP_FIRST && k.act < KEY_MAP_LAST) {
+
142  if (k.act == KEY_JOY_SENSE)
+
143  sensitivity = k.key;
+
144 
+
145  else if (k.act == KEY_JOY_DEAD_ZONE)
+
146  dead_zone = k.key;
+
147 
+
148  else if (k.act == KEY_JOY_SWAP)
+
149  swapped = k.key;
+
150 
+
151  else if (k.act == KEY_JOY_RUDDER)
+
152  rudder = k.key;
+
153 
+
154  else if (k.act == KEY_JOY_THROTTLE)
+
155  throttle = k.key;
+
156 
+
157  else if (k.act == KEY_JOY_SELECT)
+
158  select = k.key;
+
159 
+
160 
+
161  else if (k.act == KEY_AXIS_YAW)
+
162  map_axis[0] = k.key;
+
163 
+
164  else if (k.act == KEY_AXIS_PITCH)
+
165  map_axis[1] = k.key;
+
166 
+
167  else if (k.act == KEY_AXIS_ROLL)
+
168  map_axis[2] = k.key;
+
169 
+
170  else if (k.act == KEY_AXIS_THROTTLE)
+
171  map_axis[3] = k.key;
+
172 
+
173 
+
174  else if (k.act == KEY_AXIS_YAW_INVERT)
+
175  inv_axis[0] = k.key ? true : false;
+
176 
+
177  else if (k.act == KEY_AXIS_PITCH_INVERT)
+
178  inv_axis[1] = k.key ? true : false;
+
179 
+
180  else if (k.act == KEY_AXIS_ROLL_INVERT)
+
181  inv_axis[2] = k.key ? true : false;
+
182 
+
183  else if (k.act == KEY_AXIS_THROTTLE_INVERT)
+
184  inv_axis[3] = k.key ? true : false;
+
185 
+
186  else if (k.key >= KEY_JOY_1 && k.key <= KEY_JOY_32)
+
187  map[k.act] = k.key;
+
188 
+
189  else if (k.alt >= KEY_JOY_1 && k.alt <= KEY_JOY_32)
+
190  map[k.act] = k.alt;
+
191 
+
192  else if (k.joy >= KEY_JOY_1 && k.joy <= KEY_JOY_32)
+
193  map[k.act] = k.joy;
+
194 
+
195  else if (k.key >= KEY_POV_0_UP && k.key <= KEY_POV_3_RIGHT)
+
196  map[k.act] = k.key;
+
197 
+
198  else if (k.alt >= KEY_POV_0_UP && k.alt <= KEY_POV_3_RIGHT)
+
199  map[k.act] = k.alt;
+
200 
+
201  else if (k.joy >= KEY_POV_0_UP && k.joy <= KEY_POV_3_RIGHT)
+
202  map[k.act] = k.joy;
+
203  }
+
204  }
+
205 }
+
206 
+
207 // +--------------------------------------------------------------------+
+
208 
+
209 static inline double sqr(double a) { return a*a; }
+
210 
+
211 BOOL FAR PASCAL EnumJoystick(LPCDIDEVICEINSTANCE pdinst, LPVOID pvSelect)
+
212 {
+
213  CopyMemory(&devices[ndev++], pdinst, pdinst->dwSize);
+
214 
+
215  ::Print("EnumJoystick %d: '%s'\n", ndev, pdinst->tszInstanceName);
+
216  ::Print(" guid: {%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x} \n",
+
217  (DWORD) pdinst->guidInstance.Data1,
+
218  (WORD) pdinst->guidInstance.Data2,
+
219  (WORD) pdinst->guidInstance.Data3,
+
220  (BYTE) pdinst->guidInstance.Data4[0],
+
221  (BYTE) pdinst->guidInstance.Data4[1],
+
222  (BYTE) pdinst->guidInstance.Data4[2],
+
223  (BYTE) pdinst->guidInstance.Data4[3],
+
224  (BYTE) pdinst->guidInstance.Data4[4],
+
225  (BYTE) pdinst->guidInstance.Data4[5]);
+
226 
+
227  if (ndev < MAX_DEVICES)
+
228  return DIENUM_CONTINUE;
+
229 
+
230  return DIENUM_STOP;
+
231 }
+
232 
+
233 bool CreateDevice(int select)
+
234 {
+
235  if (!pdi || ndev < select)
+
236  return false;
+
237 
+
238  LPCDIDEVICEINSTANCE pdinst = &devices[select-1];
+
239 
+
240  ::Print("Joystick CreateDevice(%d)\n", select);
+
241  ::Print(" name: %s\n\n", pdinst->tszInstanceName);
+
242 
+
243  // release current device before trying to get another:
+
244  if (pdev) {
+
245  pdev->Unacquire();
+
246  pdev->Release();
+
247  pdev = 0;
+
248  }
+
249 
+
250  HRESULT hr = DI_OK;
+
251  // Create the DirectInput joystick device:
+
252  hr = pdi->CreateDeviceEx(pdinst->guidInstance,
+
253  IID_IDirectInputDevice7,
+
254  (void**)&pdev,
+
255  NULL);
+
256 
+
257  if (hr != DI_OK || pdev == 0) {
+
258  DirectInputError("Create Device Ex failed", hr);
+
259  return false;
+
260  }
+
261 
+
262  // Set the data format:
+
263  hr = pdev->SetDataFormat(&c_dfDIJoystick);
+
264 
+
265  if (hr != DI_OK) {
+
266  DirectInputError("Set Data Format failed", hr);
+
267  pdev->Release();
+
268  pdev = 0;
+
269  return false;
+
270  }
+
271 
+
272  // Set the coop level:
+
273  hr = pdev->SetCooperativeLevel(Game::GetHWND(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
+
274 
+
275  if (hr != DI_OK) {
+
276  DirectInputError("Set Cooperative Level failed", hr);
+
277  pdev->Release();
+
278  return false;
+
279  }
+
280 
+
281  // Set data ranges
+
282  DIPROPRANGE diprg;
+
283  diprg.lMin = -32768;
+
284  diprg.lMax = +32768;
+
285 
+
286  diprg.diph.dwSize = sizeof(diprg);
+
287  diprg.diph.dwHeaderSize = sizeof(diprg.diph);
+
288  diprg.diph.dwObj = DIJOFS_X;
+
289  diprg.diph.dwHow = DIPH_BYOFFSET;
+
290  pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
+
291 
+
292  diprg.diph.dwObj = DIJOFS_Y;
+
293  pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
+
294 
+
295  diprg.diph.dwObj = DIJOFS_Z;
+
296  pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
+
297 
+
298  diprg.diph.dwObj = DIJOFS_RX;
+
299  pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
+
300 
+
301  diprg.diph.dwObj = DIJOFS_RY;
+
302  pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
+
303 
+
304  diprg.diph.dwObj = DIJOFS_RZ;
+
305  pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
+
306 
+
307  diprg.diph.dwObj = DIJOFS_SLIDER(0);
+
308  pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
+
309 
+
310  diprg.diph.dwObj = DIJOFS_SLIDER(1);
+
311  pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
+
312 
+
313  ::Print("Created joystick %d (pdev = %08x)\n", select, (DWORD) pdev);
+
314  idev = select;
+
315  return true;
+
316 }
+
317 
+
318 void
+ +
320 {
+
321  if (!pdi) {
+
322  Print("Joystick: no DI7, unable to enumerate devices\n");
+
323  ndev = 0;
+
324  }
+
325 
+
326  else if (ndev < 1) {
+
327  Print("Joystick: preparing to enumerate devices\n");
+
328 
+
329  ndev = 0;
+
330  HRESULT hr =
+
331  pdi->EnumDevices(DIDEVTYPE_JOYSTICK,
+
332  EnumJoystick,
+
333  (LPVOID) 0,
+
334  DIEDFL_ATTACHEDONLY);
+
335 
+
336  if (FAILED(hr)) {
+
337  DirectInputError("Failed to enumerate devices", hr);
+ +
339  }
+
340 
+
341  else if (ndev < 1) {
+
342  Print("Joystick: no devices found\n");
+ +
344  }
+
345  }
+
346 }
+
347 
+
348 int
+ +
350 {
+
351  return ndev;
+
352 }
+
353 
+
354 const char*
+ +
356 {
+
357  if (i >= 0 && i < ndev)
+
358  return devices[i].tszInstanceName;
+
359 
+
360  return 0;
+
361 }
+
362 
+
363 // +--------------------------------------------------------------------+
+
364 
+
365 static DIJOYSTATE joystate;
+
366 static JOYINFOEX joyinfo;
+
367 
+
368 int
+ +
370 {
+
371  if (!joystick)
+
372  return 0;
+
373 
+
374  int result = 0;
+
375 
+
376  if (pdev) {
+
377  switch (a) {
+
378  case KEY_JOY_AXIS_X: result = joystate.lX; break;
+
379  case KEY_JOY_AXIS_Y: result = joystate.lY; break;
+
380  case KEY_JOY_AXIS_Z: result = joystate.lZ; break;
+
381  case KEY_JOY_AXIS_RX: result = joystate.lRx; break;
+
382  case KEY_JOY_AXIS_RY: result = joystate.lRy; break;
+
383  case KEY_JOY_AXIS_RZ: result = joystate.lRz; break;
+
384  case KEY_JOY_AXIS_S0: result = joystate.rglSlider[0]; break;
+
385  case KEY_JOY_AXIS_S1: result = joystate.rglSlider[1]; break;
+
386  }
+
387  }
+
388 
+
389  else {
+
390  switch (a) {
+
391  case KEY_JOY_AXIS_X:
+
392  if (joyinfo.dwFlags & JOY_RETURNX)
+
393  result = joyinfo.dwXpos;
+
394  break;
+
395 
+
396  case KEY_JOY_AXIS_Y:
+
397  if (joyinfo.dwFlags & JOY_RETURNY)
+
398  result = joyinfo.dwYpos;
+
399  break;
+
400 
+
401  case KEY_JOY_AXIS_Z:
+
402  if (joyinfo.dwFlags & JOY_RETURNZ)
+
403  result = joyinfo.dwZpos;
+
404  break;
+
405 
+
406  case KEY_JOY_AXIS_RZ:
+
407  if (joyinfo.dwFlags & JOY_RETURNR)
+
408  result = joyinfo.dwRpos;
+
409  break;
+
410  }
+
411  }
+
412 
+
413  return result;
+
414 }
+
415 
+
416 double
+ +
418 {
+
419  if (a < 0 || a > 3)
+
420  return 0;
+
421 
+
422  double result = 0;
+
423 
+
424  switch (map_axis[a]) {
+
425  case KEY_JOY_AXIS_X: result = joystate.lX; break;
+
426  case KEY_JOY_AXIS_Y: result = joystate.lY; break;
+
427  case KEY_JOY_AXIS_Z: result = joystate.lZ; break;
+
428  case KEY_JOY_AXIS_RX: result = joystate.lRx; break;
+
429  case KEY_JOY_AXIS_RY: result = joystate.lRy; break;
+
430  case KEY_JOY_AXIS_RZ: result = joystate.lRz; break;
+
431  case KEY_JOY_AXIS_S0: result = joystate.rglSlider[0]; break;
+
432  case KEY_JOY_AXIS_S1: result = joystate.rglSlider[1]; break;
+
433  }
+
434 
+
435  if (a < 3) {
+
436  // ignore small movements:
+
437  if (result > dead_zone) result -= dead_zone;
+
438  else if (result < -dead_zone) result += dead_zone;
+
439  else result = 0;
+
440 
+
441  double scale = 1.0 / (32768.0-dead_zone);
+
442 
+
443  if (result >= 0)
+
444  result = sqr(result * scale);
+
445  else
+
446  result = sqr(result * scale) * -1.0;
+
447 
+
448  if (inv_axis[a])
+
449  result = -result;
+
450  }
+
451  else {
+
452  result = (result+32768.0) / 65536.0;
+
453 
+
454  if (inv_axis[a])
+
455  result = 1 - result;
+
456  }
+
457 
+
458 
+
459  return result;
+
460 }
+
461 
+
462 double
+ +
464 {
+
465  if (a < 0 || a > 3)
+
466  return 0;
+
467 
+
468  double result = 0;
+
469 
+
470  switch (map_axis[a]) {
+
471  case KEY_JOY_AXIS_X:
+
472  if (joyinfo.dwFlags & JOY_RETURNX)
+
473  result = joyinfo.dwXpos - 32768;
+
474  break;
+
475 
+
476  case KEY_JOY_AXIS_Y:
+
477  if (joyinfo.dwFlags & JOY_RETURNY)
+
478  result = joyinfo.dwYpos - 32768;
+
479  break;
+
480 
+
481  case KEY_JOY_AXIS_Z:
+
482  if (joyinfo.dwFlags & JOY_RETURNZ)
+
483  result = joyinfo.dwZpos - 32768;
+
484  break;
+
485 
+
486  case KEY_JOY_AXIS_RZ:
+
487  if (joyinfo.dwFlags & JOY_RETURNR)
+
488  result = joyinfo.dwRpos - 32768;
+
489  break;
+
490  }
+
491 
+
492  if (a < 3) {
+
493  // ignore small movements:
+
494  if (result > dead_zone) result -= dead_zone;
+
495  else if (result < -dead_zone) result += dead_zone;
+
496  else result = 0;
+
497 
+
498  double scale = 1.0 / (32768.0-dead_zone);
+
499 
+
500  if (result >= 0)
+
501  result = sqr(result * scale);
+
502  else
+
503  result = sqr(result * scale) * -1.0;
+
504 
+
505  if (inv_axis[a])
+
506  result = -result;
+
507  }
+
508  else {
+
509  result = (result+32768.0) / 65536.0;
+
510 
+
511  if (inv_axis[a])
+
512  result = 1 - result;
+
513  }
+
514 
+
515  return result;
+
516 }
+
517 
+
518 // +--------------------------------------------------------------------+
+
519 
+
520 void
+ +
522 {
+
523  t = x = y = z = p = r = w = 0;
+
524  for (int i = 0; i < MotionController::MaxActions; i++)
+
525  action[i] = false;
+
526 
+
527  for (int i = 0; i < 4; i++)
+
528  for (int j = 0; j < 4; j++)
+
529  hat[i][j] = false;
+
530 
+
531  if (select == 0)
+
532  return;
+
533 
+
534  //============================================================
+
535  //
+
536  // FIRST TRY DIRECT INPUT
+
537 
+
538  bool acquired = false;
+
539 
+
540  if (pdi) {
+
541  if (idev != select) {
+
542  if (ndev < 1)
+ +
544 
+
545  if (CreateDevice(select) && pdev)
+
546  pdev->Acquire();
+
547  }
+
548 
+
549  if (pdev) {
+
550  HRESULT hr = 0;
+
551 
+
552  hr = pdev->Poll();
+
553  hr = pdev->GetDeviceState(sizeof(joystate), &joystate);
+
554 
+
555  if (hr == DIERR_INPUTLOST) {
+
556  pdev->Acquire();
+
557 
+
558  hr = pdev->Poll();
+
559  hr = pdev->GetDeviceState(sizeof(joystate), &joystate);
+
560 
+
561  if (FAILED(hr)) {
+
562  strikes--;
+
563  ::Print("Joystick could not re-acquire joystick (%08x)\n", hr);
+
564 
+
565  // give up before you hurt yourself:
+
566  if (strikes <= 0) {
+ +
568  ndev = 0;
+
569  select = 0;
+
570  }
+
571 
+
572  return;
+
573  }
+
574  }
+
575 
+
576  for (int i = 0; i < 32; i++)
+
577  action[i] = (joystate.rgbButtons[i] & 0x80) != 0;
+
578 
+
579  double joy_x = ReadAxisDI(0);
+
580  double joy_y = ReadAxisDI(1);
+
581  double joy_r = rudder ? ReadAxisDI(2) : 0;
+
582  double joy_t = throttle ? ReadAxisDI(3) : 0;
+
583 
+
584  int joy_p = joystate.rgdwPOV[0];
+
585 
+
586  ProcessAxes(joy_x, joy_y, joy_r, joy_t);
+
587 
+
588  for (int i = 0; i < 4; i++)
+
589  ProcessHat(i, joystate.rgdwPOV[i]);
+
590 
+
591  acquired = true;
+
592  }
+
593  }
+
594 
+
595  //============================================================
+
596  //
+
597  // THEN TRY WINDOWS MULTIMEDIA LIBRARY
+
598 
+
599  if (!acquired) {
+
600  memset(&joyinfo, 0, sizeof(JOYINFOEX));
+
601  joyinfo.dwSize = sizeof(JOYINFOEX);
+
602  joyinfo.dwFlags = JOY_RETURNALL;
+
603 
+
604  HRESULT hr = 0;
+
605 
+
606  if (select == 1)
+
607  hr = joyGetPosEx(JOYSTICKID1, &joyinfo);
+
608 
+
609  else if (select == 2)
+
610  hr = joyGetPosEx(JOYSTICKID2, &joyinfo);
+
611 
+
612  if (hr != 0) {
+
613  Print("\nJoystick::Acquire() joyGetPosEx %d failed (err=%08x)\n\n", select, hr);
+
614  select = 0;
+
615  }
+
616 
+
617  action[0] = (joyinfo.dwButtons & JOY_BUTTON1) ? true : false;
+
618  action[1] = (joyinfo.dwButtons & JOY_BUTTON2) ? true : false;
+
619  action[2] = (joyinfo.dwButtons & JOY_BUTTON3) ? true : false;
+
620  action[3] = (joyinfo.dwButtons & JOY_BUTTON4) ? true : false;
+
621 
+
622  double joy_x = ReadAxisMM(0);
+
623  double joy_y = ReadAxisMM(1);
+
624  double joy_r = rudder ? ReadAxisMM(2) : 0;
+
625  double joy_t = throttle ? ReadAxisMM(3) : 0;
+
626 
+
627  ProcessAxes(joy_x, joy_y, joy_r, joy_t);
+
628  ProcessHat(0, joyinfo.dwPOV);
+
629  }
+
630 
+
631  // lateral translations:
+
632  if (KeyDownMap(KEY_PLUS_Y)) y = 1;
+
633  else if (KeyDownMap(KEY_MINUS_Y)) y = -1;
+
634 
+
635  if (KeyDownMap(KEY_PLUS_Z)) z = 1;
+
636  else if (KeyDownMap(KEY_MINUS_Z)) z = -1;
+
637 
+
638  if (KeyDownMap(KEY_MINUS_X)) x = -1;
+
639  else if (KeyDownMap(KEY_PLUS_X)) x = 1;
+
640 
+
641  // button-based turns:
+
642  const double steps=10;
+
643  static double p1=0, r1=0, w1=0;
+
644 
+
645  // if roll and yaw are swapped --------------------------
+
646  if (swapped) {
+
647  // yaw:
+
648  if (KeyDownMap(KEY_ROLL_LEFT)) { if (w1<steps) w1+=1; w = -sqr(w1/steps); }
+
649  else if (KeyDownMap(KEY_ROLL_RIGHT)) { if (w1<steps) w1+=1; w = sqr(w1/steps); }
+
650 
+
651  // roll:
+
652  if (KeyDownMap(KEY_YAW_LEFT)) { if (r1<steps) r1+=1; r = sqr(r1/steps); }
+
653  else if (KeyDownMap(KEY_YAW_RIGHT)) { if (r1<steps) r1+=1; r = -sqr(r1/steps); }
+
654  else w1 = 0;
+
655  }
+
656 
+
657  // else roll and yaw are NOT swapped ---------------------
+
658  else {
+
659  // roll:
+
660  if (KeyDownMap(KEY_ROLL_LEFT)) { if (r1<steps) r1+=1; r = sqr(r1/steps); }
+
661  else if (KeyDownMap(KEY_ROLL_RIGHT)) { if (r1<steps) r1+=1; r = -sqr(r1/steps); }
+
662 
+
663  // yaw left-right
+
664  if (KeyDownMap(KEY_YAW_LEFT)) { if (w1<steps) w1+=1; w = -sqr(w1/steps); }
+
665  else if (KeyDownMap(KEY_YAW_RIGHT)) { if (w1<steps) w1+=1; w = sqr(w1/steps); }
+
666  else w1 = 0;
+
667  }
+
668 
+
669  // pitch --------------------------------------------------
+
670  if (KeyDownMap(KEY_PITCH_UP)) { if (p1<steps) p1+=1; p = -sqr(p1/steps); }
+
671  else if (KeyDownMap(KEY_PITCH_DOWN)) { if (p1<steps) p1+=1; p = sqr(p1/steps); }
+
672  else p1 = 0;
+
673 }
+
674 
+
675 // +--------------------------------------------------------------------+
+
676 
+
677 void
+
678 Joystick::ProcessAxes(double joy_x, double joy_y, double joy_r, double joy_t)
+
679 {
+
680  int roll_enable = 0;
+
681 
+
682  joy_y *= -1;
+
683  joy_t = 1 - joy_t;
+
684 
+
685  if (map[KEY_ROLL_ENABLE])
+
686  roll_enable = action[map[KEY_ROLL_ENABLE] - KEY_JOY_1];
+
687 
+
688  // if roll and yaw are swapped --------------------------
+
689  if (swapped) {
+
690  if (roll_enable) {
+
691  w = joy_x;
+
692  r = joy_r;
+
693  }
+
694  else {
+
695  w = joy_r;
+
696  r = -joy_x;
+
697  }
+
698  }
+
699 
+
700  // else roll and yaw are NOT swapped ---------------------
+
701  else {
+
702  if (roll_enable) {
+
703  w = joy_r;
+
704  r = joy_x;
+
705  }
+
706  else {
+
707  w = joy_x;
+
708  r = -joy_r;
+
709  }
+
710  }
+
711 
+
712  p = joy_y;
+
713 
+
714  // read throttle:
+
715  if (throttle) {
+
716  static double init_throttle = -1;
+
717  static bool latch_throttle = false;
+
718 
+
719  if (init_throttle < 0)
+
720  init_throttle = joy_t;
+
721  else if (init_throttle != joy_t)
+
722  latch_throttle = true;
+
723 
+
724  if (latch_throttle)
+
725  t = joy_t;
+
726  else
+
727  t = 0;
+
728  }
+
729  else {
+
730  t = 0;
+
731  }
+
732 }
+
733 
+
734 void
+
735 Joystick::ProcessHat(int i, DWORD joy_pov)
+
736 {
+
737  if (i < 0 || i > 3) return;
+
738 
+
739  if (LOWORD(joy_pov) == 0xFFFF)
+
740  return;
+
741 
+
742  switch (joy_pov) {
+
743  case JOY_POVFORWARD: hat[i][0] = true; break;
+
744  case JOY_POVBACKWARD: hat[i][1] = true; break;
+
745  case JOY_POVLEFT: hat[i][2] = true; break;
+
746  case JOY_POVRIGHT: hat[i][3] = true; break;
+
747 
+
748  case JOY_POVUPRIGHT: hat[i][0] = true;
+
749  hat[i][3] = true; break;
+
750 
+
751  case JOY_POVDNRIGHT: hat[i][1] = true;
+
752  hat[i][3] = true; break;
+
753 
+
754  case JOY_POVDNLEFT: hat[i][1] = true;
+
755  hat[i][2] = true; break;
+
756 
+
757  case JOY_POVUPLEFT: hat[i][0] = true;
+
758  hat[i][2] = true; break;
+
759 
+
760  default: break;
+
761  }
+
762 }
+
763 
+
764 // +--------------------------------------------------------------------+
+
765 
+
766 bool Joystick::KeyDown(int key)
+
767 {
+
768  if (!joystick)
+
769  return false;
+
770 
+
771  if (key >= KEY_JOY_1 && key <= KEY_JOY_32)
+
772  return joystick->action[key - KEY_JOY_1];
+
773 
+
774  else if (key >= KEY_POV_0_UP && key <= KEY_POV_0_RIGHT)
+
775  return joystick->hat[0][key - KEY_POV_0_UP];
+
776 
+
777  else if (key >= KEY_POV_1_UP && key <= KEY_POV_1_RIGHT)
+
778  return joystick->hat[1][key - KEY_POV_1_UP];
+
779 
+
780  else if (key >= KEY_POV_2_UP && key <= KEY_POV_2_RIGHT)
+
781  return joystick->hat[2][key - KEY_POV_2_UP];
+
782 
+
783  else if (key >= KEY_POV_3_UP && key <= KEY_POV_3_RIGHT)
+
784  return joystick->hat[3][key - KEY_POV_3_UP];
+
785 
+
786  return false;
+
787 }
+
788 
+
789 // +--------------------------------------------------------------------+
+
790 
+
791 bool Joystick::KeyDownMap(int key)
+
792 {
+
793  if (!joystick)
+
794  return false;
+
795 
+
796  if (key >= KEY_MAP_FIRST && key <= KEY_MAP_LAST && joystick->map[key])
+
797  return KeyDown(joystick->map[key]);
+
798 
+
799  return false;
+
800 }
+
801 
+
802 // +--------------------------------------------------------------------+
+
803 
+ +
805 {
+
806  if (!joystick || n < 0 || n > 3)
+
807  return -1;
+
808 
+
809  return joystick->map_axis[n];
+
810 }
+
811 
+ +
813 {
+
814  if (!joystick || n < 0 || n > 3)
+
815  return -1;
+
816 
+
817  return joystick->inv_axis[n];
+
818 }
+
819 
+
820 // +--------------------------------------------------------------------+
+
821 
+
822 void
+
823 DirectInputError(const char* msg, HRESULT err)
+
824 {
+
825  static int report = 50;
+
826  if (report > 0)
+
827  report--;
+
828  else
+
829  return;
+
830 
+
831  Print(" DirectInput7: %s. [%s]\n", msg, DIErrStr(err));
+
832 }
+
833 
+
834 static char errstrbuf[128];
+
835 
+
836 char* DIErrStr(HRESULT hr)
+
837 {
+
838  switch (hr) {
+
839  default:
+
840  sprintf_s(errstrbuf, "Unrecognized error value = %08x.", hr);
+
841  return errstrbuf;
+
842 
+
843  case DI_OK:
+
844  return "No error.";
+
845 
+
846  case DI_BUFFEROVERFLOW:
+
847  return "The device buffer overflowed and some input was lost. This value is equal to the S_FALSE standard COM return value.";
+
848  case DI_DOWNLOADSKIPPED:
+
849  return "The parameters of the effect were successfully updated, but the effect could not be downloaded because the associated device was not acquired in exclusive mode.";
+
850  case DI_EFFECTRESTARTED:
+
851  return "The effect was stopped, the parameters were updated, and the effect was restarted.";
+
852  case DI_POLLEDDEVICE:
+
853  return "The device is a polled device. As a result, device buffering does not collect any data and event notifications is not signaled until the IDirectInputDevice7::Poll method is called.";
+
854  case DI_TRUNCATED:
+
855  return "The parameters of the effect were successfully updated, but some of them were beyond the capabilities of the device and were truncated to the nearest supported value.";
+
856  case DI_TRUNCATEDANDRESTARTED:
+
857  return "Equal to DI_EFFECTRESTARTED | DI_TRUNCATED";
+
858  case DIERR_ACQUIRED:
+
859  return "The operation cannot be performed while the device is acquired.";
+
860  case DIERR_ALREADYINITIALIZED:
+
861  return "This object is already initialized";
+
862  case DIERR_BADDRIVERVER:
+
863  return "The object could not be created due to an incompatible driver version or mismatched or incomplete driver components.";
+
864  case DIERR_BETADIRECTINPUTVERSION:
+
865  return "The application was written for an unsupported prerelease version of DirectInput.";
+
866  case DIERR_DEVICEFULL:
+
867  return "The device is full.";
+
868  case DIERR_DEVICENOTREG:
+
869  return "The device or device instance is not registered with DirectInput. This value is equal to the REGDB_E_CLASSNOTREG standard COM return value.";
+
870  case DIERR_EFFECTPLAYING:
+
871  return "The parameters were updated in memory but were not downloaded to the device because the device does not support updating an effect while it is still playing.";
+
872  case DIERR_HASEFFECTS:
+
873  return "The device cannot be reinitialized because there are still effects attached to it.";
+
874  case DIERR_GENERIC:
+
875  return "An undetermined error occurred inside the DirectInput subsystem. This value is equal to the E_FAIL standard COM return value.";
+
876  case DIERR_HANDLEEXISTS:
+
877  return "The device already has an event notification associated with it. This value is equal to the E_ACCESSDENIED standard COM return value.";
+
878  case DIERR_INCOMPLETEEFFECT:
+
879  return "The effect could not be downloaded because essential information is missing. For example, no axes have been associated with the effect, or no type-specific information has been supplied.";
+
880  case DIERR_INPUTLOST:
+
881  return "Access to the input device has been lost. It must be reacquired.";
+
882  case DIERR_INVALIDPARAM:
+
883  return "An invalid parameter was passed to the returning function, or the object was not in a state that permitted the function to be called. This value is equal to the E_INVALIDARG standard COM return value.";
+
884  case DIERR_MOREDATA:
+
885  return "Not all the requested information fit into the buffer.";
+
886  case DIERR_NOAGGREGATION:
+
887  return "This object does not support aggregation.";
+
888  case DIERR_NOINTERFACE:
+
889  return "The specified interface is not supported by the object. This value is equal to the E_NOINTERFACE standard COM return value.";
+
890  case DIERR_NOTACQUIRED:
+
891  return "The operation cannot be performed unless the device is acquired.";
+
892  case DIERR_NOTBUFFERED:
+
893  return "The device is not buffered. Set the DIPROP_BUFFERSIZE property to enable buffering.";
+
894  case DIERR_NOTDOWNLOADED:
+
895  return "The effect is not downloaded.";
+
896  case DIERR_NOTEXCLUSIVEACQUIRED:
+
897  return "The operation cannot be performed unless the device is acquired in DISCL_EXCLUSIVE mode.";
+
898  case DIERR_NOTFOUND:
+
899  return "The requested object does not exist.";
+
900  case DIERR_NOTINITIALIZED:
+
901  return "This object has not been initialized.";
+
902  case DIERR_OLDDIRECTINPUTVERSION:
+
903  return "The application requires a newer version of DirectInput.";
+
904  case DIERR_OUTOFMEMORY:
+
905  return "The DirectInput subsystem could not allocate sufficient memory to complete the call. This value is equal to the E_OUTOFMEMORY standard COM return value.";
+
906  case DIERR_REPORTFULL:
+
907  return "More information was requested to be sent than can be sent to the device.";
+
908  case DIERR_UNPLUGGED:
+
909  return "The operation could not be completed because the device is not plugged in.";
+
910  case DIERR_UNSUPPORTED:
+
911  return "The function called is not supported at this time. This value is equal to the E_NOTIMPL standard COM return value.";
+
912  }
+
913 }
+
914 
+
+
+ + + + -- cgit v1.1