tick_animation is now sleep_animation (which just displays an indicator on new LCD)

This commit is contained in:
joeycastillo 2024-09-29 15:24:11 -04:00
parent 3795b8494a
commit 4b8b092594
36 changed files with 65 additions and 65 deletions

View File

@ -69,7 +69,7 @@ bool <#watch_face_name#>_face_loop(movement_event_t event, void *context) {
// If you did not resign in EVENT_TIMEOUT, you can use this event to update the display once a minute.
// Avoid displaying fast-updating values like seconds, since the display won't update again for 60 seconds.
// You should also consider starting the tick animation, to show the wearer that this is sleep mode:
// watch_start_tick_animation(500);
// watch_start_sleep_animation(500);
break;
default:
// Movement's default loop handler will step in for any cases you don't handle above:

View File

@ -72,8 +72,8 @@ void close_enough_clock_face_setup(uint8_t watch_face_index, void ** context_ptr
void close_enough_clock_face_activate(void *context) {
close_enough_clock_state_t *state = (close_enough_clock_state_t *)context;
if (watch_tick_animation_is_running()) {
watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) {
watch_stop_sleep_animation();
}
if (movement_clock_mode_24h()) {

View File

@ -114,7 +114,7 @@ bool day_night_percentage_face_loop(movement_event_t event, void *context) {
watch_set_indicator(WATCH_INDICATOR_PM);
}
if (event.event_type == EVENT_LOW_ENERGY_UPDATE) {
if (!watch_tick_animation_is_running()) watch_start_tick_animation(500);
if (!watch_sleep_animation_is_running()) watch_start_sleep_animation(500);
sprintf(buf, "%s%2d %02d ", weekday, date_time.unit.day, percentage / 100);
} else {
sprintf(buf, "%s%2d %04d", weekday, date_time.unit.day, percentage);

View File

@ -74,7 +74,7 @@ bool french_revolutionary_face_loop(movement_event_t event, void *context) {
if (event.event_type == EVENT_LOW_ENERGY_UPDATE) {
buf[8] = ' ';
buf[9] = ' ';
if (!watch_tick_animation_is_running()) { watch_start_tick_animation(500); }
if (!watch_sleep_animation_is_running()) { watch_start_sleep_animation(500); }
}
// Update the display with our decimal time

View File

@ -144,7 +144,7 @@ bool mars_time_face_loop(movement_event_t event, void *context) {
break;
case EVENT_LOW_ENERGY_UPDATE:
// TODO: low energy update
// watch_start_tick_animation(500);
// watch_start_sleep_animation(500);
break;
case EVENT_LIGHT_BUTTON_DOWN:
// don't light up every time light is hit

View File

@ -85,7 +85,7 @@ bool minimal_clock_face_loop(movement_event_t event, void *context) {
// If you did not resign in EVENT_TIMEOUT, you can use this event to update the display once a minute.
// Avoid displaying fast-updating values like seconds, since the display won't update again for 60 seconds.
// You should also consider starting the tick animation, to show the wearer that this is sleep mode:
// watch_start_tick_animation(500);
// watch_start_sleep_animation(500);
_minimal_clock_face_update_display();
break;
default:

View File

@ -80,7 +80,7 @@ void minute_repeater_decimal_face_setup(uint8_t watch_face_index, void ** contex
void minute_repeater_decimal_face_activate(void *context) {
minute_repeater_decimal_state_t *state = (minute_repeater_decimal_state_t *)context;
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
if (movement_clock_mode_24h()) watch_set_indicator(WATCH_INDICATOR_24H);
@ -149,7 +149,7 @@ bool minute_repeater_decimal_face_loop(movement_event_t event, void *context) {
}
pos = 0;
if (event.event_type == EVENT_LOW_ENERGY_UPDATE) {
if (!watch_tick_animation_is_running()) watch_start_tick_animation(500);
if (!watch_sleep_animation_is_running()) watch_start_sleep_animation(500);
sprintf(buf, "%s%2d%2d%02d ", watch_utility_get_weekday(date_time), date_time.unit.day, date_time.unit.hour, date_time.unit.minute);
} else {
sprintf(buf, "%s%2d%2d%02d%02d", watch_utility_get_weekday(date_time), date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);

View File

@ -65,7 +65,7 @@ void repetition_minute_face_setup(uint8_t watch_face_index, void ** context_ptr)
void repetition_minute_face_activate(void *context) {
repetition_minute_state_t *state = (repetition_minute_state_t *)context;
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
if (movement_clock_mode_24h()) watch_set_indicator(WATCH_INDICATOR_24H);
@ -134,7 +134,7 @@ bool repetition_minute_face_loop(movement_event_t event, void *context) {
}
pos = 0;
if (event.event_type == EVENT_LOW_ENERGY_UPDATE) {
if (!watch_tick_animation_is_running()) watch_start_tick_animation(500);
if (!watch_sleep_animation_is_running()) watch_start_sleep_animation(500);
sprintf(buf, "%s%2d%2d%02d ", watch_utility_get_weekday(date_time), date_time.unit.day, date_time.unit.hour, date_time.unit.minute);
} else {
sprintf(buf, "%s%2d%2d%02d%02d", watch_utility_get_weekday(date_time), date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);

View File

@ -57,7 +57,7 @@ void simple_clock_bin_led_face_setup(uint8_t watch_face_index, void ** context_p
void simple_clock_bin_led_face_activate(void *context) {
simple_clock_bin_led_state_t *state = (simple_clock_bin_led_state_t *)context;
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
if (movement_clock_mode_24h()) watch_set_indicator(WATCH_INDICATOR_24H);
@ -160,7 +160,7 @@ bool simple_clock_bin_led_face_loop(movement_event_t event, void *context) {
}
pos = 0;
if (event.event_type == EVENT_LOW_ENERGY_UPDATE) {
if (!watch_tick_animation_is_running()) watch_start_tick_animation(500);
if (!watch_sleep_animation_is_running()) watch_start_sleep_animation(500);
sprintf(buf, "%s%2d%2d%02d ", watch_utility_get_weekday(date_time), date_time.unit.day, date_time.unit.hour, date_time.unit.minute);
} else {
sprintf(buf, "%s%2d%2d%02d%02d", watch_utility_get_weekday(date_time), date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);

View File

@ -47,7 +47,7 @@ void weeknumber_clock_face_setup(uint8_t watch_face_index, void ** context_ptr)
void weeknumber_clock_face_activate(void *context) {
weeknumber_clock_state_t *state = (weeknumber_clock_state_t *)context;
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
if (movement_clock_mode_24h()) watch_set_indicator(WATCH_INDICATOR_24H);
@ -111,7 +111,7 @@ bool weeknumber_clock_face_loop(movement_event_t event, void *context) {
}
pos = 0;
if (event.event_type == EVENT_LOW_ENERGY_UPDATE) {
if (!watch_tick_animation_is_running()) watch_start_tick_animation(500);
if (!watch_sleep_animation_is_running()) watch_start_sleep_animation(500);
sprintf(buf, "%s%2d%2d%02d ", watch_utility_get_weekday(date_time), date_time.unit.day, date_time.unit.hour, date_time.unit.minute);
} else {
sprintf(buf, "%s%2d%2d%02d%02d", watch_utility_get_weekday(date_time), date_time.unit.day, date_time.unit.hour, date_time.unit.minute, watch_utility_get_weeknumber(date_time.unit.year, date_time.unit.month, date_time.unit.day));

View File

@ -139,8 +139,8 @@ void world_clock2_face_activate(void *context)
{
world_clock2_state_t *state = (world_clock2_state_t *) context;
if (watch_tick_animation_is_running())
watch_stop_tick_animation();
if (watch_sleep_animation_is_running())
watch_stop_sleep_animation();
switch (state->current_mode) {
case WORLD_CLOCK2_MODE_DISPLAY:
@ -210,8 +210,8 @@ static bool mode_display(movement_event_t event, world_clock2_state_t *state)
pos = 0;
if (event.event_type == EVENT_LOW_ENERGY_UPDATE) {
if (!watch_tick_animation_is_running())
watch_start_tick_animation(500);
if (!watch_sleep_animation_is_running())
watch_start_sleep_animation(500);
sprintf(buf, "%.2s%2d%2d%02d ",
zone_names[state->current_zone],

View File

@ -697,7 +697,7 @@ bool activity_face_loop(movement_event_t event, void *context) {
}
else {
_activity_update_logging_screen(state);
watch_start_tick_animation(500);
watch_start_sleep_animation(500);
}
break;
default:

View File

@ -228,7 +228,7 @@ bool couch_to_5k_face_loop(movement_event_t event,
// fast-updating values like seconds, since the display won't
// update again for 60 seconds. You should also consider starting
// the tick animation, to show the wearer that this is sleep mode:
// watch_start_tick_animation(500);
// watch_start_sleep_animation(500);
break;
default:
// Movement's default loop handler will step in for any cases you

View File

@ -324,8 +324,8 @@ bool menstrual_cycle_face_loop(movement_event_t event, void *context) {
state->current_page = current_page;
state->days_prev_period = 0;
watch_clear_indicator(WATCH_INDICATOR_BELL);
if (watch_tick_animation_is_running())
watch_stop_tick_animation();
if (watch_sleep_animation_is_running())
watch_stop_sleep_animation();
break;
case EVENT_ALARM_LONG_PRESS:
switch (current_page) {
@ -445,8 +445,8 @@ bool menstrual_cycle_face_loop(movement_event_t event, void *context) {
break;
case first_period:
if (state->dates.reg) {
if (!watch_tick_animation_is_running())
watch_start_tick_animation(500); // Tracking activated
if (!watch_sleep_animation_is_running())
watch_start_sleep_animation(500); // Tracking activated
}
else if (event.subsecond % 5) { // blink active for 3 quarter-seconds
sprintf(buf, "%2d", state->days_prev_period);

View File

@ -151,7 +151,7 @@ bool moon_phase_face_loop(movement_event_t event, void *context) {
state->offset = 0;
// finally: clear out the last two digits and replace them with the sleep mode indicator
watch_display_string(" ", 8);
if (!watch_tick_animation_is_running()) watch_start_tick_animation(1000);
if (!watch_sleep_animation_is_running()) watch_start_sleep_animation(1000);
break;
case EVENT_ALARM_BUTTON_UP:
// Pressing the alarm adds an offset of one day to the displayed value,

View File

@ -483,7 +483,7 @@ bool periodic_face_loop(movement_event_t event, void *context)
case EVENT_LOW_ENERGY_UPDATE:
// Display static title and tick animation during LE
watch_display_string("Pd Table", 0);
watch_start_tick_animation(500);
watch_start_sleep_animation(500);
break;
default:
return movement_default_loop_handler(event);

View File

@ -343,7 +343,7 @@ void planetary_hours_face_setup(uint8_t watch_face_index, void ** context_ptr) {
}
void planetary_hours_face_activate(void *context) {
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
#if __EMSCRIPTEN__
int16_t browser_lat = EM_ASM_INT({ return lat; });

View File

@ -279,7 +279,7 @@ void planetary_time_face_setup(uint8_t watch_face_index, void ** context_ptr) {
}
void planetary_time_face_activate(void *context) {
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
#if __EMSCRIPTEN__
int16_t browser_lat = EM_ASM_INT({ return lat; });
@ -319,7 +319,7 @@ bool planetary_time_face_loop(movement_event_t event, void *context) {
state->day_ruler = !state->day_ruler;
break;
case EVENT_LOW_ENERGY_UPDATE:
watch_start_tick_animation(500);
watch_start_sleep_animation(500);
break;
default:
return movement_default_loop_handler(event);

View File

@ -168,7 +168,7 @@ bool randonaut_face_loop(movement_event_t event, void *context) {
// If you did not resign in EVENT_TIMEOUT, you can use this event to update the display once a minute.
// Avoid displaying fast-updating values like seconds, since the display won't update again for 60 seconds.
// You should also consider starting the tick animation, to show the wearer that this is sleep mode:
// watch_start_tick_animation(500);
// watch_start_sleep_animation(500);
break;
default:
// Movement's default loop handler will step in for any cases you don't handle above:

View File

@ -77,7 +77,7 @@ static void _stopwatch_face_update_display(stopwatch_state_t *stopwatch_state, b
}
void stopwatch_face_activate(void *context) {
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
stopwatch_state_t *stopwatch_state = (stopwatch_state_t *)context;
if (stopwatch_state->running) {
@ -143,7 +143,7 @@ bool stopwatch_face_loop(movement_event_t event, void *context) {
// explicitly ignore the timeout event so we stay on screen
break;
case EVENT_LOW_ENERGY_UPDATE:
if (!watch_tick_animation_is_running()) watch_start_tick_animation(1000);
if (!watch_sleep_animation_is_running()) watch_start_sleep_animation(1000);
if (!stopwatch_state->running) {
// since the tick animation is running, displaying the stopped time could be misleading,
// as it could imply that the stopwatch is running. instead, show a blank display to

View File

@ -300,7 +300,7 @@ void sunrise_sunset_face_setup(uint8_t watch_face_index, void ** context_ptr) {
}
void sunrise_sunset_face_activate(void *context) {
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
#if __EMSCRIPTEN__
int16_t browser_lat = EM_ASM_INT({
@ -335,7 +335,7 @@ bool sunrise_sunset_face_loop(movement_event_t event, void *context) {
case EVENT_TICK:
if (state->page == 0) {
// if entering low energy mode, start tick animation
if (event.event_type == EVENT_LOW_ENERGY_UPDATE && !watch_tick_animation_is_running()) watch_start_tick_animation(1000);
if (event.event_type == EVENT_LOW_ENERGY_UPDATE && !watch_sleep_animation_is_running()) watch_start_sleep_animation(1000);
// check if we need to update the display
watch_date_time date_time = watch_rtc_get_date_time();
if (date_time.reg >= state->rise_set_expires.reg) {

View File

@ -245,7 +245,7 @@ bool tachymeter_face_loop(movement_event_t event, void *context) {
// If you did not resign in EVENT_TIMEOUT, you can use this event to update the display once a minute.
// Avoid displaying fast-updating values like seconds, since the display won't update again for 60 seconds.
// You should also consider starting the tick animation, to show the wearer that this is sleep mode:
// watch_start_tick_animation(500);
// watch_start_sleep_animation(500);
break;
case EVENT_LIGHT_BUTTON_DOWN:
// don't light up every time light is hit

View File

@ -58,7 +58,7 @@ void wareki_activate(void *context) {
wareki_state_t *state = (wareki_state_t *)context;
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
state->active = false;
@ -198,7 +198,7 @@ bool wareki_loop(movement_event_t event, void *context) {
// If you did not resign in EVENT_TIMEOUT, you can use this event to update the display once a minute.
// Avoid displaying fast-updating values like seconds, since the display won't update again for 60 seconds.
// You should also consider starting the tick animation, to show the wearer that this is sleep mode:
// watch_start_tick_animation(500);
// watch_start_sleep_animation(500);
//break;
default:
// Movement's default loop handler will step in for any cases you don't handle above:

View File

@ -117,7 +117,7 @@ bool frequency_correction_face_loop(movement_event_t event, void *context) {
case EVENT_TIMEOUT:
break;
case EVENT_LOW_ENERGY_UPDATE:
watch_start_tick_animation(500);
watch_start_sleep_animation(500);
break;
default:
movement_default_loop_handler(event);

View File

@ -66,9 +66,9 @@ bool voltage_face_loop(movement_event_t event, void *context) {
break;
case EVENT_LOW_ENERGY_UPDATE:
// clear seconds area and start tick animation if necessary
if (!watch_tick_animation_is_running()) {
if (!watch_sleep_animation_is_running()) {
watch_display_string(" ", 8);
watch_start_tick_animation(1000);
watch_start_sleep_animation(1000);
}
// update once an hour
if (date_time.unit.minute == 0) {

View File

@ -128,11 +128,11 @@ bool alarm_thermometer_face_loop(movement_event_t event, void *context) {
}
break;
case EVENT_LOW_ENERGY_UPDATE:
if (!watch_tick_animation_is_running()) {
if (!watch_sleep_animation_is_running()) {
state->mode = MODE_NORMAL;
watch_clear_indicator(WATCH_INDICATOR_BELL);
watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
watch_start_tick_animation(1000);
watch_start_sleep_animation(1000);
}
if (watch_rtc_get_date_time().unit.minute % 5 == 0) {
_alarm_thermometer_face_update(movement_use_imperial_units());

View File

@ -76,9 +76,9 @@ bool thermistor_readout_face_loop(movement_event_t event, void *context) {
break;
case EVENT_LOW_ENERGY_UPDATE:
// clear seconds area and start tick animation if necessary
if (!watch_tick_animation_is_running()) {
if (!watch_sleep_animation_is_running()) {
watch_display_string(" ", 8);
watch_start_tick_animation(1000);
watch_start_sleep_animation(1000);
}
// update every 5 minutes
if (date_time.unit.minute % 5 == 0) {

View File

@ -217,7 +217,7 @@ bool finetune_face_loop(movement_event_t event, void *context) {
// If you did not resign in EVENT_TIMEOUT, you can use this event to update the display once a minute.
// Avoid displaying fast-updating values like seconds, since the display won't update again for 60 seconds.
// You should also consider starting the tick animation, to show the wearer that this is sleep mode:
// watch_start_tick_animation(500);
// watch_start_sleep_animation(500);
break;
case EVENT_LIGHT_BUTTON_DOWN:

View File

@ -318,7 +318,7 @@ bool nanosec_face_loop(movement_event_t event, void *context) {
// If you did not resign in EVENT_TIMEOUT, you can use this event to update the display once a minute.
// Avoid displaying fast-updating values like seconds, since the display won't update again for 60 seconds.
// You should also consider starting the tick animation, to show the wearer that this is sleep mode:
// watch_start_tick_animation(500);
// watch_start_sleep_animation(500);
break;
case EVENT_BACKGROUND_TASK:
// Here we measure temperature and do main frequency correction

View File

@ -72,7 +72,7 @@ bool beats_face_loop(movement_event_t event, void *context) {
watch_display_text(WATCH_POSITION_BOTTOM, buf);
break;
case EVENT_LOW_ENERGY_UPDATE:
if (!watch_tick_animation_is_running()) watch_start_tick_animation(432);
if (!watch_sleep_animation_is_running()) watch_start_sleep_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, "%4lu ", centibeats / 100);

View File

@ -199,14 +199,14 @@ static void clock_display_low_energy(watch_date_time date_time) {
}
static void clock_start_tick_tock_animation(void) {
if (!watch_tick_animation_is_running()) {
watch_start_tick_animation(500);
if (!watch_sleep_animation_is_running()) {
watch_start_sleep_animation(500);
}
}
static void clock_stop_tick_tock_animation(void) {
if (watch_tick_animation_is_running()) {
watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) {
watch_stop_sleep_animation();
}
}

View File

@ -48,7 +48,7 @@ void simple_clock_face_setup(uint8_t watch_face_index, void ** context_ptr) {
void simple_clock_face_activate(void *context) {
simple_clock_state_t *state = (simple_clock_state_t *)context;
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
if (movement_clock_mode_24h()) watch_set_indicator(WATCH_INDICATOR_24H);
@ -122,7 +122,7 @@ bool simple_clock_face_loop(movement_event_t event, void *context) {
watch_display_text(WATCH_POSITION_MINUTES, buf + 4);
if (event.event_type == EVENT_LOW_ENERGY_UPDATE) {
watch_display_character(' ', 9);
if (!watch_tick_animation_is_running()) watch_start_tick_animation(500);
if (!watch_sleep_animation_is_running()) watch_start_sleep_animation(500);
} else {
watch_display_text(WATCH_POSITION_SECONDS, buf + 6);
}

View File

@ -56,7 +56,7 @@ void world_clock_face_activate(void *context) {
state->current_screen = 0;
_update_timezone_offset(state);
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
if (watch_sleep_animation_is_running()) watch_stop_sleep_animation();
}
static bool world_clock_face_do_display_mode(movement_event_t event, world_clock_state_t *state) {
@ -108,7 +108,7 @@ static bool world_clock_face_do_display_mode(movement_event_t event, world_clock
watch_display_text(WATCH_POSITION_HOURS, buf + 2);
watch_display_text(WATCH_POSITION_MINUTES, buf + 4);
if (event.event_type == EVENT_LOW_ENERGY_UPDATE) {
if (!watch_tick_animation_is_running()) watch_start_tick_animation(500);
if (!watch_sleep_animation_is_running()) watch_start_sleep_animation(500);
} else {
watch_display_text(WATCH_POSITION_SECONDS, buf + 6);
}

View File

@ -116,7 +116,7 @@ void watch_stop_blink(void) {
slcd_set_blink_enabled(false);
}
void watch_start_tick_animation(uint32_t duration) {
void watch_start_sleep_animation(uint32_t duration) {
#ifdef USE_CUSTOM_LCD
(void) duration;
watch_set_indicator(WATCH_INDICATOR_SLEEP);
@ -140,12 +140,12 @@ void watch_start_tick_animation(uint32_t duration) {
#endif
}
bool watch_tick_animation_is_running(void) {
bool watch_sleep_animation_is_running(void) {
// TODO: wrap this in gossamer call
return SLCD->CTRLD.bit.CSREN;
}
void watch_stop_tick_animation(void) {
void watch_stop_sleep_animation(void) {
#ifdef USE_CUSTOM_LCD
watch_clear_indicator(WATCH_INDICATOR_SLEEP);
#else

View File

@ -219,15 +219,15 @@ void watch_stop_blink(void);
* Sleep mode, since that mode turns off the LCD).
* @param duration The duration of each frame in ms. 500 milliseconds produces a classic tick/tock.
*/
void watch_start_tick_animation(uint32_t duration);
void watch_start_sleep_animation(uint32_t duration);
/** @brief Checks if the tick animation is currently running.
* @return true if the animation is running; false otherwise.
*/
bool watch_tick_animation_is_running(void);
bool watch_sleep_animation_is_running(void);
/** @brief Stops the tick/tock animation and clears all animating segments.
* @details This will stop the animation and clear all segments in position 8.
*/
void watch_stop_tick_animation(void);
void watch_stop_sleep_animation(void);
/// @}

View File

@ -96,7 +96,7 @@ static void watch_invoke_tick_callback(void *userData) {
}
}
void watch_start_tick_animation(uint32_t duration) {
void watch_start_sleep_animation(uint32_t duration) {
if (tick_interval_id != -1) return;
watch_display_character(' ', 8);
@ -104,11 +104,11 @@ void watch_start_tick_animation(uint32_t duration) {
tick_interval_id = emscripten_set_interval(watch_invoke_tick_callback, (double)duration, NULL);
}
bool watch_tick_animation_is_running(void) {
bool watch_sleep_animation_is_running(void) {
return tick_interval_id != -1;
}
void watch_stop_tick_animation(void) {
void watch_stop_sleep_animation(void) {
emscripten_clear_timeout(tick_interval_id);
tick_interval_id = -1;
tick_state = false;