From: joeycastillo Date: Sun, 29 Sep 2024 13:17:06 +0000 (-0400) Subject: bring in beats face using new time zone function X-Git-Url: https://git.earman.xyz/?a=commitdiff_plain;h=677872434d1984eb54d2755a4b306e5a9b104606;p=sensor-watch.git bring in beats face using new time zone function --- diff --git a/movement/watch_faces/clock/beats_face.c b/movement/watch_faces/clock/beats_face.c deleted file mode 100644 index 85bcbe0..0000000 --- a/movement/watch_faces/clock/beats_face.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2023 Wesley Ellis - * - * 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 "beats_face.h" -#include "watch.h" - -const uint8_t BEAT_REFRESH_FREQUENCY = 8; - -void beats_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { - (void) settings; - (void) watch_face_index; - (void) context_ptr; - if (*context_ptr == NULL) { - *context_ptr = malloc(sizeof(beats_face_state_t)); - } -} - -void beats_face_activate(movement_settings_t *settings, void *context) { - (void) settings; - beats_face_state_t *state = (beats_face_state_t *)context; - state->next_subsecond_update = 0; - state->last_centibeat_displayed = 0; - movement_request_tick_frequency(BEAT_REFRESH_FREQUENCY); -} - -bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { - (void) settings; - beats_face_state_t *state = (beats_face_state_t *)context; - if (event.event_type == EVENT_TICK && event.subsecond != state->next_subsecond_update) { - return true; // math is hard, don't do it if we don't have to. - } - - char buf[16]; - uint32_t centibeats; - - watch_date_time date_time; - switch (event.event_type) { - case EVENT_ACTIVATE: - case EVENT_TICK: - date_time = watch_rtc_get_date_time(); - centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_timezone_offsets[settings->bit.time_zone]); - if (centibeats == state->last_centibeat_displayed) { - // we missed this update, try again next subsecond - state->next_subsecond_update = (event.subsecond + 1) % BEAT_REFRESH_FREQUENCY; - } else { - state->next_subsecond_update = (event.subsecond + 1 + (BEAT_REFRESH_FREQUENCY * 2 / 3)) % BEAT_REFRESH_FREQUENCY; - state->last_centibeat_displayed = centibeats; - } - sprintf(buf, "bt %6lu", centibeats); - - watch_display_string(buf, 0); - break; - case EVENT_LOW_ENERGY_UPDATE: - if (!watch_tick_animation_is_running()) watch_start_tick_animation(432); - date_time = watch_rtc_get_date_time(); - centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_timezone_offsets[settings->bit.time_zone]); - sprintf(buf, "bt %4lu ", centibeats / 100); - - watch_display_string(buf, 0); - break; - default: - movement_default_loop_handler(event, settings); - break; - } - - return true; -} - -void beats_face_resign(movement_settings_t *settings, void *context) { - (void) settings; - (void) context; -} - -uint32_t clock2beats(uint32_t hours, uint32_t minutes, uint32_t seconds, uint32_t subseconds, int16_t utc_offset) { - uint32_t retval = seconds * 1000 + (subseconds * 1000) / (BEAT_REFRESH_FREQUENCY); - retval += 60 * minutes * 1000; - retval += hours * 60 * 60 * 1000; - retval -= (utc_offset - 60) * 60 * 1000; - - retval /= 864; // convert to centibeats - retval %= 100000; - - return retval; -} diff --git a/movement/watch_faces/clock/beats_face.h b/movement/watch_faces/clock/beats_face.h deleted file mode 100644 index 4a06624..0000000 --- a/movement/watch_faces/clock/beats_face.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2023 Wesley Ellis - * - * 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 BEATS_FACE_H_ -#define BEATS_FACE_H_ - -/* - * BEATS TIME face - * - * The Beat Time face displays the current Swatch Internet Time, or .beat time. - * This is a decimal time system that divides the day into 1000 beats. - * - * The three large digits in the bottom row indicate the current beat, and the - * two smaller digits (normally the seconds in Simple Clock) indicate the - * fractional beat; so for example you can read “67214” as “beat 672.14”. - */ - -#include "movement.h" - -typedef struct { - int8_t next_subsecond_update; - uint32_t last_centibeat_displayed; -} beats_face_state_t; - -uint32_t clock2beats(uint32_t hours, uint32_t minutes, uint32_t seconds, uint32_t subseconds, int16_t utc_offset); -void beats_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); -void beats_face_activate(movement_settings_t *settings, void *context); -bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void *context); -void beats_face_resign(movement_settings_t *settings, void *context); - -#define beats_face ((const watch_face_t){ \ - beats_face_setup, \ - beats_face_activate, \ - beats_face_loop, \ - beats_face_resign, \ - NULL, \ -}) - -#endif // BEATS_FACE_H_ \ No newline at end of file diff --git a/movement_config.h b/movement_config.h index f5c7a2c..2ad4cdb 100644 --- a/movement_config.h +++ b/movement_config.h @@ -29,6 +29,7 @@ const watch_face_t watch_faces[] = { simple_clock_face, + beats_face, world_clock_face, countdown_face, preferences_face, diff --git a/movement_faces.h b/movement_faces.h index 61d2f37..5ea739a 100644 --- a/movement_faces.h +++ b/movement_faces.h @@ -25,6 +25,7 @@ #pragma once #include "simple_clock_face.h" +#include "beats_face.h" #include "world_clock_face.h" #include "countdown_face.h" #include "set_time_face.h" diff --git a/watch-faces.mk b/watch-faces.mk index 5240782..734560d 100644 --- a/watch-faces.mk +++ b/watch-faces.mk @@ -1,5 +1,6 @@ SRCS += \ ./watch-faces/clock/simple_clock_face.c \ + ./watch-faces/clock/beats_face.c \ ./watch-faces/clock/world_clock_face.c \ ./watch-faces/complication/countdown_face.c \ ./watch-faces/settings/set_time_face.c \ diff --git a/watch-faces/clock/beats_face.c b/watch-faces/clock/beats_face.c new file mode 100644 index 0000000..9a9ffb9 --- /dev/null +++ b/watch-faces/clock/beats_face.c @@ -0,0 +1,107 @@ +/* + * MIT License + * + * Copyright (c) 2023 Wesley Ellis + * + * 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 "beats_face.h" +#include "watch.h" + +const uint8_t BEAT_REFRESH_FREQUENCY = 8; + +void beats_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + (void) settings; + (void) watch_face_index; + (void) context_ptr; + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(beats_face_state_t)); + } +} + +void beats_face_activate(movement_settings_t *settings, void *context) { + (void) settings; + beats_face_state_t *state = (beats_face_state_t *)context; + state->next_subsecond_update = 0; + state->last_centibeat_displayed = 0; + movement_request_tick_frequency(BEAT_REFRESH_FREQUENCY); +} + +bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + (void) settings; + beats_face_state_t *state = (beats_face_state_t *)context; + if (event.event_type == EVENT_TICK && event.subsecond != state->next_subsecond_update) { + return true; // math is hard, don't do it if we don't have to. + } + + char buf[16]; + uint32_t centibeats; + + watch_date_time date_time; + switch (event.event_type) { + case EVENT_ACTIVATE: + case EVENT_TICK: + date_time = watch_rtc_get_date_time(); + centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_get_current_timezone_offset()); + if (centibeats == state->last_centibeat_displayed) { + // we missed this update, try again next subsecond + state->next_subsecond_update = (event.subsecond + 1) % BEAT_REFRESH_FREQUENCY; + } else { + state->next_subsecond_update = (event.subsecond + 1 + (BEAT_REFRESH_FREQUENCY * 2 / 3)) % BEAT_REFRESH_FREQUENCY; + state->last_centibeat_displayed = centibeats; + } + sprintf(buf, "bt %6lu", centibeats); + + watch_display_text(WATCH_POSITION_FULL, buf); + break; + case EVENT_LOW_ENERGY_UPDATE: + if (!watch_tick_animation_is_running()) watch_start_tick_animation(432); + date_time = watch_rtc_get_date_time(); + centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_get_current_timezone_offset()); + sprintf(buf, "bt %4lu ", centibeats / 100); + + watch_display_text(WATCH_POSITION_FULL, buf); + break; + default: + movement_default_loop_handler(event, settings); + break; + } + + return true; +} + +void beats_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; +} + +uint32_t clock2beats(uint32_t hours, uint32_t minutes, uint32_t seconds, uint32_t subseconds, int16_t utc_offset) { + uint32_t retval = seconds * 1000 + (subseconds * 1000) / (BEAT_REFRESH_FREQUENCY); + retval += 60 * minutes * 1000; + retval += hours * 60 * 60 * 1000; + retval -= (utc_offset - 3600) * 1000; + + retval /= 864; // convert to centibeats + retval %= 100000; + + return retval; +} diff --git a/watch-faces/clock/beats_face.h b/watch-faces/clock/beats_face.h new file mode 100644 index 0000000..4a06624 --- /dev/null +++ b/watch-faces/clock/beats_face.h @@ -0,0 +1,60 @@ +/* + * MIT License + * + * Copyright (c) 2023 Wesley Ellis + * + * 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 BEATS_FACE_H_ +#define BEATS_FACE_H_ + +/* + * BEATS TIME face + * + * The Beat Time face displays the current Swatch Internet Time, or .beat time. + * This is a decimal time system that divides the day into 1000 beats. + * + * The three large digits in the bottom row indicate the current beat, and the + * two smaller digits (normally the seconds in Simple Clock) indicate the + * fractional beat; so for example you can read “67214” as “beat 672.14”. + */ + +#include "movement.h" + +typedef struct { + int8_t next_subsecond_update; + uint32_t last_centibeat_displayed; +} beats_face_state_t; + +uint32_t clock2beats(uint32_t hours, uint32_t minutes, uint32_t seconds, uint32_t subseconds, int16_t utc_offset); +void beats_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void beats_face_activate(movement_settings_t *settings, void *context); +bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void beats_face_resign(movement_settings_t *settings, void *context); + +#define beats_face ((const watch_face_t){ \ + beats_face_setup, \ + beats_face_activate, \ + beats_face_loop, \ + beats_face_resign, \ + NULL, \ +}) + +#endif // BEATS_FACE_H_ \ No newline at end of file