diff --git a/movement/watch_faces/complication/tally_face.c b/movement/watch_faces/complication/tally_face.c index 896a54f..3ea5503 100644 --- a/movement/watch_faces/complication/tally_face.c +++ b/movement/watch_faces/complication/tally_face.c @@ -27,47 +27,162 @@ #include "tally_face.h" #include "watch.h" +#define TALLY_FACE_MAX 9999 +#define TALLY_FACE_MIN -99 + +static bool _init_val; +static bool _quick_ticks_running; + +static const int16_t _tally_default[] = { + 0, + +#ifdef TALLY_FACE_PRESETS_MTG + 20, + 40, +#endif /* TALLY_FACE_PRESETS_MTG */ + +#ifdef TALLY_FACE_PRESETS_YUGIOH + 4000, + 8000, +#endif /* TALLY_FACE_PRESETS_YUGIOH */ + +}; + +#define TALLY_FACE_PRESETS_SIZE() (sizeof(_tally_default) / sizeof(int16_t)) + void tally_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; (void) watch_face_index; if (*context_ptr == NULL) { *context_ptr = malloc(sizeof(tally_state_t)); memset(*context_ptr, 0, sizeof(tally_state_t)); + tally_state_t *state = (tally_state_t *)*context_ptr; + state->tally_default_idx = 0; + state->tally_idx = _tally_default[state->tally_default_idx]; + _init_val = true; } } void tally_face_activate(movement_settings_t *settings, void *context) { (void) settings; (void) context; + _quick_ticks_running = false; +} + +static void start_quick_cyc(void){ + _quick_ticks_running = true; + movement_request_tick_frequency(8); +} + +static void stop_quick_cyc(void){ + _quick_ticks_running = false; + movement_request_tick_frequency(1); +} + +static void tally_face_increment(tally_state_t *state, bool sound_on) { + bool soundOn = !_quick_ticks_running && sound_on; + _init_val = false; + if (state->tally_idx >= TALLY_FACE_MAX){ + if (soundOn) watch_buzzer_play_note(BUZZER_NOTE_E7, 30); + } + else { + state->tally_idx++; + print_tally(state, sound_on); + if (soundOn) watch_buzzer_play_note(BUZZER_NOTE_E6, 30); + } +} + +static void tally_face_decrement(tally_state_t *state, bool sound_on) { + bool soundOn = !_quick_ticks_running && sound_on; + _init_val = false; + if (state->tally_idx <= TALLY_FACE_MIN){ + if (soundOn) watch_buzzer_play_note(BUZZER_NOTE_C5SHARP_D5FLAT, 30); + } + else { + state->tally_idx--; + print_tally(state, sound_on); + if (soundOn) watch_buzzer_play_note(BUZZER_NOTE_C6SHARP_D6FLAT, 30); + } +} + +static bool tally_face_should_move_back(tally_state_t *state) { + if (TALLY_FACE_PRESETS_SIZE() <= 1) { return false; } + return state->tally_idx == _tally_default[state->tally_default_idx]; } bool tally_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { - (void) settings; tally_state_t *state = (tally_state_t *)context; - + static bool using_led = false; + + if (using_led) { + if(!watch_get_pin_level(BTN_MODE) && !watch_get_pin_level(BTN_LIGHT) && !watch_get_pin_level(BTN_ALARM)) + using_led = false; + else { + if (event.event_type == EVENT_LIGHT_BUTTON_DOWN || event.event_type == EVENT_ALARM_BUTTON_DOWN) + movement_illuminate_led(); + return true; + } + } + switch (event.event_type) { - case EVENT_ALARM_BUTTON_UP: - // increment tally index - state->tally_idx++; - if (state->tally_idx > 999999) { //0-999,999 - //reset tally index and play a reset tune - state->tally_idx = 0; - watch_buzzer_play_note(BUZZER_NOTE_G6, 30); - watch_buzzer_play_note(BUZZER_NOTE_REST, 30); + case EVENT_TICK: + if (_quick_ticks_running) { + bool light_pressed = watch_get_pin_level(BTN_LIGHT); + bool alarm_pressed = watch_get_pin_level(BTN_ALARM); + if (light_pressed && alarm_pressed) stop_quick_cyc(); + else if (light_pressed) tally_face_increment(state, settings->bit.button_should_sound); + else if (alarm_pressed) tally_face_decrement(state, settings->bit.button_should_sound); + else stop_quick_cyc(); } - print_tally(state); - watch_buzzer_play_note(BUZZER_NOTE_E6, 30); + break; + case EVENT_ALARM_BUTTON_UP: + tally_face_decrement(state, settings->bit.button_should_sound); break; case EVENT_ALARM_LONG_PRESS: - state->tally_idx = 0; // reset tally index - //play a reset tune - watch_buzzer_play_note(BUZZER_NOTE_G6, 30); - watch_buzzer_play_note(BUZZER_NOTE_REST, 30); - watch_buzzer_play_note(BUZZER_NOTE_E6, 30); - print_tally(state); + tally_face_decrement(state, settings->bit.button_should_sound); + start_quick_cyc(); + break; + case EVENT_MODE_LONG_PRESS: + if (tally_face_should_move_back(state)) { + _init_val = true; + movement_move_to_face(0); + } + else { + state->tally_idx = _tally_default[state->tally_default_idx]; // reset tally index + _init_val = true; + //play a reset tune + if (settings->bit.button_should_sound) watch_buzzer_play_note(BUZZER_NOTE_G6, 30); + if (settings->bit.button_should_sound) watch_buzzer_play_note(BUZZER_NOTE_REST, 30); + if (settings->bit.button_should_sound) watch_buzzer_play_note(BUZZER_NOTE_E6, 30); + print_tally(state, settings->bit.button_should_sound); + } + break; + case EVENT_LIGHT_BUTTON_UP: + tally_face_increment(state, settings->bit.button_should_sound); + break; + case EVENT_LIGHT_BUTTON_DOWN: + case EVENT_ALARM_BUTTON_DOWN: + if (watch_get_pin_level(BTN_MODE)) { + movement_illuminate_led(); + using_led = true; + } + break; + case EVENT_LIGHT_LONG_PRESS: + if (TALLY_FACE_PRESETS_SIZE() > 1 && _init_val){ + state->tally_default_idx = (state->tally_default_idx + 1) % TALLY_FACE_PRESETS_SIZE(); + state->tally_idx = _tally_default[state->tally_default_idx]; + if (settings->bit.button_should_sound) watch_buzzer_play_note(BUZZER_NOTE_E6, 30); + if (settings->bit.button_should_sound) watch_buzzer_play_note(BUZZER_NOTE_REST, 30); + if (settings->bit.button_should_sound) watch_buzzer_play_note(BUZZER_NOTE_G6, 30); + print_tally(state, settings->bit.button_should_sound); + } + else{ + tally_face_increment(state, settings->bit.button_should_sound); + start_quick_cyc(); + } break; case EVENT_ACTIVATE: - print_tally(state); + print_tally(state, settings->bit.button_should_sound); break; case EVENT_TIMEOUT: // ignore timeout @@ -81,9 +196,16 @@ bool tally_face_loop(movement_event_t event, movement_settings_t *settings, void } // print tally index at the center of display. -void print_tally(tally_state_t *state) { +void print_tally(tally_state_t *state, bool sound_on) { char buf[14]; - sprintf(buf, "TA %06d", (int)(state->tally_idx)); // center of LCD display + if (sound_on) + watch_set_indicator(WATCH_INDICATOR_BELL); + else + watch_clear_indicator(WATCH_INDICATOR_BELL); + if (state->tally_idx >= 0) + sprintf(buf, "TA %4d ", (int)(state->tally_idx)); // center of LCD display + else + sprintf(buf, "TA %-3d", (int)(state->tally_idx)); // center of LCD display watch_display_string(buf, 0); } diff --git a/movement/watch_faces/complication/tally_face.h b/movement/watch_faces/complication/tally_face.h index 8096592..80623f4 100644 --- a/movement/watch_faces/complication/tally_face.h +++ b/movement/watch_faces/complication/tally_face.h @@ -29,25 +29,41 @@ * TALLY face * * Tally face is designed to act as a tally counter. - * Based on the counter_face watch face by Shogo Okamoto. * - * To advance the counter, press the ALARM button. - * To reset, long press the ALARM button. + * Alarm + * Press: Decrement + * Hold : Fast Decrement + * + * Light + * Press: Increment + * Hold : On initial value: Cycles through other initial values. + * Else: Fast Increment + * + * Mode + * Press: Next face + * Hold : On initial value: Go to first face. + * Else: Resets counter + * + * Incrementing or Decrementing the tally will beep if Beeping is set in the global Preferences */ #include "movement.h" typedef struct { - uint32_t tally_idx; + int16_t tally_idx; + uint8_t tally_default_idx; } tally_state_t; +//#define TALLY_FACE_PRESETS_MTG +//#define TALLY_FACE_PRESETS_YUGIOH + void tally_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void tally_face_activate(movement_settings_t *settings, void *context); bool tally_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void tally_face_resign(movement_settings_t *settings, void *context); -void print_tally(tally_state_t *state); +void print_tally(tally_state_t *state, bool sound_on); #define tally_face ((const watch_face_t){ \ tally_face_setup, \