#include "game_timer.h" static bool is_module_playing; static bool is_game_playing; static bool game_time_count_up; // in ms static uint32_t game_time_left; static uint32_t module_time_left; static void game_timer_task(void *arg); static uint32_t sat_sub(uint32_t x, uint32_t y); static void write_game_time(uint32_t millis) { if (millis > 60'000) { int disp_time = (millis / 60'000) * 100; disp_time = disp_time + ((millis % 60'000) / 1'000); set_game_sseg_num(disp_time, 2); } else { set_game_sseg_num(millis / 100, 1); } } static void write_module_time(uint32_t millis) { if (millis > 60'000) { int disp_time = (millis / 60'000) * 100; disp_time = disp_time + ((millis % 60'000) / 1'000); set_module_sseg_num(disp_time, 2); } else { set_module_sseg_num(millis / 100, 1); } } void init_game_module_timer(void) { xTaskCreate(game_timer_task, "game_module_timer", 4096, NULL, 10, NULL); } void start_game_timer(void) { is_game_playing = true; } void stop_game_timer(void) { is_game_playing = false; } void start_module_timer(void) { is_module_playing = true; } void stop_module_timer(void) { is_module_playing = false; } void set_game_time(uint32_t new_time) { if (new_time > 0) { game_time_count_up = false; game_time_left = new_time; } else { game_time_count_up = true; game_time_left = -new_time; } write_game_time(game_time_left); } uint32_t get_game_time() { return game_time_left; } void set_module_time(uint32_t new_time) { module_time_left = new_time; write_module_time(module_time_left); } uint32_t get_module_time() { return module_time_left; } /// Issues a time penalty to the game time void time_penalty(uint32_t penalty) { if (game_time_count_up) { game_time_left += penalty; } else { game_time_left = sat_sub(game_time_left, penalty); if (game_time_left == 0) { game_time_count_up = true; } } } static void game_timer_task(void *arg) { TickType_t lastWakeTime = xTaskGetTickCount(); const uint32_t frequency = 100; while (1) { vTaskDelayUntil( &lastWakeTime, pdMS_TO_TICKS(frequency)); if (is_game_playing) { if (game_time_count_up) { game_time_left += frequency; } else { game_time_left = sat_sub(game_time_left, frequency); if (game_time_left == 0) { game_time_count_up = true; } } write_game_time(game_time_left); } if (is_module_playing) { module_time_left = sat_sub(module_time_left, frequency); write_module_time(module_time_left); } } vTaskDelete(NULL); } static uint32_t sat_sub(uint32_t x, uint32_t y) { uint32_t res = x - y; res &= -(res <= x); return res; }