blk_box_tc/main/drivers/game_timer.cpp

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;
}