132 lines
3.1 KiB
C++
132 lines
3.1 KiB
C++
#include "game_timer.h"
|
|
#include <esp_log.h>
|
|
|
|
static const char* TAG = "game_timer";
|
|
|
|
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);
|
|
|
|
void init_game_timers() {
|
|
ESP_LOGI(TAG, "Initializing game timers...");
|
|
|
|
xTaskCreate(game_timer_task, "game_timers", 4096, NULL, 10, NULL);
|
|
|
|
ESP_LOGI(TAG, "Game timers initialized!");
|
|
}
|
|
|
|
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 start_game_timer() {
|
|
is_game_playing = true;
|
|
}
|
|
|
|
void stop_game_timer() {
|
|
is_game_playing = false;
|
|
}
|
|
|
|
void start_module_timer() {
|
|
is_module_playing = true;
|
|
}
|
|
|
|
void stop_module_timer() {
|
|
is_module_playing = false;
|
|
}
|
|
|
|
void set_game_time(int32_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);
|
|
}
|
|
|
|
int32_t get_game_time() {
|
|
if (game_time_count_up) {
|
|
return -((int32_t) game_time_left);
|
|
} else {
|
|
return ((int32_t) 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;
|
|
}
|