wii_anal_keys.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. #include <stdbool.h>
  2. #include "bc_logging.h"
  3. #include "wii_anal.h"
  4. //+============================================================================ ========================================
  5. // Stop Calibration mode
  6. //
  7. static
  8. void calStop (state_t* const state)
  9. {
  10. state->hold = 0; // stop calibration mode
  11. state->calib &= ~(CAL_RANGE | CAL_NOTJOY); // ...
  12. }
  13. //+============================================================================ ========================================
  14. // Change to another scene
  15. //
  16. void sceneSet (state_t* const state, const scene_t scene)
  17. {
  18. calStop(state); // Stop software calibration
  19. state->scenePrev = state->scene; // Remember where we came from
  20. state->scene = scene; // Go to new scene
  21. INFO("Scene : %d -> %d", state->scenePrev, state->scene);
  22. }
  23. //+============================================================================ ========================================
  24. // Change to an easter egg scene
  25. //
  26. static
  27. void sceneSetEgg (state_t* const state, const scene_t scene)
  28. {
  29. calStop(state); // Stop software calibration
  30. state->scenePegg = state->scene; // Remember where we came from
  31. state->scene = scene; // Go to new scene
  32. INFO("Scene* : %d => %d", state->scenePegg, state->scene);
  33. }
  34. //+============================================================================ ========================================
  35. // Several EC screens have 'peak-hold' and 'calibration' features
  36. // Enabling peak-hold on screen with no peak meters will have no effect
  37. // So, to avoid code duplication...
  38. //
  39. bool key_calib (const eventMsg_t* const msg, state_t* const state)
  40. {
  41. int used = false; // assume key is NOT-handled
  42. switch (msg->input.type) {
  43. case InputTypeShort: //# <! After InputTypeRelease within INPUT_LONG_PRESS interval
  44. switch (msg->input.key) {
  45. case InputKeyUp: //# <U [ SHORT-UP ]
  46. state->hold = (state->hold == +1) ? 0 : +1 ; // toggle peak hold
  47. used = true;
  48. break;
  49. case InputKeyDown: //# <D [ SHORT-DOWN ]
  50. state->hold = (state->hold == -1) ? 0 : -1 ; // toggle trough hold
  51. used = true;
  52. break;
  53. case InputKeyOk: //# <O [ SHORT-OK ]
  54. if (state->calib & CAL_RANGE) calStop(state) ; // STOP softare calibration
  55. else ecCalibrate(&state->ec, CAL_CENTRE) ; // perform centre calibration
  56. used = true;
  57. break;
  58. default: break ;
  59. }
  60. break;
  61. case InputTypeLong: //# >! After INPUT_LONG_PRESS interval, asynch to InputTypeRelease
  62. switch (msg->input.key) {
  63. case InputKeyOk: //# >O [ LONG-OK ]
  64. ecCalibrate(&state->ec, CAL_RESET | CAL_CENTRE); // START software calibration
  65. state->hold = 0;
  66. state->calib |= CAL_RANGE;
  67. state->flash = 8; // start with flash ON
  68. used = true;
  69. break;
  70. default: break ;
  71. }
  72. break;
  73. default: break ;
  74. }
  75. return used;
  76. }
  77. //+============================================================================ ========================================
  78. // WAIT screen
  79. //
  80. static inline
  81. bool wait_key (const eventMsg_t* const msg, state_t* const state)
  82. {
  83. int used = false; // assume key is NOT-handled
  84. if (msg->input.type == InputTypeShort) {
  85. switch (msg->input.key) {
  86. case InputKeyLeft: //# <L [ SHORT-LEFT ]
  87. sceneSet(state, SCENE_SPLASH);
  88. used = true;
  89. break;
  90. case InputKeyUp: //# <U [ SHORT-UP ]
  91. sceneSet(state, SCENE_RIP);
  92. used = true;
  93. break;
  94. case InputKeyBack: //# <B [ SHORT-BACK ]
  95. state->run = false;
  96. used = true;
  97. break;
  98. default: break ;
  99. }
  100. }
  101. return used;
  102. }
  103. //+============================================================================ ========================================
  104. // DEBUG screen
  105. //
  106. static inline
  107. bool debug_key (const eventMsg_t* const msg, state_t* const state)
  108. {
  109. int used = false; // assume key is NOT-handled
  110. switch (msg->input.type) {
  111. case InputTypeShort: //# <! After InputTypeRelease within INPUT_LONG_PRESS interval
  112. switch (msg->input.key) {
  113. case InputKeyUp: { //# <U [ SHORT-UP ]
  114. bool init = ecInit(&state->ec, NULL); // Initialise the controller //! NULL = no encryption
  115. (void)init; // in case INFO is optimised out
  116. INFO("%s : %s", __func__, (init ? "init OK" : "init fail"));
  117. used = true;
  118. break;
  119. }
  120. case InputKeyOk: //# <O [ SHORT-OK ]
  121. if (ecRead(&state->ec) == 0) { // Read the controller
  122. INFO( "%s : joy: {%02X,%02X,%02X,%02X,%02X,%02X}", __func__,
  123. state->ec.joy[0], state->ec.joy[1], state->ec.joy[2],
  124. state->ec.joy[3], state->ec.joy[4], state->ec.joy[5] );
  125. }
  126. used = true;
  127. break;
  128. case InputKeyDown: //# <D [ SHORT-DOWN ]
  129. timerEn(state, true); // restart the timer
  130. sceneSet(state, state->scenePrev);
  131. used = true;
  132. break;
  133. case InputKeyBack: //# <B [ SHORT-BACK ]
  134. state->run = false;
  135. used = true;
  136. break;
  137. default: break ; //# <?
  138. }
  139. break;
  140. default: break ;
  141. }
  142. return used;
  143. }
  144. //+============================================================================ ========================================
  145. // SPLASH and RIP screen
  146. //
  147. static inline
  148. bool splash_key (const eventMsg_t* const msg, state_t* const state)
  149. {
  150. // Back key on the initial SPLASH screen (this will catch the InputKeyPress)
  151. if ((msg->input.key == InputKeyBack) && (state->scenePrev == SCENE_NONE)) state->run = false ;
  152. // ANY-other-KEY press
  153. if (msg->input.type == InputTypeShort) {
  154. timerEn(state, true); // Restart the timer
  155. state->scene = state->scenePegg;
  156. }
  157. return true;
  158. }
  159. //+============================================================================ ========================================
  160. // "_pre" allows the plugin to use the key before the active scene gets a chance
  161. //
  162. static inline
  163. bool key_pre (const eventMsg_t* const msg, state_t* const state)
  164. {
  165. (void)msg;
  166. (void)state;
  167. return false;
  168. }
  169. //+============================================================================ ========================================
  170. // "_post" allows the plugin to use a key if it was not used by the active scene
  171. //
  172. static inline
  173. bool key_post (const eventMsg_t* const msg, state_t* const state)
  174. {
  175. int used = false; // assume key is NOT-handled
  176. if (msg->input.key == InputKeyBack) {
  177. if (msg->input.type == InputTypeShort) { //# <B [SHORT-BACK]
  178. state->ec.init = false; // reset/disconnect the controller
  179. sceneSet(state, SCENE_WAIT);
  180. used = true;
  181. } else if (msg->input.type == InputTypeLong) { //# >B [LONG-BACK]
  182. state->run = false; // Signal the plugin to exit
  183. used = true;
  184. }
  185. }
  186. // Easter eggs
  187. switch (state->scene) {
  188. case SCENE_SPLASH: // Scenes that do NOT offer Easter eggs
  189. case SCENE_RIP:
  190. case SCENE_DEBUG:
  191. break;
  192. default:
  193. if (msg->input.type == InputTypeLong) {
  194. switch (msg->input.key) {
  195. case InputKeyDown: //# >D [LONG-DOWN]
  196. timerEn(state, false); // Stop the timer
  197. sceneSetEgg(state, SCENE_DEBUG);
  198. used = true;
  199. break;
  200. case InputKeyLeft: //# >L [ LONG-LEFT ]
  201. timerEn(state, false); // Stop the timer
  202. sceneSetEgg(state, SCENE_SPLASH);
  203. used = true;
  204. break;
  205. case InputKeyUp: //# >U [ LONG-UP ]
  206. timerEn(state, false); // Stop the timer
  207. sceneSetEgg(state, SCENE_RIP);
  208. used = true;
  209. break;
  210. default: break ;
  211. }
  212. }
  213. break;
  214. }
  215. return used;
  216. }
  217. //+============================================================================ ========================================
  218. // Handle a key press event
  219. //
  220. bool evKey (const eventMsg_t* const msg, state_t* const state)
  221. {
  222. furi_assert(msg);
  223. furi_assert(state);
  224. bool used = key_pre(msg, state);
  225. if (!used) switch (state->scene) {
  226. case SCENE_SPLASH: //...
  227. case SCENE_RIP: used = splash_key(msg, state); break ;
  228. case SCENE_WAIT: used = wait_key(msg, state); break ;
  229. case SCENE_DEBUG: used = debug_key(msg, state); break ;
  230. default:
  231. if (state->ec.pidx >= PID_ERROR) {
  232. ERROR("%s : bad PID = %d", __func__, state->ec.pidx);
  233. } else {
  234. if ((state->scene == SCENE_DUMP) || !ecId[state->ec.pidx].keys)
  235. ecId[PID_UNKNOWN].keys(msg, state);
  236. else
  237. ecId[state->ec.pidx].keys(msg, state);
  238. }
  239. break;
  240. case SCENE_NONE: break;
  241. }
  242. if (!used) used = key_post(msg, state) ;
  243. return used;
  244. }