From: joeycastillo Date: Mon, 23 Sep 2024 12:49:19 +0000 (-0400) Subject: 24H only is handled by disabling changing the setting X-Git-Url: https://git.earman.xyz/?a=commitdiff_plain;h=0a6ef3d82ada84ef20baff3fbb84ed5114f7031a;p=sensor-watch.git 24H only is handled by disabling changing the setting --- diff --git a/movement/watch_faces/clock/world_clock_face.c b/movement/watch_faces/clock/world_clock_face.c deleted file mode 100644 index b12d9cd..0000000 --- a/movement/watch_faces/clock/world_clock_face.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022 Joey Castillo - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include "world_clock_face.h" -#include "watch.h" -#include "watch_utility.h" - -void world_clock_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(world_clock_state_t)); - memset(*context_ptr, 0, sizeof(world_clock_state_t)); - uint8_t backup_register = movement_claim_backup_register(); - if (backup_register) { - world_clock_state_t *state = (world_clock_state_t *)*context_ptr; - state->settings.reg = watch_get_backup_data(backup_register); - state->backup_register = backup_register; - } - } -} - -void world_clock_face_activate(movement_settings_t *settings, void *context) { - (void) settings; - world_clock_state_t *state = (world_clock_state_t *)context; - state->current_screen = 0; - - if (watch_tick_animation_is_running()) watch_stop_tick_animation(); -} - -static bool world_clock_face_do_display_mode(movement_event_t event, movement_settings_t *settings, world_clock_state_t *state) { - char buf[11]; - uint8_t pos; - - uint32_t timestamp; - uint32_t previous_date_time; - watch_date_time date_time; - switch (event.event_type) { - case EVENT_ACTIVATE: - if (settings->bit.clock_mode_24h) watch_set_indicator(WATCH_INDICATOR_24H); - watch_set_colon(); - state->previous_date_time = 0xFFFFFFFF; - // fall through - case EVENT_TICK: - case EVENT_LOW_ENERGY_UPDATE: - date_time = watch_rtc_get_date_time(); - timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60); - date_time = watch_utility_date_time_from_unix_time(timestamp, movement_timezone_offsets[state->settings.bit.timezone_index] * 60); - previous_date_time = state->previous_date_time; - state->previous_date_time = date_time.reg; - - if ((date_time.reg >> 6) == (previous_date_time >> 6) && event.event_type != EVENT_LOW_ENERGY_UPDATE) { - // everything before seconds is the same, don't waste cycles setting those segments. - pos = 8; - sprintf(buf, "%02d", date_time.unit.second); - } else if ((date_time.reg >> 12) == (previous_date_time >> 12) && event.event_type != EVENT_LOW_ENERGY_UPDATE) { - // everything before minutes is the same. - pos = 6; - sprintf(buf, "%02d%02d", date_time.unit.minute, date_time.unit.second); - } else { - // other stuff changed; let's do it all. - if (!settings->bit.clock_mode_24h) { - // if we are in 12 hour mode, do some cleanup. - if (date_time.unit.hour < 12) { - watch_clear_indicator(WATCH_INDICATOR_PM); - } else { - watch_set_indicator(WATCH_INDICATOR_PM); - } - date_time.unit.hour %= 12; - if (date_time.unit.hour == 0) date_time.unit.hour = 12; - } - pos = 0; - if (event.event_type == EVENT_LOW_ENERGY_UPDATE) { - if (!watch_tick_animation_is_running()) watch_start_tick_animation(500); - sprintf(buf, "%c%c%2d%2d%02d ", - movement_valid_position_0_chars[state->settings.bit.char_0], - movement_valid_position_1_chars[state->settings.bit.char_1], - date_time.unit.day, - date_time.unit.hour, - date_time.unit.minute); - } else { - sprintf(buf, "%c%c%2d%2d%02d%02d", - movement_valid_position_0_chars[state->settings.bit.char_0], - movement_valid_position_1_chars[state->settings.bit.char_1], - date_time.unit.day, - date_time.unit.hour, - date_time.unit.minute, - date_time.unit.second); - } - } - watch_display_string(buf, pos); - break; - case EVENT_ALARM_LONG_PRESS: - movement_request_tick_frequency(4); - state->current_screen = 1; - break; - default: - return movement_default_loop_handler(event, settings); - } - - return true; -} - -static bool _world_clock_face_do_settings_mode(movement_event_t event, movement_settings_t *settings, world_clock_state_t *state) { - switch (event.event_type) { - case EVENT_MODE_BUTTON_UP: - if (state->backup_register) watch_store_backup_data(state->settings.reg, state->backup_register); - movement_move_to_next_face(); - return false; - case EVENT_LIGHT_BUTTON_DOWN: - state->current_screen++; - if (state->current_screen > 3) { - movement_request_tick_frequency(1); - state->current_screen = 0; - if (state->backup_register) watch_store_backup_data(state->settings.reg, state->backup_register); - event.event_type = EVENT_ACTIVATE; - return world_clock_face_do_display_mode(event, settings, state); - } - break; - case EVENT_ALARM_BUTTON_DOWN: - switch (state->current_screen) { - case 1: - state->settings.bit.char_0++; - if (state->settings.bit.char_0 >= strlen(movement_valid_position_0_chars)) { - state->settings.bit.char_0 = 0; - } - break; - case 2: - state->settings.bit.char_1++; - if (state->settings.bit.char_1 >= strlen(movement_valid_position_1_chars)) { - state->settings.bit.char_1 = 0; - } - break; - case 3: - state->settings.bit.timezone_index++; - if (state->settings.bit.timezone_index > 40) state->settings.bit.timezone_index = 0; - break; - } - break; - case EVENT_TIMEOUT: - movement_move_to_face(0); - break; - default: - break; - } - - char buf[13]; - sprintf(buf, "%c%c %3d%02d ", - movement_valid_position_0_chars[state->settings.bit.char_0], - movement_valid_position_1_chars[state->settings.bit.char_1], - (int8_t) (movement_timezone_offsets[state->settings.bit.timezone_index] / 60), - (int8_t) (movement_timezone_offsets[state->settings.bit.timezone_index] % 60) * (movement_timezone_offsets[state->settings.bit.timezone_index] < 0 ? -1 : 1)); - watch_set_colon(); - watch_clear_indicator(WATCH_INDICATOR_PM); - - // blink up the parameter we're setting - if (event.subsecond % 2) { - switch (state->current_screen) { - case 1: - case 2: - buf[state->current_screen - 1] = '_'; - break; - case 3: - watch_clear_colon(); - sprintf(buf + 3, " "); - break; - } - } - - watch_display_string(buf, 0); - - return true; -} - -bool world_clock_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { - world_clock_state_t *state = (world_clock_state_t *)context; - - if (state->current_screen == 0) { - return world_clock_face_do_display_mode(event, settings, state); - } else { - return _world_clock_face_do_settings_mode(event, settings, state); - } -} - -void world_clock_face_resign(movement_settings_t *settings, void *context) { - (void) settings; - (void) context; -} diff --git a/movement/watch_faces/clock/world_clock_face.h b/movement/watch_faces/clock/world_clock_face.h deleted file mode 100644 index 92e91a6..0000000 --- a/movement/watch_faces/clock/world_clock_face.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022 Joey Castillo - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef WORLD_CLOCK_FACE_H_ -#define WORLD_CLOCK_FACE_H_ - -/* - * WORLD CLOCK FACE - * - * The World Clock watch face looks similar to the Simple Clock watch face, - * but you’ll notice that at first launch the day of week indicators are blank. - * That’s because this watch face does not display the day of the week. - * Instead, you may customize these letters to display the name of a time zone - * of your choosing. - * - * To customize this watch face, press and hold the ALARM button. The first - * letter in the top row will begin flashing. Press the ALARM button repeatedly - * to advance through the available letters in the first slot, then press the - * LIGHT button to move to the second letter. Finally, press LIGHT again to move - * to the time zone setting, and press ALARM to cycle through the available time - * zones. Press LIGHT one last time to return to the world clock display. - * - * Note that the second slot cannot display all letters or numbers. Also note - * that at this time, time zones do not automatically update for daylight saving - * time; you will need to manually adjust this field each spring and fall. - */ - -#include "movement.h" - -typedef union { - struct { - uint8_t char_0; - uint8_t char_1; - uint8_t timezone_index; - } bit; - uint32_t reg; -} world_clock_settings_t; - -typedef struct { - world_clock_settings_t settings; - uint8_t backup_register; - uint8_t current_screen; - uint32_t previous_date_time; -} world_clock_state_t; - -void world_clock_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); -void world_clock_face_activate(movement_settings_t *settings, void *context); -bool world_clock_face_loop(movement_event_t event, movement_settings_t *settings, void *context); -void world_clock_face_resign(movement_settings_t *settings, void *context); - -uint8_t world_clock_face_get_weekday(uint16_t day, uint16_t month, uint16_t year); - -#define world_clock_face ((const watch_face_t){ \ - world_clock_face_setup, \ - world_clock_face_activate, \ - world_clock_face_loop, \ - world_clock_face_resign, \ - NULL, \ -}) - -#endif // WORLD_CLOCK_FACE_H_ diff --git a/watch-faces/clock/simple_clock_face.c b/watch-faces/clock/simple_clock_face.c index 19c661c..0257c6e 100644 --- a/watch-faces/clock/simple_clock_face.c +++ b/watch-faces/clock/simple_clock_face.c @@ -51,11 +51,7 @@ void simple_clock_face_activate(movement_settings_t *settings, void *context) { if (watch_tick_animation_is_running()) watch_stop_tick_animation(); -#ifdef CLOCK_FACE_24H_ONLY - watch_set_indicator(WATCH_INDICATOR_24H); -#else if (settings->bit.clock_mode_24h) watch_set_indicator(WATCH_INDICATOR_24H); -#endif // handle chime indicator if (state->signal_enabled) watch_set_indicator(WATCH_INDICATOR_BELL); @@ -110,7 +106,6 @@ bool simple_clock_face_loop(movement_event_t event, movement_settings_t *setting watch_display_text(WATCH_POSITION_SECONDS, buf + 2); } else { // other stuff changed; let's do it all. -#ifndef CLOCK_FACE_24H_ONLY if (!settings->bit.clock_mode_24h) { // if we are in 12 hour mode, do some cleanup. if (date_time.unit.hour < 12) { @@ -121,7 +116,6 @@ bool simple_clock_face_loop(movement_event_t event, movement_settings_t *setting date_time.unit.hour %= 12; if (date_time.unit.hour == 0) date_time.unit.hour = 12; } -#endif watch_display_text(WATCH_POSITION_TOP_LEFT, (char *) watch_utility_get_weekday(date_time)); sprintf(buf, "%2d%2d%02d%02d", date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second); watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); diff --git a/watch-faces/clock/world_clock_face.c b/watch-faces/clock/world_clock_face.c new file mode 100644 index 0000000..b12d9cd --- /dev/null +++ b/watch-faces/clock/world_clock_face.c @@ -0,0 +1,211 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include "world_clock_face.h" +#include "watch.h" +#include "watch_utility.h" + +void world_clock_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(world_clock_state_t)); + memset(*context_ptr, 0, sizeof(world_clock_state_t)); + uint8_t backup_register = movement_claim_backup_register(); + if (backup_register) { + world_clock_state_t *state = (world_clock_state_t *)*context_ptr; + state->settings.reg = watch_get_backup_data(backup_register); + state->backup_register = backup_register; + } + } +} + +void world_clock_face_activate(movement_settings_t *settings, void *context) { + (void) settings; + world_clock_state_t *state = (world_clock_state_t *)context; + state->current_screen = 0; + + if (watch_tick_animation_is_running()) watch_stop_tick_animation(); +} + +static bool world_clock_face_do_display_mode(movement_event_t event, movement_settings_t *settings, world_clock_state_t *state) { + char buf[11]; + uint8_t pos; + + uint32_t timestamp; + uint32_t previous_date_time; + watch_date_time date_time; + switch (event.event_type) { + case EVENT_ACTIVATE: + if (settings->bit.clock_mode_24h) watch_set_indicator(WATCH_INDICATOR_24H); + watch_set_colon(); + state->previous_date_time = 0xFFFFFFFF; + // fall through + case EVENT_TICK: + case EVENT_LOW_ENERGY_UPDATE: + date_time = watch_rtc_get_date_time(); + timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60); + date_time = watch_utility_date_time_from_unix_time(timestamp, movement_timezone_offsets[state->settings.bit.timezone_index] * 60); + previous_date_time = state->previous_date_time; + state->previous_date_time = date_time.reg; + + if ((date_time.reg >> 6) == (previous_date_time >> 6) && event.event_type != EVENT_LOW_ENERGY_UPDATE) { + // everything before seconds is the same, don't waste cycles setting those segments. + pos = 8; + sprintf(buf, "%02d", date_time.unit.second); + } else if ((date_time.reg >> 12) == (previous_date_time >> 12) && event.event_type != EVENT_LOW_ENERGY_UPDATE) { + // everything before minutes is the same. + pos = 6; + sprintf(buf, "%02d%02d", date_time.unit.minute, date_time.unit.second); + } else { + // other stuff changed; let's do it all. + if (!settings->bit.clock_mode_24h) { + // if we are in 12 hour mode, do some cleanup. + if (date_time.unit.hour < 12) { + watch_clear_indicator(WATCH_INDICATOR_PM); + } else { + watch_set_indicator(WATCH_INDICATOR_PM); + } + date_time.unit.hour %= 12; + if (date_time.unit.hour == 0) date_time.unit.hour = 12; + } + pos = 0; + if (event.event_type == EVENT_LOW_ENERGY_UPDATE) { + if (!watch_tick_animation_is_running()) watch_start_tick_animation(500); + sprintf(buf, "%c%c%2d%2d%02d ", + movement_valid_position_0_chars[state->settings.bit.char_0], + movement_valid_position_1_chars[state->settings.bit.char_1], + date_time.unit.day, + date_time.unit.hour, + date_time.unit.minute); + } else { + sprintf(buf, "%c%c%2d%2d%02d%02d", + movement_valid_position_0_chars[state->settings.bit.char_0], + movement_valid_position_1_chars[state->settings.bit.char_1], + date_time.unit.day, + date_time.unit.hour, + date_time.unit.minute, + date_time.unit.second); + } + } + watch_display_string(buf, pos); + break; + case EVENT_ALARM_LONG_PRESS: + movement_request_tick_frequency(4); + state->current_screen = 1; + break; + default: + return movement_default_loop_handler(event, settings); + } + + return true; +} + +static bool _world_clock_face_do_settings_mode(movement_event_t event, movement_settings_t *settings, world_clock_state_t *state) { + switch (event.event_type) { + case EVENT_MODE_BUTTON_UP: + if (state->backup_register) watch_store_backup_data(state->settings.reg, state->backup_register); + movement_move_to_next_face(); + return false; + case EVENT_LIGHT_BUTTON_DOWN: + state->current_screen++; + if (state->current_screen > 3) { + movement_request_tick_frequency(1); + state->current_screen = 0; + if (state->backup_register) watch_store_backup_data(state->settings.reg, state->backup_register); + event.event_type = EVENT_ACTIVATE; + return world_clock_face_do_display_mode(event, settings, state); + } + break; + case EVENT_ALARM_BUTTON_DOWN: + switch (state->current_screen) { + case 1: + state->settings.bit.char_0++; + if (state->settings.bit.char_0 >= strlen(movement_valid_position_0_chars)) { + state->settings.bit.char_0 = 0; + } + break; + case 2: + state->settings.bit.char_1++; + if (state->settings.bit.char_1 >= strlen(movement_valid_position_1_chars)) { + state->settings.bit.char_1 = 0; + } + break; + case 3: + state->settings.bit.timezone_index++; + if (state->settings.bit.timezone_index > 40) state->settings.bit.timezone_index = 0; + break; + } + break; + case EVENT_TIMEOUT: + movement_move_to_face(0); + break; + default: + break; + } + + char buf[13]; + sprintf(buf, "%c%c %3d%02d ", + movement_valid_position_0_chars[state->settings.bit.char_0], + movement_valid_position_1_chars[state->settings.bit.char_1], + (int8_t) (movement_timezone_offsets[state->settings.bit.timezone_index] / 60), + (int8_t) (movement_timezone_offsets[state->settings.bit.timezone_index] % 60) * (movement_timezone_offsets[state->settings.bit.timezone_index] < 0 ? -1 : 1)); + watch_set_colon(); + watch_clear_indicator(WATCH_INDICATOR_PM); + + // blink up the parameter we're setting + if (event.subsecond % 2) { + switch (state->current_screen) { + case 1: + case 2: + buf[state->current_screen - 1] = '_'; + break; + case 3: + watch_clear_colon(); + sprintf(buf + 3, " "); + break; + } + } + + watch_display_string(buf, 0); + + return true; +} + +bool world_clock_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + world_clock_state_t *state = (world_clock_state_t *)context; + + if (state->current_screen == 0) { + return world_clock_face_do_display_mode(event, settings, state); + } else { + return _world_clock_face_do_settings_mode(event, settings, state); + } +} + +void world_clock_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; +} diff --git a/watch-faces/clock/world_clock_face.h b/watch-faces/clock/world_clock_face.h new file mode 100644 index 0000000..92e91a6 --- /dev/null +++ b/watch-faces/clock/world_clock_face.h @@ -0,0 +1,82 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef WORLD_CLOCK_FACE_H_ +#define WORLD_CLOCK_FACE_H_ + +/* + * WORLD CLOCK FACE + * + * The World Clock watch face looks similar to the Simple Clock watch face, + * but you’ll notice that at first launch the day of week indicators are blank. + * That’s because this watch face does not display the day of the week. + * Instead, you may customize these letters to display the name of a time zone + * of your choosing. + * + * To customize this watch face, press and hold the ALARM button. The first + * letter in the top row will begin flashing. Press the ALARM button repeatedly + * to advance through the available letters in the first slot, then press the + * LIGHT button to move to the second letter. Finally, press LIGHT again to move + * to the time zone setting, and press ALARM to cycle through the available time + * zones. Press LIGHT one last time to return to the world clock display. + * + * Note that the second slot cannot display all letters or numbers. Also note + * that at this time, time zones do not automatically update for daylight saving + * time; you will need to manually adjust this field each spring and fall. + */ + +#include "movement.h" + +typedef union { + struct { + uint8_t char_0; + uint8_t char_1; + uint8_t timezone_index; + } bit; + uint32_t reg; +} world_clock_settings_t; + +typedef struct { + world_clock_settings_t settings; + uint8_t backup_register; + uint8_t current_screen; + uint32_t previous_date_time; +} world_clock_state_t; + +void world_clock_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void world_clock_face_activate(movement_settings_t *settings, void *context); +bool world_clock_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void world_clock_face_resign(movement_settings_t *settings, void *context); + +uint8_t world_clock_face_get_weekday(uint16_t day, uint16_t month, uint16_t year); + +#define world_clock_face ((const watch_face_t){ \ + world_clock_face_setup, \ + world_clock_face_activate, \ + world_clock_face_loop, \ + world_clock_face_resign, \ + NULL, \ +}) + +#endif // WORLD_CLOCK_FACE_H_