finish up tetris and fix step1

This commit is contained in:
Mitchell Marino 2024-08-10 14:18:57 -05:00
parent a0de2ccd04
commit e75e7465fb
10 changed files with 215 additions and 91 deletions

View File

@ -31,7 +31,9 @@ static bool _take_key(KeypadKey* kp, uint16_t* keypad_bitfield) {
for (int i = 0; i < 16; i++) {
int bit_selector = (1 << i);
if ((*keypad_bitfield) & bit_selector) {
if (kp != nullptr) {
*kp = (KeypadKey) i;
}
// clear bit
*keypad_bitfield &= ~bit_selector;
return true;
@ -90,7 +92,9 @@ static bool _take_button(ButtonKey* button, uint16_t* button_bitfield) {
for (int i = 0; i < 4; i++) {
int bit_selector = (1 << (i+8));
if ((*button_bitfield) & bit_selector) {
if (button != nullptr) {
*button = (ButtonKey) i;
}
// clear bit
*button_bitfield &= ~bit_selector;
return true;
@ -102,7 +106,9 @@ static bool _take_switch(SwitchKey* switch_, uint16_t* button_bitfield) {
for (int i = 0; i < 4; i++) {
int bit_selector = (1 << i);
if ((*button_bitfield) & bit_selector) {
if (switch_ != nullptr) {
*switch_ = (SwitchKey) i;
}
// clear bit
*button_bitfield &= ~bit_selector;
return true;
@ -132,7 +138,9 @@ bool get_flipped_switch(SwitchKey* switch_) {
for (int i = 0; i < 4; i++) {
int bit_selector = (1 << (i+4));
if (button_pressed & bit_selector || button_released & bit_selector) {
if (switch_ != nullptr) {
*switch_ = (SwitchKey) i;
}
// clear bit
button_pressed &= ~bit_selector;
button_released &= ~bit_selector;

View File

@ -58,13 +58,25 @@ static void game_timer_task(void *arg)
vTaskDelayUntil( &lastWakeTime, pdMS_TO_TICKS(frequency));
if (is_game_playing) {
game_time_left = sat_sub(game_time_left, frequency);
if (game_time_left > 60'000) {
int disp_time = (game_time_left / 60'000) * 100;
disp_time = disp_time + ((game_time_left % 60'000) / 1'000);
set_game_sseg_num(disp_time, 2);
} else {
set_game_sseg_num(game_time_left / 100, 1);
}
}
if (is_module_playing) {
module_time_left = sat_sub(module_time_left, frequency);
if (module_time_left > 60'000) {
int disp_time = (module_time_left / 60'000) * 100;
disp_time = disp_time + ((module_time_left % 60'000) / 1'000);
set_module_sseg_num(disp_time, 2);
} else {
set_module_sseg_num(module_time_left / 100, 1);
}
}
}
vTaskDelete(NULL);
}

View File

@ -12,7 +12,7 @@ void clean_bomb(void) {
// clear module timer
stop_module_timer();
set_module_time(0);
uint8_t clear[] = {0};
uint8_t clear[4] = {0};
set_module_sseg_raw(clear);
// clear char lcd
@ -31,3 +31,74 @@ void poster_child_task(void* arg) {
vTaskDelete(NULL);
}
static const int STRING_MAX_LEN = 8;
void do_star_codes(StarCodeHandler* star_codes, int star_codes_len) {
KeypadKey key;
int current_idx = 0;
char current[STRING_MAX_LEN+1] = {0};
while (1) {
while (get_pressed_keypad(&key)) {
if (key == KeypadKey::star) {
current[0] = '*';
for (int i = 1; i < STRING_MAX_LEN; i++) {
current[i] = 0;
}
current_idx = 1;
} else if (key == KeypadKey::pound) {
// submit
if (current[0] == '\0') {
continue;
}
bool hit = false;
for (int i = 0; i < star_codes_len; i++) {
StarCodeHandler sch = star_codes[i];
if (strcmp(current, sch.code) == 0) {
hit = true;
lcd_set_cursor(&lcd, 1, 2);
lcd_print(&lcd, sch.display_text);
vTaskDelay(pdMS_TO_TICKS(2000));
if (sch.callback != nullptr) {
(sch.callback)();
}
if (sch.should_exit) {
return;
}
break;
}
}
if (!hit) {
lcd_set_cursor(&lcd, 1, 2);
lcd_print(&lcd, "Invalid Star Code");
vTaskDelay(pdMS_TO_TICKS(2000));
}
// clear
for (int i = 0; i < STRING_MAX_LEN; i++) {
current[i] = 0;
}
current_idx = 0;
} else {
// out of room. skip
if (current_idx >= STRING_MAX_LEN) break;
// no code started.
if (current[0] != '*') continue;
char c = char_of_keypad_key(key);
current[current_idx++] = c;
}
// ESP_LOGI(STEP0_TAG, "Pressed: %c", c);
lcd_clear(&lcd);
lcd_set_cursor(&lcd, 1, 1);
lcd_print(&lcd, current);
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}

View File

@ -9,8 +9,16 @@
#include "drivers/leds.h"
#include "drivers/speaker.h"
struct StarCodeHandler {
char* code;
char* display_text;
bool should_exit;
void (*callback)(void);
};
/// Clears most persistant bomb state
void clean_bomb(void);
void poster_child_task(void* arg);
void do_star_codes(StarCodeHandler* star_codes, int star_codes_len);
#endif /* HELPER_H */

View File

@ -40,10 +40,9 @@ extern "C" void app_main(void) {
init_bottom_half();
init_char_lcd();
// create_demo_ui();
clean_bomb();
step0();
set_game_time(1200000);
set_game_time(30*60*1000 + 1000);
start_game_timer();
clean_bomb();
step1();
@ -62,13 +61,5 @@ extern "C" void app_main(void) {
stop_game_timer();
ESP_LOGI(TAG, "Bomb has been diffused. Counter-Terrorists win.");
ESP_ERROR_CHECK_WITHOUT_ABORT(play_raw("/sdcard/diffused.pcm"));
// play_example();
// deinit_sd();
// set_game_timer(1234, 1);
// set_module_timer(5678, 2);
}

View File

@ -4,62 +4,20 @@ static const char* TAG = "step0";
/// Wait for "*9819"
void step0(void) {
KeypadKey key;
int current_idx = 0;
char current[STRING_MAX_LEN+1] = {0};
while (1) {
while (get_pressed_keypad(&key)) {
if (key == KeypadKey::star) {
current[0] = '*';
for (int i = 1; i < STRING_MAX_LEN; i++) {
current[i] = 0;
}
current_idx = 1;
} else if (key == KeypadKey::pound) {
// submit
if (current[0] == '\0') {
// do nothing
} else if (strcmp(current, "*9819") == 0) {
lcd_set_cursor(&lcd, 1, 2);
lcd_print(&lcd, "Diffusal Initated");
vTaskDelay(pdMS_TO_TICKS(2000));
lcd_clear(&lcd);
return;
} else if (strcmp(current, "*59861") == 0) {
lcd_set_cursor(&lcd, 1, 2);
lcd_print(&lcd, "Set Up Wires");
vTaskDelay(pdMS_TO_TICKS(2000));
setup_wires();
} else {
lcd_set_cursor(&lcd, 1, 2);
lcd_print(&lcd, "Invalid Star Code");
strike("Invalid Star Code");
vTaskDelay(pdMS_TO_TICKS(2000));
}
// clear
for (int i = 0; i < STRING_MAX_LEN; i++) {
current[i] = 0;
}
current_idx = 0;
} else {
// out of room. skip
if (current_idx >= STRING_MAX_LEN) break;
// no code started.
if (current[0] != '*') continue;
char c = char_of_keypad_key(key);
current[current_idx++] = c;
}
// ESP_LOGI(STEP0_TAG, "Pressed: %c", c);
lcd_clear(&lcd);
lcd_set_cursor(&lcd, 1, 1);
lcd_print(&lcd, current);
}
vTaskDelay(pdMS_TO_TICKS(10));
}
StarCodeHandler star_codes[] = {
{
.code = "*9819",
.display_text = "Diffusal Initiated",
.should_exit = true,
.callback = nullptr,
},
{
.code = "*59861",
.display_text = "Set Up Wires",
.should_exit = false,
.callback = setup_wires,
},
};
int len = sizeof(star_codes)/sizeof(StarCodeHandler);
do_star_codes(star_codes, len);
}

View File

@ -5,6 +5,7 @@
#include "../drivers/char_lcd.h"
#include "../drivers/wires.h"
#include "setup_wires.h"
#include "../helper.h"
#define STRING_MAX_LEN 8

View File

@ -176,9 +176,9 @@ static int generate_part_c(void) {
return text_color + 4;
}
static void part_a(void) {
static bool part_a(void) {
stop_module_timer();
set_module_time(30);
set_module_time(30*1000);
lcd_clear(&lcd);
lcd_set_cursor(&lcd, 1, 1);
@ -206,6 +206,10 @@ static void part_a(void) {
while (get_flipped_switch(&switch_)) {
strike("Incorrect color action");
}
if (get_module_time() <= 0) {
strike("Out of time");
return false;
}
vTaskDelay(pdMS_TO_TICKS(10));
}
@ -217,11 +221,12 @@ static void part_a(void) {
}
vTaskDelay(pdMS_TO_TICKS(80));
play_raw(MOUNT_POINT "/correct.pcm");
return true;
}
static void part_b(void) {
static bool part_b(void) {
stop_module_timer();
set_module_time(25);
set_module_time(25*1000);
lcd_clear(&lcd);
lcd_set_cursor(&lcd, 1, 1);
@ -249,6 +254,10 @@ static void part_b(void) {
while (get_flipped_switch(&switch_)) {
strike("Incorrect color action");
}
if (get_module_time() <= 0) {
strike("Out of time");
return false;
}
vTaskDelay(pdMS_TO_TICKS(10));
}
@ -259,11 +268,12 @@ static void part_b(void) {
}
vTaskDelay(pdMS_TO_TICKS(80));
play_raw(MOUNT_POINT "/correct.pcm");
return true;
}
static void part_c(void) {
static bool part_c(void) {
stop_module_timer();
set_module_time(20);
set_module_time(20*1000);
lcd_clear(&lcd);
lcd_set_cursor(&lcd, 1, 1);
@ -292,12 +302,16 @@ static void part_c(void) {
start_module_timer();
if (switch_leds[(int)(switch_)] + 4 == correct) {
times++;
if (times >= 10) break;
if (times >= 15) break;
correct = generate_part_c();
} else {
strike("Incorrect color action");
}
}
if (get_module_time() <= 0) {
strike("Out of time");
return false;
}
vTaskDelay(pdMS_TO_TICKS(10));
}
@ -308,16 +322,17 @@ static void part_c(void) {
}
vTaskDelay(pdMS_TO_TICKS(80));
play_raw(MOUNT_POINT "/correct.pcm");
return true;
}
void step1(void) {
SwitchKey switch_;
while (get_flipped_switch(&switch_));
while (get_flipped_switch(nullptr));
init_step();
part_a();
part_b();
part_c();
while (!part_a());
while (!part_b());
while (!part_c());
clean_up_step();
// TODO: flash lights
}

View File

@ -16,6 +16,8 @@ static int board[height][width] = {0};
static lv_obj_t* visual_board[height][width] = {0};
static lv_obj_t* line_clear_img;
static lv_style_t game_over_style;
static lv_obj_t* game_over_label;
static const void* LINE_CLEAR_SRC = (void*)"A:/sdcard/clear.bin";
static const void* BACKGROUND_SRC = (void*)"A:/sdcard/bg.bin";
@ -140,6 +142,17 @@ static void init_screen(void) {
lv_img_set_src(line_clear_img, LINE_CLEAR_SRC);
lv_obj_align(line_clear_img, LV_ALIGN_BOTTOM_LEFT, 159, -(height*16));
lv_style_init(&game_over_style);
lv_style_set_text_color(&game_over_style, lv_color_white());
lv_style_set_bg_color(&game_over_style, lv_color_black());
lv_style_set_bg_opa(&game_over_style, LV_OPA_100);
lv_style_set_text_align(&game_over_style, LV_TEXT_ALIGN_CENTER);
game_over_label = lv_label_create(lv_scr_act());
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
lv_obj_align(game_over_label, LV_ALIGN_CENTER, 0, 0);
lv_obj_add_style(game_over_label, &game_over_style, LV_STATE_DEFAULT);
// for (int h = 0; h < height; h++) {
// for (int w = 0; w < width; w++) {
// visual_board[h][w] = lv_img_create(lv_scr_act());
@ -172,7 +185,6 @@ bool play_game(int time, int required_score) {
score = 0;
update_score();
set_module_time(time);
vTaskDelay(1000);
start_module_timer();
clear_board();
@ -180,6 +192,7 @@ bool play_game(int time, int required_score) {
generate_block();
ButtonKey button;
while (get_pressed_button(&button));
// SwitchKey switch_;
while(game) {
@ -231,12 +244,58 @@ bool play_game(int time, int required_score) {
return false;
}
static void complete(void) {
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
lv_label_set_text(game_over_label, "Winner!\nPress any button to continue");
lv_obj_clear_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
xSemaphoreGive(xGuiSemaphore);
}
vTaskDelay(pdMS_TO_TICKS(500));
while (get_pressed_button(nullptr));
while (1) {
if (get_pressed_button(nullptr)) break;
vTaskDelay(pdMS_TO_TICKS(10));
}
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
xSemaphoreGive(xGuiSemaphore);
}
}
static void fail(void) {
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
lv_label_set_text(game_over_label, "Game Over\nPress any button to continue");
lv_obj_clear_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
xSemaphoreGive(xGuiSemaphore);
}
vTaskDelay(pdMS_TO_TICKS(500));
while (get_pressed_button(nullptr));
while (1) {
if (get_pressed_button(nullptr)) break;
vTaskDelay(pdMS_TO_TICKS(10));
}
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
xSemaphoreGive(xGuiSemaphore);
}
}
void step2(void) {
StarCodeHandler star_code = {
.code = "*3850",
.display_text = "Starting...",
.should_exit = true,
.callback = nullptr,
};
do_star_codes(&star_code, 1);
init_screen();
while (!play_game(60000, 4)) vTaskDelay(2000);
while (!play_game(60000, 8)) vTaskDelay(2000);
while (!play_game(120000, 16)) vTaskDelay(2000);
while (!play_game(4*60*1000, 2)) fail();
complete();
while (!play_game(4*60*1000, 4)) fail();
complete();
while (!play_game(8*60*1000, 8)) fail();
complete();
deinit_screen();
}

View File

@ -8,6 +8,7 @@
#include "../drivers/game_timer.h"
#include "../drivers/wires.h"
#include "../drivers/char_lcd.h"
#include "../helper.h"
// TODO:
// - [ ] set up real game loop