You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
4.6 KiB

  1. /* gc_n64_usb : Gamecube or N64 controller to USB adapter firmware
  2. Copyright (C) 2007-2016 Raphael Assenat <raph@raphnet.net>
  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, either version 3 of the License, or
  6. (at your option) any later version.
  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 for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <avr/io.h>
  15. #include <avr/interrupt.h>
  16. #include <util/delay.h>
  17. #include <string.h>
  18. #include "gamepads.h"
  19. #include "gamecube.h"
  20. #include "gcn64_protocol.h"
  21. /*********** prototypes *************/
  22. static void gamecubeInit(unsigned char chn);
  23. static char gamecubeUpdate(unsigned char chn);
  24. static char gamecubeChanged(unsigned char chn);
  25. static char gc_rumbling[GAMEPAD_MAX_CHANNELS] = { };
  26. static char origins_set[GAMEPAD_MAX_CHANNELS] = { };
  27. static unsigned char orig_x[GAMEPAD_MAX_CHANNELS];
  28. static unsigned char orig_y[GAMEPAD_MAX_CHANNELS];
  29. static unsigned char orig_cx[GAMEPAD_MAX_CHANNELS];
  30. static unsigned char orig_cy[GAMEPAD_MAX_CHANNELS];
  31. static void gamecubeInit(unsigned char chn)
  32. {
  33. gamecubeUpdate(chn);
  34. }
  35. void gc_decodeAnswer(unsigned char chn, unsigned char data[8])
  36. {
  37. unsigned char x,y,cx,cy;
  38. // Note: Checking seems a good idea, adds protection
  39. // against corruption (if the "constant" bits are invalid,
  40. // maybe others are : Drop the packet).
  41. //
  42. // However, I have seen bit 2 in a high state. To be as compatible
  43. // as possible, I decided NOT to look at these bits since instead
  44. // of being "constant" bits they might have a meaning I don't know.
  45. // Check the always 0 and always 1 bits
  46. #if 0
  47. if (gcn64_workbuf[0] || gcn64_workbuf[1] || gcn64_workbuf[2])
  48. return 1;
  49. if (!gcn64_workbuf[8])
  50. return 1;
  51. #endif
  52. /*
  53. (Source: Nintendo Gamecube Controller Protocol
  54. updated 8th March 2004, by James.)
  55. Bit Function
  56. 0-2 Always 0 << RAPH: Not true, I see 001!
  57. 3 Start
  58. 4 Y
  59. 5 X
  60. 6 B
  61. 7 A
  62. 8 Always 1
  63. 9 L
  64. 10 R
  65. 11 Z
  66. 12-15 Up,Down,Right,Left
  67. 16-23 Joy X
  68. 24-31 Joy Y
  69. 32-39 C Joystick X
  70. 40-47 C Joystick Y
  71. 48-55 Left Btn Val
  72. 56-63 Right Btn Val
  73. */
  74. last_built_report[chn].pad_type = PAD_TYPE_GAMECUBE;
  75. last_built_report[chn].gc.buttons = data[0] | data[1] << 8;
  76. x = data[2];
  77. y = data[3];
  78. cx = data[4];
  79. cy = data[5];
  80. last_built_report[chn].gc.lt = data[6];
  81. last_built_report[chn].gc.rt = data[7];
  82. memcpy(last_built_report[chn].gc.raw_data, data, 8);
  83. if (origins_set[chn]) {
  84. last_built_report[chn].gc.x = ((int)x-(int)orig_x[chn]);
  85. last_built_report[chn].gc.y = ((int)y-(int)orig_y[chn]);
  86. last_built_report[chn].gc.cx = ((int)cx-(int)orig_cx[chn]);
  87. last_built_report[chn].gc.cy = ((int)cy-(int)orig_cy[chn]);
  88. } else {
  89. orig_x[chn] = x;
  90. orig_y[chn] = y;
  91. orig_cx[chn] = cx;
  92. orig_cy[chn] = cy;
  93. last_built_report[chn].gc.x = 0;
  94. last_built_report[chn].gc.y = 0;
  95. last_built_report[chn].gc.cx = 0;
  96. last_built_report[chn].gc.cy = 0;
  97. origins_set[chn] = 1;
  98. }
  99. }
  100. static char gamecubeUpdate(unsigned char chn)
  101. {
  102. unsigned char tmpdata[GC_GETSTATUS_REPLY_LENGTH];
  103. unsigned char count;
  104. tmpdata[0] = GC_GETSTATUS1;
  105. tmpdata[1] = GC_GETSTATUS2;
  106. tmpdata[2] = GC_GETSTATUS3(gc_rumbling[chn]);
  107. count = gcn64_transaction(GCN64_CHANNEL_0, tmpdata, 3, tmpdata, GC_GETSTATUS_REPLY_LENGTH);
  108. if (count != GC_GETSTATUS_REPLY_LENGTH) {
  109. return 1;
  110. }
  111. gc_decodeAnswer(chn, tmpdata);
  112. return 0;
  113. }
  114. static void gamecubeHotplug(unsigned char chn)
  115. {
  116. // Make sure next read becomes the refence center values
  117. origins_set[chn] = 0;
  118. }
  119. static char gamecubeProbe(unsigned char chn)
  120. {
  121. origins_set[chn] = 0;
  122. if (gamecubeUpdate(chn)) {
  123. return 0;
  124. }
  125. return 1;
  126. }
  127. static char gamecubeChanged(unsigned char chn)
  128. {
  129. return memcmp(&last_built_report[chn], &last_sent_report[chn], sizeof(gamepad_data));
  130. }
  131. static void gamecubeGetReport(unsigned char chn, gamepad_data *dst)
  132. {
  133. if (dst)
  134. memcpy(dst, &last_built_report[chn], sizeof(gamepad_data));
  135. }
  136. static void gamecubeVibration(unsigned char chn, char enable)
  137. {
  138. gc_rumbling[chn] = enable;
  139. }
  140. Gamepad GamecubeGamepad = {
  141. .init = gamecubeInit,
  142. .update = gamecubeUpdate,
  143. .changed = gamecubeChanged,
  144. .getReport = gamecubeGetReport,
  145. .probe = gamecubeProbe,
  146. .setVibration = gamecubeVibration,
  147. .hotplug = gamecubeHotplug,
  148. };
  149. Gamepad *gamecubeGetGamepad(void)
  150. {
  151. return &GamecubeGamepad;
  152. }