wii_ec_classic.c 14 KB

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