| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- #include <stdbool.h>
- #include "bc_logging.h"
- #include "wii_anal.h"
- //+============================================================================ ========================================
- // Stop Calibration mode
- //
- static void calStop(state_t* const state) {
- state->hold = 0; // stop calibration mode
- state->calib &= ~(CAL_RANGE | CAL_NOTJOY); // ...
- }
- //+============================================================================ ========================================
- // Change to another scene
- //
- void sceneSet(state_t* const state, const scene_t scene) {
- calStop(state); // Stop software calibration
- state->scenePrev = state->scene; // Remember where we came from
- state->scene = scene; // Go to new scene
- INFO("Scene : %d -> %d", state->scenePrev, state->scene);
- }
- //+============================================================================ ========================================
- // Change to an easter egg scene
- //
- static void sceneSetEgg(state_t* const state, const scene_t scene) {
- calStop(state); // Stop software calibration
- state->scenePegg = state->scene; // Remember where we came from
- state->scene = scene; // Go to new scene
- INFO("Scene* : %d => %d", state->scenePegg, state->scene);
- }
- //+============================================================================ ========================================
- // Several EC screens have 'peak-hold' and 'calibration' features
- // Enabling peak-hold on screen with no peak meters will have no effect
- // So, to avoid code duplication...
- //
- bool key_calib(const eventMsg_t* const msg, state_t* const state) {
- int used = false; // assume key is NOT-handled
- switch(msg->input.type) {
- case InputTypeShort: //# <! After InputTypeRelease within INPUT_LONG_PRESS interval
- switch(msg->input.key) {
- case InputKeyUp: //# <U [ SHORT-UP ]
- state->hold = (state->hold == +1) ? 0 : +1; // toggle peak hold
- used = true;
- break;
- case InputKeyDown: //# <D [ SHORT-DOWN ]
- state->hold = (state->hold == -1) ? 0 : -1; // toggle trough hold
- used = true;
- break;
- case InputKeyOk: //# <O [ SHORT-OK ]
- if(state->calib & CAL_RANGE)
- calStop(state); // STOP softare calibration
- else
- ecCalibrate(&state->ec, CAL_CENTRE); // perform centre calibration
- used = true;
- break;
- default:
- break;
- }
- break;
- case InputTypeLong: //# >! After INPUT_LONG_PRESS interval, asynch to InputTypeRelease
- switch(msg->input.key) {
- case InputKeyOk: //# >O [ LONG-OK ]
- ecCalibrate(&state->ec, CAL_RESET | CAL_CENTRE); // START software calibration
- state->hold = 0;
- state->calib |= CAL_RANGE;
- state->flash = 8; // start with flash ON
- used = true;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- return used;
- }
- //+============================================================================ ========================================
- // WAIT screen
- //
- static inline bool wait_key(const eventMsg_t* const msg, state_t* const state) {
- int used = false; // assume key is NOT-handled
- if(msg->input.type == InputTypeShort) {
- switch(msg->input.key) {
- case InputKeyLeft: //# <L [ SHORT-LEFT ]
- timerEn(state, false); // Stop the timer
- sceneSetEgg(state, SCENE_SPLASH);
- used = true;
- break;
- case InputKeyUp: //# <U [ SHORT-UP ]
- timerEn(state, false); // Stop the timer
- sceneSetEgg(state, SCENE_RIP);
- used = true;
- break;
- case InputKeyBack: //# <B [ SHORT-BACK ]
- state->run = false;
- used = true;
- break;
- default:
- break;
- }
- }
- return used;
- }
- //+============================================================================ ========================================
- // DEBUG screen
- //
- static inline bool debug_key(const eventMsg_t* const msg, state_t* const state) {
- int used = false; // assume key is NOT-handled
- switch(msg->input.type) {
- case InputTypeShort: //# <! After InputTypeRelease within INPUT_LONG_PRESS interval
- switch(msg->input.key) {
- case InputKeyUp: { //# <U [ SHORT-UP ]
- bool init =
- ecInit(&state->ec, NULL); // Initialise the controller //! NULL = no encryption
- (void)init; // in case INFO is optimised out
- INFO("%s : %s", __func__, (init ? "init OK" : "init fail"));
- used = true;
- break;
- }
- case InputKeyOk: //# <O [ SHORT-OK ]
- if(ecRead(&state->ec) == 0) { // Read the controller
- INFO(
- "%s : joy: {%02X,%02X,%02X,%02X,%02X,%02X}",
- __func__,
- state->ec.joy[0],
- state->ec.joy[1],
- state->ec.joy[2],
- state->ec.joy[3],
- state->ec.joy[4],
- state->ec.joy[5]);
- }
- used = true;
- break;
- case InputKeyDown: //# <D [ SHORT-DOWN ]
- timerEn(state, true); // restart the timer
- sceneSet(state, state->scenePrev);
- used = true;
- break;
- case InputKeyBack: //# <B [ SHORT-BACK ]
- state->run = false;
- used = true;
- break;
- default:
- break; //# <?
- }
- break;
- default:
- break;
- }
- return used;
- }
- //+============================================================================ ========================================
- // SPLASH and RIP screen
- //
- static inline bool splash_key(const eventMsg_t* const msg, state_t* const state) {
- // Back key on the initial SPLASH screen (this will catch the InputKeyPress)
- if((msg->input.key == InputKeyBack) && (state->scenePrev == SCENE_NONE)) state->run = false;
- // ANY-other-KEY press
- if(msg->input.type == InputTypeShort) {
- timerEn(state, true); // Restart the timer
- state->scene = state->scenePegg;
- }
- return true;
- }
- //+============================================================================ ========================================
- // "_pre" allows the plugin to use the key before the active scene gets a chance
- //
- static inline bool key_pre(const eventMsg_t* const msg, state_t* const state) {
- (void)msg;
- (void)state;
- return false;
- }
- //+============================================================================ ========================================
- // "_post" allows the plugin to use a key if it was not used by the active scene
- //
- static inline bool key_post(const eventMsg_t* const msg, state_t* const state) {
- int used = false; // assume key is NOT-handled
- if(msg->input.key == InputKeyBack) {
- if(msg->input.type == InputTypeShort) { //# <B [SHORT-BACK]
- state->ec.init = false; // reset/disconnect the controller
- sceneSet(state, SCENE_WAIT);
- used = true;
- } else if(msg->input.type == InputTypeLong) { //# >B [LONG-BACK]
- state->run = false; // Signal the plugin to exit
- used = true;
- }
- }
- // Easter eggs
- switch(state->scene) {
- case SCENE_SPLASH: // Scenes that do NOT offer Easter eggs
- case SCENE_RIP:
- case SCENE_DEBUG:
- break;
- default:
- if(msg->input.type == InputTypeLong) {
- switch(msg->input.key) {
- case InputKeyDown: //# >D [LONG-DOWN]
- timerEn(state, false); // Stop the timer
- sceneSetEgg(state, SCENE_DEBUG);
- used = true;
- break;
- case InputKeyLeft: //# >L [ LONG-LEFT ]
- timerEn(state, false); // Stop the timer
- sceneSetEgg(state, SCENE_SPLASH);
- used = true;
- break;
- case InputKeyUp: //# >U [ LONG-UP ]
- timerEn(state, false); // Stop the timer
- sceneSetEgg(state, SCENE_RIP);
- used = true;
- break;
- default:
- break;
- }
- }
- break;
- }
- return used;
- }
- //+============================================================================ ========================================
- // Handle a key press event
- //
- bool evKey(const eventMsg_t* const msg, state_t* const state) {
- furi_assert(msg);
- furi_assert(state);
- bool used = key_pre(msg, state);
- if(!used) switch(state->scene) {
- case SCENE_SPLASH: //...
- case SCENE_RIP:
- used = splash_key(msg, state);
- break;
- case SCENE_WAIT:
- used = wait_key(msg, state);
- break;
- case SCENE_DEBUG:
- used = debug_key(msg, state);
- break;
- default:
- if(state->ec.pidx >= PID_ERROR) {
- ERROR("%s : bad PID = %d", __func__, state->ec.pidx);
- } else {
- if((state->scene == SCENE_DUMP) || !ecId[state->ec.pidx].keys)
- ecId[PID_UNKNOWN].keys(msg, state);
- else
- ecId[state->ec.pidx].keys(msg, state);
- }
- break;
- case SCENE_NONE:
- break;
- }
- if(!used) used = key_post(msg, state);
- return used;
- }
|