wii_ec_classic.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. #include <stdint.h>
  2. #include <furi.h> // Core API
  3. #include "wii_anal.h"
  4. #include "wii_ec.h"
  5. #include "bc_logging.h"
  6. //#include "gfx/images.h" // Images
  7. #include "wii_anal_lcd.h" // Drawing functions
  8. #include "wii_anal_keys.h" // key mappings
  9. // ** If you want to see what this source code looks like with all the MACROs expanded
  10. // ** grep -v '#include ' wii_i2c_classic.c | gcc -E -o /dev/stdout -xc -
  11. #include "wii_ec_macros.h"
  12. //----------------------------------------------------------------------------- ----------------------------------------
  13. // Classic Controller ... Classic Controller Pro is electronically the same
  14. //
  15. // ANA{l} ANA{r}
  16. // BTN{l} BTN{L} BTN{R} BTN{r}
  17. // ,--------. ,-, ,-, .--------,
  18. // .----------------------------------------------------------.
  19. // | |
  20. // | BTN{W} BTN{x} |
  21. // | BTN{A} BTN{D} BTN{-} BTN{h} BTN{+} BTN{y} BTN{a} |
  22. // | BTN{S} BTN{b} |
  23. // | |
  24. // | ANA{y} ANA{Y} |
  25. // | ANA{x} ANA{X} |
  26. // | |
  27. // `----------------------------------------------------------'
  28. //+============================================================================ ========================================
  29. // https://wiibrew.org/wiki/Wiimote/Extension_Controllers/Classic_Controller
  30. // I think a LOT of drugs went in to "designing" this layout
  31. // ...And yes, the left-joystick has an extra 'bit' of precision!
  32. // ...Also: trgZ{L|R} WILL continue to increase after btnZ{L|R} has gone active
  33. //
  34. void classic_decode(wiiEC_t* const pec) {
  35. ecDecClassic_t* p = &pec->dec[(pec->decN = !pec->decN)].classic;
  36. uint8_t* joy = pec->joy;
  37. p->trgZL = ((joy[2] >> 2) & 0x18) | ((joy[3] >> 5) & 0x07); // {5}
  38. p->btnZL = !(joy[4] & 0x20); // !{1}
  39. p->trgZR = joy[3] & 0x1F; // {5}
  40. p->btnZR = !(joy[4] & 0x02); // !{1}
  41. p->btnL = !(joy[5] & 0x80); // !{1}
  42. p->btnR = !(joy[5] & 0x04); // !{1}
  43. p->padU = !(joy[5] & 0x01); // !{1}
  44. p->padD = !(joy[4] & 0x40); // !{1}
  45. p->padL = !(joy[5] & 0x02); // !{1}
  46. p->padR = !(joy[4] & 0x80); // !{1}
  47. p->btnM = !(joy[4] & 0x10); // !{1}
  48. p->btnH = !(joy[4] & 0x08); // !{1}
  49. p->btnP = !(joy[4] & 0x04); // !{1}
  50. p->btnX = !(joy[5] & 0x08); // !{1}
  51. p->btnY = !(joy[5] & 0x20); // !{1}
  52. p->btnA = !(joy[5] & 0x10); // !{1}
  53. p->btnB = !(joy[5] & 0x40); // !{1}
  54. p->joyLX = joy[0] & 0x3F; // {6}
  55. p->joyLY = joy[1] & 0x3F; // {6}
  56. p->joyRX = ((joy[0] >> 3) & 0x18) | ((joy[1] >> 5) & 0x06) | ((joy[2] >> 7) & 0x01); // {5}
  57. p->joyRY = joy[2] & 0x1F; // {5}
  58. DEBUG(
  59. ">%d> ZL{%02X}%c, L:%c, R:%c, ZR{%02X}%c",
  60. pec->decN,
  61. p->trgZL,
  62. (p->btnZL ? '#' : '.'),
  63. (p->btnL ? '#' : '.'),
  64. (p->btnR ? '#' : '.'),
  65. p->trgZR,
  66. (p->btnZR ? '#' : '.'));
  67. DEBUG(
  68. ">%d> D:{%c,%c,%c,%c}, H:{%c,%c,%c}, B:{%c,%c,%c,%c}",
  69. pec->decN,
  70. (p->padU ? 'U' : '.'),
  71. (p->padD ? 'D' : '.'),
  72. (p->padL ? 'L' : '.'),
  73. (p->padR ? 'R' : '.'),
  74. (p->btnM ? '-' : '.'),
  75. (p->btnH ? 'H' : '.'),
  76. (p->btnP ? '+' : '.'),
  77. (p->btnX ? 'X' : '.'),
  78. (p->btnY ? 'Y' : '.'),
  79. (p->btnA ? 'A' : '.'),
  80. (p->btnB ? 'B' : '.'));
  81. DEBUG(
  82. ">%d> JoyL{x:%02X, y:%02X}, JoyR{x:%02X, y:%02X}",
  83. pec->decN,
  84. p->joyLX,
  85. p->joyLY,
  86. p->joyRX,
  87. p->joyRY);
  88. }
  89. //+============================================================================ ========================================
  90. // Give each button a unique character identifier
  91. //
  92. void classic_msg(wiiEC_t* const pec, FuriMessageQueue* const queue) {
  93. ecDecClassic_t* new = &pec->dec[pec->decN].classic;
  94. ecDecClassic_t* old = &pec->dec[!pec->decN].classic;
  95. eventMsg_t msg = {
  96. .id = EVID_WIIEC,
  97. .wiiEc = {
  98. .type = WIIEC_NONE,
  99. .in = ' ',
  100. .val = 0,
  101. }};
  102. ANALOG(trgZL, 'l'); // FIVE bit value
  103. ANABTN(btnZL, trgZL, 'l');
  104. BUTTON(btnL, 'L');
  105. BUTTON(btnR, 'R');
  106. ANALOG(trgZR, 'r'); // FIVE bit value
  107. ANABTN(btnZR, trgZR, 'r');
  108. BUTTON(padU, 'W');
  109. BUTTON(padL, 'A');
  110. BUTTON(padD, 'S');
  111. BUTTON(padR, 'D');
  112. BUTTON(btnM, '-');
  113. BUTTON(btnH, 'h');
  114. BUTTON(btnP, '+');
  115. BUTTON(btnX, 'x');
  116. BUTTON(btnY, 'y');
  117. BUTTON(btnA, 'a');
  118. BUTTON(btnB, 'b');
  119. ANALOG(joyLX, 'x'); // SIX bit values
  120. ANALOG(joyLY, 'y');
  121. ANALOG(joyRX, 'X'); // FIVE bit values
  122. ANALOG(joyRY, 'Y');
  123. }
  124. //+============================================================================ ========================================
  125. // https://web.archive.org/web/20090415045219/http://www.wiili.org/index.php/Wiimote/Extension_Controllers/Classic_Controller#Calibration_data
  126. //
  127. // Calibration data
  128. // 0..2 left analog stick X axis {maximum, minimum, center} ... JoyL is 6bits, so >>2 to compare to readings
  129. // 3..5 left analog stick Y axis {maximum, minimum, center} ... JoyL is 6bits, so >>2 to compare to readings
  130. // 6..8 right analog stick X axis {maximum, minimum, center} ... JoyR is 5bits, so >>3 to compare to readings
  131. // 9..11 right analog stick Y axis {maximum, minimum, center} ... JoyR is 5bits, so >>3 to compare to readings
  132. // 12..15 somehow describe the shoulder {5bit} button values!?
  133. //
  134. void classic_calib(wiiEC_t* const pec, ecCalib_t c) {
  135. ecDecClassic_t* src = &pec->dec[pec->decN].classic; // from input
  136. ecCalClassic_t* dst = pec->calS.classic; // to calibration data
  137. if(c & CAL_RESET) { // initialise ready for software calibration
  138. // LO is set to the MAXIMUM value (so it can be reduced)
  139. // HI is set to ZERO (so it can be increased)
  140. RESET_LO_HI(trgZL, 5); // 5bit value
  141. RESET_LO_HI(trgZR, 5); // 5bit value
  142. RESET_LO_MID_HI(joyLX, 6); // 6bit value
  143. RESET_LO_MID_HI(joyLY, 6); // 6bit value
  144. RESET_LO_MID_HI(joyRX, 5); // 5bit value
  145. RESET_LO_MID_HI(joyRY, 5); // 5bit value
  146. }
  147. if(c & CAL_FACTORY) { // (re)set to factory defaults
  148. //! strategy for factory calibration for classic controller [pro] triggers is (currently) unknown
  149. //! FACTORY_LO( trgZL, pec->calF[12..15]);
  150. //! FACTORY_MID(trgZL, pec->calF[12..15]);
  151. //! FACTORY_HI( trgZL, pec->calF[12..15]);
  152. //! FACTORY_LO( trgZR, pec->calF[12..15]);
  153. //! FACTORY_MID(trgZR, pec->calF[12..15]);
  154. //! FACTORY_HI( trgZR, pec->calF[12..15]);
  155. #if 1
  156. FACTORY_LO(trgZL, 0x03);
  157. FACTORY_LO(trgZR, 0x03);
  158. FACTORY_MID(trgZL, 0x1B); //! these will be set every time the digital switch changes to ON
  159. FACTORY_MID(trgZR, 0x1B);
  160. #endif
  161. FACTORY_LO(joyLX, pec->calF[1] >> 2);
  162. FACTORY_MID(joyLX, pec->calF[2] >> 2);
  163. FACTORY_HI(joyLX, pec->calF[0] >> 2);
  164. FACTORY_LO(joyLY, pec->calF[4] >> 2);
  165. FACTORY_MID(joyLY, pec->calF[5] >> 2);
  166. FACTORY_HI(joyLY, pec->calF[3] >> 2);
  167. FACTORY_LO(joyRX, pec->calF[7] >> 3);
  168. FACTORY_MID(joyRX, pec->calF[8] >> 3);
  169. FACTORY_HI(joyRX, pec->calF[6] >> 3);
  170. FACTORY_LO(joyRY, pec->calF[10] >> 3);
  171. FACTORY_MID(joyRY, pec->calF[11] >> 3);
  172. FACTORY_HI(joyRY, pec->calF[9] >> 3);
  173. }
  174. if(c & CAL_TRACK) { // track maximum and minimum values seen
  175. TRACK_LO_HI(trgZL);
  176. TRACK_LO_HI(trgZR);
  177. TRACK_LO_HI(joyLX);
  178. TRACK_LO_HI(joyLY);
  179. TRACK_LO_HI(joyRX);
  180. TRACK_LO_HI(joyRY);
  181. }
  182. if(c & CAL_RANGE) { // perform software calibration step
  183. RANGE_LO_HI(trgZL);
  184. RANGE_LO_HI(trgZR);
  185. RANGE_LO_HI(joyLX);
  186. RANGE_LO_HI(joyLY);
  187. RANGE_LO_HI(joyRX);
  188. RANGE_LO_HI(joyRY);
  189. }
  190. if(c & CAL_CENTRE) { // reset centre point of joystick
  191. CENTRE(joyLX);
  192. CENTRE(joyLY);
  193. CENTRE(joyRX);
  194. CENTRE(joyRY);
  195. }
  196. }
  197. //+============================================================================ ========================================
  198. // bits that are common to both screens
  199. //
  200. static void classic_show_(Canvas* const canvas, state_t* const state) {
  201. ecDecClassic_t* d = &state->ec.dec[state->ec.decN].classic;
  202. ecCalClassic_t* js = state->ec.calS.classic;
  203. static const int dead = 1; // trigger deadzone
  204. const image_t* img = NULL; // trigger image
  205. show(canvas, 6, 0, &img_cc_Main, SHOW_SET_BLK);
  206. show(canvas, 62, 53, &img_cc_Cable, SHOW_SET_BLK);
  207. // classic triggers
  208. if(d->trgZL >= js[2].trgZL)
  209. img = &img_cc_trg_L4;
  210. else if(d->trgZL <= js[1].trgZL + dead)
  211. img = NULL;
  212. else {
  213. // copied from the joystick calibration code
  214. int lo = js[1].trgZL + dead + 1;
  215. int hi = js[2].trgZL - 1;
  216. int range = hi - lo + 1;
  217. int div = range / 3; // each division (base amount, eg. 17/3==5)
  218. int rem = range - (div * 3); // remainder (ie. range%3)
  219. int hi1 = lo + div - 1; // (in brevity)
  220. int lo3 = lo + div + div + (rem == 2); // ...
  221. if(d->trgZL <= hi1)
  222. img = &img_cc_trg_L1; // zone #1
  223. else if(d->trgZL >= lo3)
  224. img = &img_cc_trg_L3; // zone #3
  225. else
  226. img = &img_cc_trg_L2; // zone #2
  227. }
  228. if(img) show(canvas, 22, 1, img, SHOW_SET_BLK);
  229. if(d->trgZR >= js[2].trgZR)
  230. img = &img_cc_trg_R4;
  231. else if(d->trgZR <= js[1].trgZR + dead)
  232. img = NULL;
  233. else {
  234. // copied from the joystick calibration code
  235. int lo = js[1].trgZR + dead + 1;
  236. int hi = js[2].trgZR - 1;
  237. int range = hi - lo + 1;
  238. int div = range / 3; // each division (base amount, eg. 17/3==5)
  239. int rem = range - (div * 3); // remainder (ie. range%3)
  240. int hi1 = lo + div - 1; // (in brevity)
  241. int lo3 = lo + div + div + (rem == 2); // ...
  242. if(d->trgZR <= hi1)
  243. img = &img_cc_trg_R1; // zone #1
  244. else if(d->trgZR >= lo3)
  245. img = &img_cc_trg_R3; // zone #3
  246. else
  247. img = &img_cc_trg_R2; // zone #2
  248. }
  249. if(img) show(canvas, 89, 1, img, SHOW_SET_BLK);
  250. if(d->padU) show(canvas, 27, 16, &img_cc_pad_UD1, SHOW_ALL);
  251. if(d->padL) show(canvas, 20, 23, &img_cc_pad_LR1, SHOW_ALL);
  252. if(d->padD) show(canvas, 27, 28, &img_cc_pad_UD1, SHOW_ALL);
  253. if(d->padR) show(canvas, 32, 23, &img_cc_pad_LR1, SHOW_ALL);
  254. if(d->btnX) show(canvas, 96, 16, &img_cc_btn_X1, SHOW_ALL);
  255. if(d->btnY) show(canvas, 85, 23, &img_cc_btn_Y1, SHOW_ALL);
  256. if(d->btnA) show(canvas, 107, 23, &img_cc_btn_A1, SHOW_ALL);
  257. if(d->btnB) show(canvas, 96, 30, &img_cc_btn_B1, SHOW_ALL);
  258. canvas_set_color(canvas, ColorBlack);
  259. if(d->btnL) canvas_draw_box(canvas, 46, 2, 5, 4);
  260. if(d->btnR) canvas_draw_box(canvas, 77, 2, 5, 4);
  261. if(d->btnM) canvas_draw_box(canvas, 54, 24, 4, 4);
  262. if(d->btnH) canvas_draw_box(canvas, 62, 24, 4, 4);
  263. if(d->btnP) canvas_draw_box(canvas, 70, 24, 4, 4);
  264. // Show joysticks
  265. showJoy(
  266. canvas,
  267. 48,
  268. 42,
  269. js[1].joyLX,
  270. js[2].joyLX,
  271. js[3].joyLX,
  272. js[1].joyLY,
  273. js[2].joyLY,
  274. js[3].joyLY,
  275. d->joyLX,
  276. d->joyLY,
  277. 6);
  278. showJoy(
  279. canvas,
  280. 78,
  281. 42,
  282. js[1].joyRX,
  283. js[2].joyRX,
  284. js[3].joyRX,
  285. js[1].joyRY,
  286. js[2].joyRY,
  287. js[3].joyRY,
  288. d->joyRX,
  289. d->joyRY,
  290. 5);
  291. show(canvas, 0, 55, &img_key_L, SHOW_SET_BLK);
  292. }
  293. //+============================================================================ ========================================
  294. static void classic_showN(Canvas* const canvas, state_t* const state) {
  295. ecCalClassic_t* c = (state->hold) ?
  296. &state->ec.calS.classic[(state->hold < 0) ? 0 : 4] :
  297. (ecCalClassic_t*)(&state->ec.dec[state->ec.decN].classic); //! danger
  298. classic_show_(canvas, state);
  299. showHex(canvas, 0, 0, c->trgZL, 2, 1); // 5bits
  300. showHex(canvas, 113, 0, c->trgZR, 2, 1); // 5bits
  301. showHex(canvas, 24, 41, c->joyLX, 2, 1); // 6bits
  302. showHex(canvas, 41, 54, c->joyLY, 2, 1); // 6bits
  303. showHex(canvas, 88, 41, c->joyRX, 2, 1); // 5bits
  304. showHex(canvas, 71, 54, c->joyRY, 2, 1); // 5bits
  305. showPeakHold(state, canvas, state->hold); // peak keys
  306. }
  307. //+============================================================================ ========================================
  308. void classic_show(Canvas* const canvas, state_t* const state) {
  309. // Classic controllers have TWO scenes
  310. if(state->scene == SCENE_CLASSIC_N) return classic_showN(canvas, state);
  311. // Default scene
  312. classic_show_(canvas, state);
  313. show(canvas, 9, 55, &img_key_R, SHOW_SET_BLK);
  314. show(
  315. canvas,
  316. 119,
  317. 55,
  318. ((state->calib & CAL_RANGE) && (++state->flash & 8)) ? &img_key_OKi : &img_key_OK,
  319. SHOW_SET_BLK);
  320. }
  321. //+============================================================================ ========================================
  322. static bool classic_keyN(const eventMsg_t* const msg, state_t* const state) {
  323. int used = false; // assume key is NOT-handled
  324. if((msg->input.type == InputTypeShort) && (msg->input.key == InputKeyLeft)) {
  325. sceneSet(state, SCENE_CLASSIC);
  326. used = true;
  327. }
  328. // Calibration keys
  329. if(!used) used = key_calib(msg, state);
  330. return used;
  331. }
  332. //+============================================================================ ========================================
  333. bool classic_key(const eventMsg_t* const msg, state_t* const state) {
  334. // Classic controllers have TWO scenes
  335. if(state->scene == SCENE_CLASSIC_N) return classic_keyN(msg, state);
  336. // Default scene
  337. int used = false; // assume key is NOT-handled
  338. switch(msg->input.type) {
  339. case InputTypeShort: //# <! After InputTypeRelease within INPUT_LONG_PRESS interval
  340. switch(msg->input.key) {
  341. case InputKeyUp: //# <U [ SHORT-UP ]
  342. case InputKeyDown: //# <D [ SHORT-DOWN ]
  343. used = true; // Block peak/trough-hold
  344. break;
  345. case InputKeyLeft: //# <L [ SHORT-LEFT ]
  346. sceneSet(state, SCENE_DUMP);
  347. used = true;
  348. break;
  349. case InputKeyRight: //# <R [ SHORT-RIGHT ]
  350. sceneSet(state, SCENE_CLASSIC_N);
  351. used = true;
  352. break;
  353. default:
  354. break; //# <?
  355. }
  356. break;
  357. default:
  358. break;
  359. }
  360. // Calibration keys
  361. if(!used) used = key_calib(msg, state);
  362. return used;
  363. }