Take care of a few more compiler warnings.
[dolphin.git] / Source / Plugins / Plugin_Wiimote / Src / FillReport.cpp
bloba54eb23914ca0cf74f9d27c5ce579505555d3816
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
18 #include <wx/msgdlg.h>
20 #include <vector>
21 #include <string>
23 #include "Common.h" // Common
24 #include "Timer.h"
25 #include "pluginspecs_wiimote.h"
26 #include "StringUtil.h" // For ArrayToString
28 #include "wiimote_hid.h"
29 #include "main.h"
30 #include "EmuMain.h"
31 #include "EmuSubroutines.h"
32 #include "EmuDefinitions.h"
33 #include "Config.h" // For g_Config
35 extern SWiimoteInitialize g_WiimoteInitialize;
37 namespace WiiMoteEmu
40 // Recorded movements
41 // Variables: 0 = Wiimote, 1 = Nunchuck
42 int g_RecordingPlaying[3]; //g_RecordingPlaying[0] = -1; g_RecordingPlaying[1] = -1;
43 int g_RecordingCounter[3]; //g_RecordingCounter[0] = 0; g_RecordingCounter[1] = 0;
44 int g_RecordingPoint[3]; //g_RecordingPoint[0] = 0; g_RecordingPoint[1] = 0;
45 double g_RecordingStart[3]; //g_RecordingStart[0] = 0; g_RecordingStart[1] = 0;
46 double g_RecordingCurrentTime[3]; //g_RecordingCurrentTime[0] = 0; g_RecordingCurrentTime[1] = 0;
48 /* Convert from -350 to -3.5 g. The Nunchuck gravity size is 51 compared to the 26 to 28 for the Wiimote.
49 So the maximum g values are higher for the Wiimote. */
50 int G2Accelerometer(int _G, int XYZ, int Wm)
52 float G = (float)_G / 100.0;
53 float Neutral = 0.0, OneG = 0.0, Accelerometer;
55 switch(XYZ)
57 case 0: // X
58 if(Wm == WM_RECORDING_WIIMOTE)
60 OneG = (float)g_wm.cal_g.x;
61 Neutral = (float)g_wm.cal_zero.x;
63 else
65 OneG = (float)g_nu.cal_g.x;
66 Neutral = (float)g_nu.cal_zero.x;
68 break;
69 case 1: // Y
70 if(Wm == WM_RECORDING_WIIMOTE)
72 OneG = (float)g_wm.cal_g.y;
73 Neutral = (float)g_wm.cal_zero.y;
75 else
77 OneG = (float)g_nu.cal_g.y;
78 Neutral = (float)g_nu.cal_zero.y;
80 break;
81 case 2: // Z
82 if(Wm == WM_RECORDING_WIIMOTE)
84 OneG = (float)g_wm.cal_g.z;
85 Neutral = (float)g_wm.cal_zero.z;
87 else
89 OneG = (float)g_nu.cal_g.z;
90 Neutral = (float)g_nu.cal_zero.z;
92 break;
93 default: PanicAlert("There is a syntax error in a function that is calling G2Accelerometer(%i, %i)", _G, XYZ);
96 Accelerometer = Neutral + (OneG * G);
97 int Return = (int)Accelerometer;
99 // Logging
100 //DEBUG_LOG(WIIMOTE, "G2Accelerometer():%f %f %f %f", Neutral, OneG, G, Accelerometer);
102 // Boundaries
103 if (Return > 255) Return = 255;
104 if (Return < 0) Return = 0;
106 return Return;
109 template<class IRReportType>
110 bool RecordingPlayAccIR(u8 &_x, u8 &_y, u8 &_z, IRReportType &_IR, int Wm)
112 // Check if the recording is on
113 if (g_RecordingPlaying[Wm] == -1) return false;
115 // Return if the list is empty
116 if(VRecording.at(g_RecordingPlaying[Wm]).Recording.size() == 0)
118 g_RecordingPlaying[Wm] = -1;
119 DEBUG_LOG(WIIMOTE, "Empty");
120 return false;
123 // Return if the playback speed is unset
124 if(VRecording.at(g_RecordingPlaying[Wm]).PlaybackSpeed < 0)
126 DEBUG_LOG(WIIMOTE, "PlaybackSpeed empty: %i", g_RecordingPlaying[Wm]);
127 g_RecordingPlaying[Wm] = -1;
128 return false;
131 // Get IR bytes
132 int IRBytes = VRecording.at(g_RecordingPlaying[Wm]).IRBytes;
134 // Return if the IR mode is wrong
135 if (Wm == WM_RECORDING_IR
136 && ( (IRBytes == 12 && !(g_ReportingMode[g_ID] == 0x33))
137 || (IRBytes == 10 && !(g_ReportingMode[g_ID] == 0x36 || g_ReportingMode[g_ID] == 0x37))
141 DEBUG_LOG(WIIMOTE, "Wrong IR mode: %i", g_RecordingPlaying[Wm]);
142 g_RecordingPlaying[Wm] = -1;
143 return false;
146 // Get starting time
147 if(g_RecordingCounter[Wm] == 0)
149 DEBUG_LOG(WIIMOTE, "Begin: %i", Wm);
150 g_RecordingStart[Wm] = Common::Timer::GetDoubleTime();
153 // Get current time
154 g_RecordingCurrentTime[Wm] = Common::Timer::GetDoubleTime() - g_RecordingStart[Wm];
156 // Modify the current time
157 g_RecordingCurrentTime[Wm] *= ((25.0 + (double)VRecording.at(g_RecordingPlaying[Wm]).PlaybackSpeed * 25.0) / 100.0);
159 // Select reading
160 for (int i = 0; i < (int)VRecording.at(g_RecordingPlaying[Wm]).Recording.size(); i++)
161 if (VRecording.at(g_RecordingPlaying[Wm]).Recording.at(i).Time > g_RecordingCurrentTime[Wm])
163 g_RecordingPoint[Wm] = i;
164 break; // Break loop
167 // Return if we are at the end of the list
168 if(g_RecordingCurrentTime[Wm] >=
169 VRecording.at(g_RecordingPlaying[Wm]).Recording.at(
170 VRecording.at(g_RecordingPlaying[Wm]).Recording.size() - 1).Time)
171 // Or if we are playing back all observations regardless of time
172 //g_RecordingPoint[Wm] = g_RecordingCounter[Wm];
173 //if (g_RecordingPoint[Wm] >= VRecording.at(g_RecordingPlaying[Wm]).Recording.size())
175 g_RecordingCounter[Wm] = 0;
176 g_RecordingPlaying[Wm] = -1;
177 g_RecordingStart[Wm] = 0;
178 g_RecordingCurrentTime[Wm] = 0;
179 DEBUG_LOG(WIIMOTE, "End: %i", Wm);
180 return false;
183 // Update accelerometer values
184 _x = G2Accelerometer(VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).x, 0, Wm);
185 _y = G2Accelerometer(VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).y, 1, Wm);
186 _z = G2Accelerometer(VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).z, 2, Wm);
187 // Update IR values
188 if(Wm == WM_RECORDING_IR) memcpy(&_IR, VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).IR, IRBytes);
190 if (g_DebugAccelerometer)
192 //Console::ClearScreen();
193 DEBUG_LOG(WIIMOTE, "Current time: [%i / %i] %f %f",
194 g_RecordingPoint[Wm], VRecording.at(g_RecordingPlaying[Wm]).Recording.size(),
195 VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).Time, g_RecordingCurrentTime[Wm]
197 DEBUG_LOG(WIIMOTE, "Accel x, y, z: %03u %03u %03u", _x, _y, _z);
199 //DEBUG_LOG(WIIMOTE, "Accel x, y, z: %03u %03u %03u", _x, _y, _z);
201 g_RecordingCounter[Wm]++;
203 return true;
206 /* Because the playback is neatly controlled by RecordingPlayAccIR() we use these functions to be able to
207 use RecordingPlayAccIR() for both accelerometer and IR recordings */
208 bool RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm)
210 wm_ir_basic IR;
211 return RecordingPlayAccIR(_x, _y, _z, IR, Wm);
214 template<class IRReportType>
215 bool RecordingPlayIR(IRReportType &_IR)
217 u8 x, y, z;
218 return RecordingPlayAccIR(x, y, z, _IR, 2);
221 // Return true if this particual numerical key is pressed
222 bool IsNumericalKeyPressed(int _Key)
224 #ifdef _WIN32
225 // Check which key it is
226 std::string TmpKey = StringFromFormat("%i", _Key);
227 if(GetAsyncKeyState(TmpKey[0]))
228 return true;
229 else
230 // That numerical key is pressed
231 return false;
232 #else
233 // TODO linux port
234 return false;
235 #endif
238 // Check if a switch is pressed
239 bool IsSwitchPressed(int _Key)
241 #ifdef _WIN32
242 // Check if that switch is pressed
243 switch (_Key)
245 case 0: if (GetAsyncKeyState(VK_SHIFT)) return true;
246 case 1: if (GetAsyncKeyState(VK_CONTROL)) return true;
247 case 2: if (GetAsyncKeyState(VK_MENU)) return true;
250 // That switch was not pressed
251 return false;
252 #else
253 // TODO linux port
254 return false;
255 #endif
258 // Check if we should start the playback of a recording. Once it has been started it can currently
259 // not be stopped, it will always run to the end of the recording.
260 int RecordingCheckKeys(int WmNuIr)
262 #ifdef _WIN32
263 //DEBUG_LOG(WIIMOTE, "RecordingCheckKeys: %i", Wiimote);
265 // Check if we have a HotKey match
266 bool Match = false;
267 int Recording = -1;
268 for(int i = 0; i < RECORDING_ROWS; i++)
270 // Check all ten numerical keys
271 for(int j = 0; j < 10; j++)
273 if ((VRecording.at(i).HotKeyWiimote == j && WmNuIr == 0 && IsNumericalKeyPressed(j)
274 || VRecording.at(i).HotKeyNunchuck == j && WmNuIr == 1 && IsNumericalKeyPressed(j)
275 || VRecording.at(i).HotKeyIR == j && WmNuIr == 2 && IsNumericalKeyPressed(j))
276 && (IsSwitchPressed(VRecording.at(i).HotKeySwitch) || VRecording.at(i).HotKeySwitch == 3))
278 //DEBUG_LOG(WIIMOTE, "Match: %i %i", i, Key);
279 Match = true;
280 Recording = i;
281 break;
286 // Return nothing if we don't have a match
287 if (!Match) return -1;
289 // Return the match
290 return Recording;
291 #else
292 return -1;
293 #endif
297 // Multi System Input Status Check
298 bool IsKey(int Key)
300 int Ret = false;
302 if (WiiMapping[g_ID].Source == 1)
304 int MapKey = WiiMapping[g_ID].Button[Key];
306 #ifdef _WIN32
307 if (MapKey < 256)
309 Ret = GetAsyncKeyState(MapKey); // Keyboard (Windows)
311 else if (MapKey < 0x1100)
312 #elif defined(HAVE_X11) && HAVE_X11
313 if (MapKey < 256 || MapKey >= 0xf000)
315 char keys[32];
316 KeyCode keyCode;
317 XQueryKeymap(WMdisplay, keys);
318 keyCode = XKeysymToKeycode(WMdisplay, MapKey);
319 Ret = (keys[keyCode/8] & (1 << (keyCode%8))); // Keyboard (Linux)
321 else if (MapKey < 0x1100)
322 #else
323 if (MapKey < 0x1100)
324 #endif
326 Ret = SDL_JoystickGetButton(WiiMapping[g_ID].joy, MapKey - 0x1000); // Pad button
328 else // Pad hat
330 u8 HatCode, HatKey;
331 HatCode = SDL_JoystickGetHat(WiiMapping[g_ID].joy, (MapKey - 0x1100) / 0x0010);
332 HatKey = (MapKey - 0x1100) % 0x0010;
334 if (HatCode & HatKey)
335 Ret = HatKey;
338 #ifdef _WIN32
339 if ((Key == EWM_SHAKE && GetAsyncKeyState(VK_MBUTTON))
340 || (Key == EWM_A && GetAsyncKeyState(VK_LBUTTON))
341 || (Key == EWM_B && GetAsyncKeyState(VK_RBUTTON)))
343 float x, y;
344 GetMousePos(x, y);
345 Ret = !(x < 0 || x > 1 || y < 0 || y > 1);
347 #endif
348 #if defined(HAVE_X11) && HAVE_X11
349 if (Key == EWM_SHAKE || Key == EWM_A || Key == EWM_B)
351 Window GLWin = *(Window *)g_WiimoteInitialize.pXWindow;
352 int root_x, root_y, win_x, win_y;
353 Window rootDummy, childWin;
354 unsigned int mask;
355 XQueryPointer(WMdisplay, GLWin, &rootDummy, &childWin, &root_x, &root_y, &win_x, &win_y, &mask);
356 if (((Key == EWM_A) && (mask & Button1Mask))
357 || ((Key == EWM_B) && (mask & Button3Mask))
358 || ((Key == EWM_SHAKE) && (mask & Button3Mask)))
360 float x, y;
361 GetMousePos(x, y);
362 Ret = !(x < 0 || x > 1 || y < 0 || y > 1);
365 #endif
368 return (Ret) ? true : false;
371 // Wiimote core buttons
372 void FillReportInfo(wm_core& _core)
374 // Check that Dolphin is in focus
375 if (!IsFocus()) return;
377 u32 mask=0;
378 if (WiiMapping[g_ID].UDPWM.instance)
379 WiiMapping[g_ID].UDPWM.instance->update();
381 if ((WiiMapping[g_ID].UDPWM.instance)&&(WiiMapping[g_ID].UDPWM.enableButtons))
382 mask=WiiMapping[g_ID].UDPWM.instance->getButtons();
384 // Allow both mouse buttons and keyboard to press a and b
385 _core.a = IsKey(EWM_A)||(mask&UDPWM_BA);
386 _core.b = IsKey(EWM_B)||(mask&UDPWM_BB);
387 _core.one = IsKey(EWM_ONE)||(mask&UDPWM_B1);
388 _core.two = IsKey(EWM_TWO)||(mask&UDPWM_B2);
389 _core.plus = IsKey(EWM_P)||(mask&UDPWM_BP);
390 _core.minus = IsKey(EWM_M)||(mask&UDPWM_BM);
391 _core.home = IsKey(EWM_H)||(mask&UDPWM_BH);
393 /* Sideways controls (for example for Wario Land) if the Wiimote is intended to be held sideways */
394 if(WiiMapping[g_ID].bSideways)
396 _core.left = IsKey(EWM_D)||(mask&UDPWM_BL);
397 _core.up = IsKey(EWM_L)||(mask&UDPWM_BU);
398 _core.right = IsKey(EWM_U)||(mask&UDPWM_BR);
399 _core.down = IsKey(EWM_R)||(mask&UDPWM_BU);
401 else
403 _core.left = IsKey(EWM_L)||(mask&UDPWM_BL);
404 _core.up = IsKey(EWM_U)||(mask&UDPWM_BU);
405 _core.right = IsKey(EWM_R)||(mask&UDPWM_BR);
406 _core.down = IsKey(EWM_D)||(mask&UDPWM_BD);
410 void FillReportAcc(wm_accel& _acc)
412 // Recorded movements
413 // Check for a playback command
414 if (g_RecordingPlaying[0] < 0)
416 g_RecordingPlaying[0] = RecordingCheckKeys(0);
418 else
420 // If the recording reached the end or failed somehow we will not return
421 if (RecordingPlay(_acc.x, _acc.y, _acc.z, 0))
422 return;
423 //DEBUG_LOG(WIIMOTE, "X, Y, Z: %u %u %u", _acc.x, _acc.y, _acc.z);
426 // Initial value
427 _acc.x = g_wm.cal_zero.x;
428 _acc.y = g_wm.cal_zero.y;
429 _acc.z = g_wm.cal_zero.z;
431 // Adjust position, also add some noise to prevent disconnection
432 if (!WiiMapping[g_ID].bUpright)
433 _acc.z += g_wm.cal_g.z + WiiMapping[g_ID].Motion.TiltWM.FakeNoise;
434 else // Upright wiimote
435 _acc.y -= g_wm.cal_g.y + WiiMapping[g_ID].Motion.TiltWM.FakeNoise;
437 WiiMapping[g_ID].Motion.TiltWM.FakeNoise = -WiiMapping[g_ID].Motion.TiltWM.FakeNoise;
439 if (IsFocus())
441 int acc_x = _acc.x;
442 int acc_y = _acc.y;
443 int acc_z = _acc.z;
445 if ((WiiMapping[g_ID].UDPWM.instance && WiiMapping[g_ID].UDPWM.enableButtons
446 && (WiiMapping[g_ID].UDPWM.instance->getButtons() & UDPWM_SK))
447 || (IsKey(EWM_SHAKE) && !WiiMapping[g_ID].Motion.TiltWM.Shake))
448 WiiMapping[g_ID].Motion.TiltWM.Shake = 1;
450 // Step the shake simulation one step
451 ShakeToAccelerometer(acc_x, acc_y, acc_z, WiiMapping[g_ID].Motion.TiltWM);
453 // Tilt Wiimote, allow the shake function to interrupt it
454 if (!WiiMapping[g_ID].Motion.TiltWM.Shake)
455 TiltWiimote(acc_x, acc_y, acc_z);
457 // Boundary check
458 if (acc_x > 0xFF) acc_x = 0xFF;
459 else if (acc_x < 0x00) acc_x = 0x00;
460 if (acc_y > 0xFF) acc_y = 0xFF;
461 else if (acc_y < 0x00) acc_y = 0x00;
462 if (acc_z > 0xFF) acc_z = 0xFF;
463 else if (acc_z < 0x00) acc_z = 0x00;
465 _acc.x = acc_x;
466 _acc.y = acc_y;
467 _acc.z = acc_z;
470 // Debugging for translating Wiimote to Keyboard (or Gamepad)
473 // Toogle console display
474 if(GetAsyncKeyState('U'))
476 if(consoleDisplay < 2)
477 consoleDisplay ++;
478 else
479 consoleDisplay = 0;
482 if(GetAsyncKeyState('5'))
483 A-=1;
484 else if(GetAsyncKeyState('6'))
485 A+=1;
486 if(GetAsyncKeyState('7'))
487 B-=1;
488 else if(GetAsyncKeyState('8'))
489 B+=1;
490 if(GetAsyncKeyState('9'))
491 C-=1;
492 else if(GetAsyncKeyState('0'))
493 C+=1;
495 else if(GetAsyncKeyState(VK_NUMPAD3))
496 d-=1;
497 else if(GetAsyncKeyState(VK_NUMPAD6))
498 d+=1;
499 else if(GetAsyncKeyState(VK_ADD))
500 yhistsize-=1;
501 else if(GetAsyncKeyState(VK_SUBTRACT))
502 yhistsize+=1;
505 if(GetAsyncKeyState(VK_INSERT))
506 AX-=1;
507 else if(GetAsyncKeyState(VK_DELETE))
508 AX+=1;
509 else if(GetAsyncKeyState(VK_HOME))
510 AY-=1;
511 else if(GetAsyncKeyState(VK_END))
512 AY+=1;
513 else if(GetAsyncKeyState(VK_SHIFT))
514 AZ-=1;
515 else if(GetAsyncKeyState(VK_CONTROL))
516 AZ+=1;
518 if(GetAsyncKeyState(VK_NUMPAD1))
519 X+=1;
520 else if(GetAsyncKeyState(VK_NUMPAD2))
521 X-=1;
522 if(GetAsyncKeyState(VK_NUMPAD4))
523 Y+=1;
524 else if(GetAsyncKeyState(VK_NUMPAD5))
525 Y-=1;
526 if(GetAsyncKeyState(VK_NUMPAD7))
527 Z+=1;
528 else if(GetAsyncKeyState(VK_NUMPAD8))
529 Z-=1;
531 //if(consoleDisplay == 0)
532 DEBUG_LOG(WIIMOTE, "x: %03i | y: %03i | z: %03i | A:%i B:%i C:%i a:%i b:%i c:%i d:%i X:%i Y:%i Z:%i",
533 _acc.x, _acc.y, _acc.z,
534 A, B, C,
535 a, b, c, d,
536 X, Y, Z
538 DEBUG_LOG(WIIMOTE, "x: %03i | y: %03i | z: %03i | X:%i Y:%i Z:%i | AX:%i AY:%i AZ:%i ",
539 _acc.x, _acc.y, _acc.z,
540 X, Y, Z,
541 AX, AY, AZ
542 );*/
545 // The extended 12 byte (3 byte per object) reporting
546 void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
548 // Recorded movements
549 // Check for a playback command
550 if(g_RecordingPlaying[2] < 0)
552 g_RecordingPlaying[2] = RecordingCheckKeys(2);
554 else
556 //DEBUG_LOG(WIIMOTE, "X, Y, Z: %u %u %u", _acc.x, _acc.y, _acc.z);
557 if (RecordingPlayIR(_ir0)) return;
560 /* Fill with 0xff if empty. The real Wiimote seems to use 0xff when it
561 doesn't see a certain point, at least from how WiiMoteReal::SendEvent()
562 works. */
563 memset(&_ir0, 0xff, sizeof(wm_ir_extended));
564 memset(&_ir1, 0xff, sizeof(wm_ir_extended));
566 float MouseX, MouseY;
567 if ((WiiMapping[g_ID].UDPWM.instance)&&(WiiMapping[g_ID].UDPWM.enableIR))
568 WiiMapping[g_ID].UDPWM.instance->getIR(MouseX,MouseY);
569 else
570 GetMousePos(MouseX, MouseY);
572 // If we are outside the screen leave the values at 0xff
573 if(MouseX > 1 || MouseX < 0 || MouseY > 1 || MouseY < 0) return;
575 // Position calculation
576 int y0 = g_Config.iIRTop + g_Config.iIRHeight * MouseY;
577 int y1 = y0;
579 // The distance between the x positions are two sensor bar radii
580 int x0 = 1023 - g_Config.iIRLeft - g_Config.iIRWidth * MouseX - SENSOR_BAR_WIDTH / 2;
581 int x1 = x0 + SENSOR_BAR_WIDTH;
583 RotateIRDot(x0, y0, WiiMapping[g_ID].Motion.TiltWM);
584 RotateIRDot(x1, y1, WiiMapping[g_ID].Motion.TiltWM);
586 // Converted to IR data
587 _ir0.x = x0 & 0xff; _ir0.xHi = x0 >> 8;
588 _ir0.y = y0 & 0xff; _ir0.yHi = y0 >> 8;
590 _ir1.x = x1 & 0xff; _ir1.xHi = x1 >> 8;
591 _ir1.y = y1 & 0xff; _ir1.yHi = y1 >> 8;
593 // The size can be between 0 and 15 and is probably not important
594 _ir0.size = 10;
595 _ir1.size = 10;
597 // Debugging for calibration
599 if(!GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_RIGHT))
600 Right +=1;
601 else if(GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_RIGHT))
602 Right -=1;
603 if(!GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_LEFT))
604 Left +=1;
605 else if(GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_LEFT))
606 Left -=1;
607 if(!GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_UP))
608 Top += 1;
609 else if(GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_UP))
610 Top -= 1;
611 if(!GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_DOWN))
612 Bottom += 1;
613 else if(GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_DOWN))
614 Bottom -= 1;
615 if(!GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_NUMPAD0))
616 SensorBarRadius += 1;
617 else if(GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_NUMPAD0))
618 SensorBarRadius -= 1;
620 //Console::ClearScreen();
621 //if(consoleDisplay == 1)
622 DEBUG_LOG(WIIMOTE, "x0:%03i x1:%03i y0:%03i y1:%03i | T:%i L:%i R:%i B:%i S:%i",
623 x0, x1, y0, y1, Top, Left, Right, Bottom, SensorBarRadius
624 );*/
627 // The 10 byte reporting used when an extension is connected
628 void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
630 // Recorded movements
631 // Check for a playback command
632 if(g_RecordingPlaying[2] < 0)
634 g_RecordingPlaying[2] = RecordingCheckKeys(2);
636 // We are playing back a recording, we don't accept any manual input this time
637 else
639 //DEBUG_LOG(WIIMOTE, "X, Y, Z: %u %u %u", _acc.x, _acc.y, _acc.z);
640 if (RecordingPlayIR(_ir0)) return;
643 // Fill with 0xff if empty
644 memset(&_ir0, 0xff, sizeof(wm_ir_basic));
645 memset(&_ir1, 0xff, sizeof(wm_ir_basic));
647 float MouseX, MouseY;
648 if ((WiiMapping[g_ID].UDPWM.instance)&&(WiiMapping[g_ID].UDPWM.enableIR))
649 WiiMapping[g_ID].UDPWM.instance->getIR(MouseX,MouseY);
650 else
651 GetMousePos(MouseX, MouseY);
653 // If we are outside the screen leave the values at 0xff
654 if(MouseX > 1 || MouseX < 0 || MouseY > 1 || MouseY < 0) return;
656 int y1 = g_Config.iIRTop + g_Config.iIRHeight * MouseY;
657 int y2 = y1;
659 int x1 = 1023 - g_Config.iIRLeft - g_Config.iIRWidth * MouseX - SENSOR_BAR_WIDTH / 2;
660 int x2 = x1 + SENSOR_BAR_WIDTH;
662 RotateIRDot(x1, y1, WiiMapping[g_ID].Motion.TiltWM);
663 RotateIRDot(x2, y2, WiiMapping[g_ID].Motion.TiltWM);
665 /* As with the extented report we settle with emulating two out of four
666 possible objects the only difference is that we don't report any size of
667 the tracked object here */
669 _ir0.x1 = x1 & 0xff; _ir0.x1Hi = (x1 >> 8); // we are dealing with 2 bit values here
670 _ir0.y1 = y1 & 0xff; _ir0.y1Hi = (y1 >> 8);
672 _ir0.x2 = x2 & 0xff; _ir0.x2Hi = (x2 >> 8);
673 _ir0.y2 = y2 & 0xff; _ir0.y2Hi = (y2 >> 8);
675 // Debugging for calibration
677 if(GetAsyncKeyState(VK_NUMPAD1))
678 Right +=1;
679 else if(GetAsyncKeyState(VK_NUMPAD2))
680 Right -=1;
681 if(GetAsyncKeyState(VK_NUMPAD4))
682 Left +=1;
683 else if(GetAsyncKeyState(VK_NUMPAD5))
684 Left -=1;
685 if(GetAsyncKeyState(VK_NUMPAD7))
686 Top += 1;
687 else if(GetAsyncKeyState(VK_NUMPAD8))
688 Top -= 1;
689 if(GetAsyncKeyState(VK_NUMPAD6))
690 Bottom += 1;
691 else if(GetAsyncKeyState(VK_NUMPAD3))
692 Bottom -= 1;
693 if(GetAsyncKeyState(VK_INSERT))
694 SensorBarRadius += 1;
695 else if(GetAsyncKeyState(VK_DELETE))
696 SensorBarRadius -= 1;
698 //ClearScreen();
699 //if(consoleDisplay == 1)
701 DEBUG_LOG(WIIMOTE, "x1:%03i x2:%03i y1:%03i y2:%03i irx1:%02x y1:%02x x2:%02x y2:%02x | T:%i L:%i R:%i B:%i S:%i",
702 x1, x2, y1, y2, _ir0.x1, _ir0.y1, _ir1.x2, _ir1.y2, Top, Left, Right, Bottom, SensorBarRadius
704 DEBUG_LOG(WIIMOTE, "");
705 DEBUG_LOG(WIIMOTE, "ir0.x1:%02x x1h:%02x x2:%02x x2h:%02x | ir0.y1:%02x y1h:%02x y2:%02x y2h:%02x | ir1.x1:%02x x1h:%02x x2:%02x x2h:%02x | ir1.y1:%02x y1h:%02x y2:%02x y2h:%02x",
706 _ir0.x1, _ir0.x1Hi, _ir0.x2, _ir0.x2Hi,
707 _ir0.y1, _ir0.y1Hi, _ir0.y2, _ir0.y2Hi,
708 _ir1.x1, _ir1.x1Hi, _ir1.x2, _ir1.x2Hi,
709 _ir1.y1, _ir1.y1Hi, _ir1.y2, _ir1.y2Hi
710 );*/
711 // ------------------
715 /* Generate the 6 byte extension report for the Nunchuck, encrypted. The bytes
716 are JX JY AX AY AZ BT. */
717 void FillReportExtension(wm_extension& _ext)
719 // Recorded movements
720 // Check for a playback command
721 if(g_RecordingPlaying[1] < 0)
723 g_RecordingPlaying[1] = RecordingCheckKeys(1);
725 else
727 // We should not play back the accelerometer values
728 if (RecordingPlay(_ext.ax, _ext.ay, _ext.az, 1))
729 return;
732 // The default joystick and button values unless we use them
733 _ext.jx = g_nu.jx.center;
734 _ext.jy = g_nu.jy.center;
735 _ext.bt = 0x03; // 0x03 means no button pressed, the button is zero active
737 // Use the neutral values
738 _ext.ax = g_nu.cal_zero.x;
739 _ext.ay = g_nu.cal_zero.y;
740 _ext.az = g_nu.cal_zero.z + g_nu.cal_g.z;
742 if (IsFocus())
744 int acc_x = _ext.ax;
745 int acc_y = _ext.ay;
746 int acc_z = _ext.az;
748 if (IsKey(ENC_SHAKE) && !WiiMapping[g_ID].Motion.TiltNC.Shake)
749 WiiMapping[g_ID].Motion.TiltNC.Shake = 1;
751 // Step the shake simulation one step
752 ShakeToAccelerometer(acc_x, acc_y, acc_z, WiiMapping[g_ID].Motion.TiltNC);
754 // Tilt Nunchuck, allow the shake function to interrupt it
755 if (!WiiMapping[g_ID].Motion.TiltNC.Shake)
756 TiltNunchuck(acc_x, acc_y, acc_z);
758 // Boundary check
759 if (acc_x > 0xFF) acc_x = 0xFF;
760 else if (acc_x < 0x00) acc_x = 0x00;
761 if (acc_y > 0xFF) acc_y = 0xFF;
762 else if (acc_y < 0x00) acc_y = 0x00;
763 if (acc_z > 0xFF) acc_z = 0xFF;
764 else if (acc_z < 0x00) acc_z = 0x00;
766 _ext.ax = acc_x;
767 _ext.ay = acc_y;
768 _ext.az = acc_z;
770 if ((WiiMapping[g_ID].UDPWM.instance)&&(WiiMapping[g_ID].UDPWM.enableNunchuck))
772 float x,y;
773 u8 b;
774 WiiMapping[g_ID].UDPWM.instance->getNunchuck(x,y,b);
775 //NOTICE_LOG(WIIMOTE,"%f %f %x",x,y,b);
777 int factNeg= + g_nu.jx.center - g_nu.jx.min;
778 int factPoz= - g_nu.jx.center + g_nu.jx.max;
779 if (x==0) _ext.jx=g_nu.jx.center;
780 if (x>0) _ext.jx=(int)(x*factPoz+g_nu.jx.center);
781 if (x<0) _ext.jx=(int)(x*factNeg+g_nu.jx.center);
783 factNeg= + g_nu.jy.center - g_nu.jy.min;
784 factPoz= - g_nu.jy.center + g_nu.jy.max;
785 if (y==0) _ext.jy=g_nu.jy.center;
786 if (y>0) _ext.jy=(int)(y*factPoz+g_nu.jy.center);
787 if (y<0) _ext.jy=(int)(y*factNeg+g_nu.jy.center);
788 //buttons
789 if(IsKey(ENC_C)||(b&UDPWM_NC)) _ext.bt &= ~0x02;
790 if(IsKey(ENC_Z)||(b&UDPWM_NZ)) _ext.bt &= ~0x01;
791 } else
793 // Update the analog stick
794 if (WiiMapping[g_ID].Stick.NC == FROM_KEYBOARD)
796 // Set the max values to the current calibration values
797 if(IsKey(ENC_L)) // x
798 _ext.jx = g_nu.jx.min;
799 if(IsKey(ENC_R))
800 _ext.jx = g_nu.jx.max;
802 if(IsKey(ENC_D)) // y
803 _ext.jy = g_nu.jy.min;
804 if(IsKey(ENC_U))
805 _ext.jy = g_nu.jy.max;
807 // On a real stick, the initialization value of center is 0x80,
808 // but after a first time touch, the center value automatically changes to 0x7F
809 if(_ext.jx != g_nu.jx.center)
810 g_nu.jx.center = 0x7F;
811 if(_ext.jy != g_nu.jy.center)
812 g_nu.jy.center = 0x7F;
814 else
816 // Get adjusted pad state values
817 int _Lx = WiiMapping[g_ID].AxisState.Lx;
818 int _Ly = WiiMapping[g_ID].AxisState.Ly;
819 int _Rx = WiiMapping[g_ID].AxisState.Rx;
820 int _Ry = WiiMapping[g_ID].AxisState.Ry;
822 // The Y-axis is inverted
823 _Ly = 0xff - _Ly;
824 _Ry = 0xff - _Ry;
826 /* This is if we are also using a real Nunchuck that we are sharing the
827 calibration with. It's not needed if we are using our default
828 values. We adjust the values to the configured range, we even allow
829 the center to not be 0x80. */
830 if(g_nu.jx.max != 0xff || g_nu.jy.max != 0xff
831 || g_nu.jx.min != 0 || g_nu.jy.min != 0
832 || g_nu.jx.center != 0x80 || g_nu.jy.center != 0x80)
834 float Lx = (float)_Lx;
835 float Ly = (float)_Ly;
836 float Rx = (float)_Rx;
837 float Ry = (float)_Ry;
838 //float Tl = (float)_Tl;
839 //float Tr = (float)_Tr;
841 float XRangePos = (float) (g_nu.jx.max - g_nu.jx.center);
842 float XRangeNeg = (float) (g_nu.jx.center - g_nu.jx.min);
843 float YRangePos = (float) (g_nu.jy.max - g_nu.jy.center);
844 float YRangeNeg = (float) (g_nu.jy.center - g_nu.jy.min);
845 if (Lx > 0x80) Lx = Lx * (XRangePos / 128.0);
846 if (Lx < 0x80) Lx = Lx * (XRangeNeg / 128.0);
847 if (Lx == 0x80) Lx = (float)g_nu.jx.center;
848 if (Ly > 0x80) Ly = Ly * (YRangePos / 128.0);
849 if (Ly < 0x80) Ly = Ly * (YRangeNeg / 128.0);
850 if (Ly == 0x80) Lx = (float)g_nu.jy.center;
851 // Boundaries
852 _Lx = (int)Lx;
853 _Ly = (int)Ly;
854 _Rx = (int)Rx;
855 _Ry = (int)Ry;
856 if (_Lx > 0xff) _Lx = 0xff; if (_Lx < 0) _Lx = 0;
857 if (_Rx > 0xff) _Rx = 0xff; if (_Rx < 0) _Rx = 0;
858 if (_Ly > 0xff) _Ly = 0xff; if (_Ly < 0) _Ly = 0;
859 if (_Ry > 0xff) _Ry = 0xff; if (_Ry < 0) _Ry = 0;
862 if (WiiMapping[g_ID].Stick.NC == FROM_ANALOG1)
864 _ext.jx = _Lx;
865 _ext.jy = _Ly;
867 else // ANALOG2
869 _ext.jx = _Rx;
870 _ext.jy = _Ry;
874 if(IsKey(ENC_C)) _ext.bt &= ~0x02;
875 if(IsKey(ENC_Z)) _ext.bt &= ~0x01;
879 /* Here we encrypt the report */
881 // Create a temporary storage for the data
882 u8 Tmp[sizeof(_ext)];
883 // Clear the array by copying zeroes to it
884 memset(Tmp, 0, sizeof(_ext));
885 // Copy the data to it
886 memcpy(Tmp, &_ext, sizeof(_ext));
887 // Encrypt it
888 wiimote_encrypt(&g_ExtKey[g_ID], Tmp, 0x00, sizeof(_ext));
889 // Write it back to the struct
890 memcpy(&_ext, Tmp, sizeof(_ext));
894 /* Generate the 6 byte extension report for the Classic Controller, encrypted.
895 The bytes are ... */
896 void FillReportClassicExtension(wm_classic_extension& _ext)
898 /* These are the default neutral values for the analog triggers and sticks */
899 u8 Rx = g_ClassicContCalibration.Rx.center, Ry = g_ClassicContCalibration.Ry.center,
900 Lx = g_ClassicContCalibration.Lx.center, Ly = g_ClassicContCalibration.Ly.center,
901 lT = g_ClassicContCalibration.Tl.neutral, rT = g_ClassicContCalibration.Tl.neutral;
903 _ext.b1.padding = 0x01; // 0x01 means not pressed
904 _ext.b1.bRT = 0x01;
905 _ext.b1.bP = 0x01;
906 _ext.b1.bH = 0x01;
907 _ext.b1.bM = 0x01;
908 _ext.b1.bLT = 0x01;
909 _ext.b1.bdD = 0x01;
910 _ext.b1.bdR = 0x01;
912 _ext.b2.bdU = 0x01;
913 _ext.b2.bdL = 0x01;
914 _ext.b2.bZR = 0x01;
915 _ext.b2.bX = 0x01;
916 _ext.b2.bA = 0x01;
917 _ext.b2.bY = 0x01;
918 _ext.b2.bB = 0x01;
919 _ext.b2.bZL = 0x01;
921 // Check that Dolphin is in focus
922 if (IsFocus())
924 /* Left and right analog sticks and analog triggers
926 u8 Lx : 6; // byte 0
927 u8 Rx : 2;
928 u8 Ly : 6; // byte 1
929 u8 Rx2 : 2;
930 u8 Ry : 5; // byte 2
931 u8 lT : 2;
932 u8 Rx3 : 1;
933 u8 rT : 5; // byte 3
934 u8 lT2 : 3;
936 We use a 200 range (28 to 228) for the left analog stick and a 176 range
937 (40 to 216) for the right analog stick to match our calibration values
938 in classic_calibration
941 // Update the left analog stick
942 if (WiiMapping[g_ID].Stick.CCL == FROM_KEYBOARD)
944 if(IsKey(ECC_Ll)) // Left analog left
945 Lx = g_ClassicContCalibration.Lx.min;
946 if(IsKey(ECC_Lr)) // right
947 Lx = g_ClassicContCalibration.Lx.max;
948 if(IsKey(ECC_Lu)) // up
949 Ly = g_ClassicContCalibration.Ly.max;
950 if(IsKey(ECC_Ld)) // down
951 Ly = g_ClassicContCalibration.Ly.min;
953 // On a real stick, the initialization value of center is 0x80,
954 // but after a first time touch, the center value automatically changes to 0x7F
955 if(Lx != g_ClassicContCalibration.Lx.center)
956 g_ClassicContCalibration.Lx.center = 0x7F;
957 if(Ly != g_ClassicContCalibration.Ly.center)
958 g_ClassicContCalibration.Ly.center = 0x7F;
960 else
962 // Get adjusted pad state values
963 int _Lx = WiiMapping[g_ID].AxisState.Lx;
964 int _Ly = WiiMapping[g_ID].AxisState.Ly;
965 int _Rx = WiiMapping[g_ID].AxisState.Rx;
966 int _Ry = WiiMapping[g_ID].AxisState.Ry;
968 // The Y-axis is inverted
969 _Ly = 0xff - _Ly;
970 _Ry = 0xff - _Ry;
972 /* This is if we are also using a real Classic Controller that we
973 are sharing the calibration with. It's not needed if we are
974 using our default values. We adjust the values to the configured
975 range.
977 Status: Not added, we are not currently sharing the calibration
978 with the real Classic Controller
981 if (WiiMapping[g_ID].Stick.CCL == FROM_ANALOG1)
983 Lx = _Lx;
984 Ly = _Ly;
986 else // ANALOG2
988 Lx = _Rx;
989 Ly = _Ry;
993 // Update the right analog stick
994 if (WiiMapping[g_ID].Stick.CCR == FROM_KEYBOARD)
996 if(IsKey(ECC_Rl)) // Right analog left
997 Rx = g_ClassicContCalibration.Rx.min;
998 if(IsKey(ECC_Rr)) // right
999 Rx = g_ClassicContCalibration.Rx.max;
1000 if(IsKey(ECC_Ru)) // up
1001 Ry = g_ClassicContCalibration.Ry.max;
1002 if(IsKey(ECC_Rd)) // down
1003 Ry = g_ClassicContCalibration.Ry.min;
1005 // On a real stick, the initialization value of center is 0x80,
1006 // but after a first time touch, the center value automatically changes to 0x7F
1007 if(Rx != g_ClassicContCalibration.Rx.center)
1008 g_ClassicContCalibration.Rx.center = 0x7F;
1009 if(Ry != g_ClassicContCalibration.Ry.center)
1010 g_ClassicContCalibration.Ry.center = 0x7F;
1012 else
1014 // Get adjusted pad state values
1015 int _Lx = WiiMapping[g_ID].AxisState.Lx;
1016 int _Ly = WiiMapping[g_ID].AxisState.Ly;
1017 int _Rx = WiiMapping[g_ID].AxisState.Rx;
1018 int _Ry = WiiMapping[g_ID].AxisState.Ry;
1020 // The Y-axis is inverted
1021 _Ly = 0xff - _Ly;
1022 _Ry = 0xff - _Ry;
1024 /* This is if we are also using a real Classic Controller that we
1025 are sharing the calibration with. It's not needed if we are
1026 using our default values. We adjust the values to the configured
1027 range.
1029 Status: Not added, we are not currently sharing the calibration
1030 with the real Classic Controller
1033 if (WiiMapping[g_ID].Stick.CCR == FROM_ANALOG1)
1035 Rx = _Lx;
1036 Ry = _Ly;
1038 else // ANALOG2
1040 Rx = _Rx;
1041 Ry = _Ry;
1045 // Update the left and right analog triggers
1046 if (WiiMapping[g_ID].Stick.CCT == FROM_KEYBOARD)
1048 if(IsKey(ECC_Tl)) // analog left trigger
1049 { _ext.b1.bLT = 0x00; lT = 0x1f; }
1050 if(IsKey(ECC_Tr)) // analog right trigger
1051 { _ext.b1.bRT = 0x00; rT = 0x1f; }
1053 else // g_Config.ClassicController.TRIGGER
1055 // Get adjusted pad state values
1056 int _Tl = WiiMapping[g_ID].AxisState.Tl;
1057 int _Tr = WiiMapping[g_ID].AxisState.Tr;
1059 /* This is if we are also using a real Classic Controller that we
1060 are sharing the calibration with. It's not needed if we are
1061 using our default values. We adjust the values to the configured
1062 range.
1064 Status: Not added, we are not currently sharing the calibration
1065 with the real Classic Controller
1068 // Check if the trigger is fully pressed, then update the digital
1069 // trigger values to
1070 if (_Tl == 0xff) _ext.b1.bLT = 0x00;
1071 if (_Tr == 0xff) _ext.b1.bRT = 0x00;
1073 // These can be copied directly, the bitshift further down fix this
1074 // value to
1075 lT = _Tl;
1076 rT = _Tr;
1079 /* D-Pad
1081 u8 b1;
1083 6: bdD
1084 7: bdR
1086 u8 b2;
1087 0: bdU
1088 1: bdL
1090 if(IsKey(ECC_Dl)) _ext.b2.bdL = 0x00; // Digital left
1091 if(IsKey(ECC_Du)) _ext.b2.bdU = 0x00; // Up
1092 if(IsKey(ECC_Dr)) _ext.b1.bdR = 0x00; // Right
1093 if(IsKey(ECC_Dd)) _ext.b1.bdD = 0x00; // Down
1095 /* Buttons
1096 u8 b1;
1098 6: -
1099 7: -
1101 u8 b2;
1102 0: -
1103 1: -
1104 2: bZr
1105 3: bX
1106 4: bA
1107 5: bY
1108 6: bB
1109 7: bZl
1111 if(IsKey(ECC_A)) _ext.b2.bA = 0x00;
1112 if(IsKey(ECC_B)) _ext.b2.bB = 0x00;
1113 if(IsKey(ECC_Y)) _ext.b2.bY = 0x00;
1114 if(IsKey(ECC_X)) _ext.b2.bX = 0x00;
1115 if(IsKey(ECC_P)) _ext.b1.bP = 0x00;
1116 if(IsKey(ECC_M)) _ext.b1.bM = 0x00;
1117 if(IsKey(ECC_H)) _ext.b1.bH = 0x00;
1118 if(IsKey(ECC_Zl)) _ext.b2.bZL = 0x00;
1119 if(IsKey(ECC_Zr)) _ext.b2.bZR = 0x00;
1121 // All buttons pressed
1122 //if(GetAsyncKeyState('C') && GetAsyncKeyState('Z'))
1123 // { _ext.b2.bA = 0x01; _ext.b2.bB = 0x01; }
1126 // Convert data for reporting
1127 _ext.Lx = (Lx >> 2);
1128 _ext.Ly = (Ly >> 2);
1129 // 5 bit to 1 bit
1130 _ext.Rx = (Rx >> 3) & 0x01;
1131 // 5 bit to the next 2 bit
1132 _ext.Rx2 = ((Rx >> 3) >> 1) & 0x03;
1133 // 5 bit to the next 2 bit
1134 _ext.Rx3 = ((Rx >> 3) >> 3) & 0x03;
1135 _ext.Ry = (Ry >> 3);
1136 // 5 bit to 3 bit
1137 _ext.lT = (lT >> 3) & 0x07;
1138 // 5 bit to the highest two bits
1139 _ext.lT2 = (lT >> 3) >> 3;
1140 _ext.rT = (rT >> 3);
1142 /* Here we encrypt the report */
1143 // Create a temporary storage for the data
1144 u8 Tmp[sizeof(_ext)];
1145 // Clear the array by copying zeroes to it
1146 memset(Tmp, 0, sizeof(_ext));
1147 // Copy the data to it
1148 memcpy(Tmp, &_ext, sizeof(_ext));
1149 // Encrypt it
1150 wiimote_encrypt(&g_ExtKey[g_ID], Tmp, 0x00, sizeof(_ext));
1151 // Write it back to the struct
1152 memcpy(&_ext, Tmp, sizeof(_ext));
1155 /* Generate the 6 byte extension report for the GH3 Controller, encrypted.
1156 The bytes are ... */
1157 void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
1159 // u8 TB : 5; // not used in GH3
1160 // u8 WB : 5;
1161 u8 SX = g_GH3Calibration.Lx.center, SY = g_GH3Calibration.Ly.center;
1163 _ext.pad1 = 3;
1164 _ext.pad2 = 3;
1165 _ext.pad3 = 0;
1166 _ext.pad4 = 0;
1167 _ext.pad5 = 3;
1168 _ext.pad6 = 1;
1169 _ext.pad7 = 1;
1170 _ext.pad8 = 1;
1171 _ext.pad9 = 3;
1173 _ext.Plus = 1;
1174 _ext.Minus = 1;
1175 _ext.StrumDown = 1;
1176 _ext.StrumUp = 1;
1177 _ext.Yellow = 1;
1178 _ext.Green = 1;
1179 _ext.Blue = 1;
1180 _ext.Red = 1;
1181 _ext.Orange = 1;
1183 // Check that Dolphin is in focus
1184 if (IsFocus())
1186 // Update the left analog stick
1187 if (WiiMapping[g_ID].Stick.GH == FROM_KEYBOARD)
1189 if(IsKey(EGH_Al)) // Left analog left
1190 _ext.SX = g_GH3Calibration.Lx.min;
1191 if(IsKey(EGH_Ar)) // right
1192 _ext.SX = g_GH3Calibration.Lx.max;
1193 if(IsKey(EGH_Au)) // up
1194 _ext.SY = g_GH3Calibration.Ly.max;
1195 if(IsKey(EGH_Ad)) // down
1196 _ext.SY = g_GH3Calibration.Ly.min;
1198 else
1200 // Get adjusted pad state values
1201 int _Lx = WiiMapping[g_ID].AxisState.Lx;
1202 int _Ly = WiiMapping[g_ID].AxisState.Ly;
1203 int _Rx = WiiMapping[g_ID].AxisState.Rx;
1204 int _Ry = WiiMapping[g_ID].AxisState.Ry;
1206 // The Y-axis is inverted
1207 _Ly = 0xff - _Ly;
1208 _Ry = 0xff - _Ry;
1210 if (WiiMapping[g_ID].Stick.GH == FROM_ANALOG1)
1212 SX = _Lx;
1213 SY = _Ly;
1215 else // ANALOG2
1217 SX = _Rx;
1218 SX = _Ry;
1222 if(IsKey(EGH_Yellow)) _ext.Yellow = 0;
1223 if(IsKey(EGH_Green)) _ext.Green = 0;
1224 if(IsKey(EGH_Blue)) _ext.Blue = 0;
1225 if(IsKey(EGH_Red)) _ext.Red = 0;
1226 if(IsKey(EGH_Orange)) _ext.Orange = 0;
1227 if(IsKey(EGH_Plus)) _ext.Plus = 0;
1228 if(IsKey(EGH_Minus)) _ext.Minus = 0;
1229 if(IsKey(EGH_StrumUp)) _ext.StrumUp = 0; // Strum Up
1230 if(IsKey(EGH_StrumDown)) _ext.StrumDown= 0; // Strum Down
1233 // Convert data for reporting
1234 _ext.SX = (SX >> 2);
1235 _ext.SY = (SY >> 2);
1237 /* Here we encrypt the report */
1238 // Create a temporary storage for the data
1239 u8 Tmp[sizeof(_ext)];
1240 // Clear the array by copying zeroes to it
1241 memset(Tmp, 0, sizeof(_ext));
1242 // Copy the data to it
1243 memcpy(Tmp, &_ext, sizeof(_ext));
1244 // Encrypt it
1245 wiimote_encrypt(&g_ExtKey[g_ID], Tmp, 0x00, sizeof(_ext));
1246 // Write it back to the struct
1247 memcpy(&_ext, Tmp, sizeof(_ext));
1250 } // end of namespace