419 lines
13 KiB
C++
419 lines
13 KiB
C++
#include "step0.h"
|
|
#include "drivers/state_tracking.h"
|
|
|
|
static const char* TAG = "step0";
|
|
|
|
extern uint32_t initial_game_time;
|
|
extern uint32_t skip_to_step;
|
|
|
|
static void set_game_time();
|
|
static void skip_to_step1() { skip_to_step = 1; }
|
|
static void skip_to_step2() { skip_to_step = 2; }
|
|
static void skip_to_step3() { skip_to_step = 3; }
|
|
static void skip_to_step4() { skip_to_step = 4; }
|
|
static void skip_to_step5() { skip_to_step = 5; }
|
|
static void skip_to_step6() { skip_to_step = 6; }
|
|
static void try_step1() { clean_bomb(); step1(); }
|
|
static void try_step2() { clean_bomb(); step2(); }
|
|
static void try_step3() { clean_bomb(); step3(); }
|
|
static void try_step4() { clean_bomb(); step4(); }
|
|
static void try_step5() { clean_bomb(); step5(); }
|
|
static void try_step6() { clean_bomb(); step6(); }
|
|
static void issue_strike() { strike("Strike Issued"); }
|
|
static void flashbang();
|
|
static void debug_switches();
|
|
static void battery_stats() {
|
|
BaseType_t xReturned;
|
|
TaskHandle_t xHandle = NULL;
|
|
xReturned = xTaskCreate(bat_monitor_task, "bat_monitor", 4096, NULL, 5, &xHandle);
|
|
|
|
KeypadKey k;
|
|
while (!get_keypad_pressed(&k) || k != KeypadKey::pound) vTaskDelay(pdMS_TO_TICKS(10));
|
|
|
|
if (xReturned == pdPASS) {
|
|
vTaskDelete(xHandle);
|
|
}
|
|
}
|
|
|
|
// TODO: remove. This is temperary
|
|
static void replay_last() {
|
|
FILE* record_file = fopen(MOUNT_POINT "/record.txt", "r");
|
|
if (record_file == nullptr) {
|
|
ESP_LOGE("main", "failed to open record.txt");
|
|
}
|
|
set_playback_source(record_file, true);
|
|
start_playback();
|
|
}
|
|
|
|
|
|
void step0() {
|
|
led_set(IndicatorLED::LED_SPEAKER, LEDColor::LED_COLOR_BLUE);
|
|
leds_flush();
|
|
|
|
SemaphoreHandle_t continue_sem = xSemaphoreCreateBinary();
|
|
if (continue_sem == nullptr) {
|
|
ESP_LOGE(TAG, "could not create semaphore");
|
|
return;
|
|
}
|
|
|
|
StarCodeEntry star_codes[] = {
|
|
{
|
|
.code = "9819",
|
|
.display_text = "Diffusal Initiated",
|
|
.delay_us = 2'000'000,
|
|
.callback = nullptr,
|
|
.triggered_sem = continue_sem,
|
|
},
|
|
{
|
|
.code = "59861",
|
|
.display_text = "Setup Wires",
|
|
.delay_us = 10'000'000,
|
|
.callback = setup_wires,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "59862",
|
|
.display_text = "Set Game Time",
|
|
.delay_us = 2'000'000,
|
|
.callback = set_game_time,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "59863",
|
|
.display_text = "Debug switches",
|
|
.delay_us = 2'000'000,
|
|
.callback = debug_switches,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "59864",
|
|
.display_text = "Battery Stats",
|
|
.delay_us = 2'000'000,
|
|
.callback = battery_stats,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "59871",
|
|
.display_text = "Try Step 1",
|
|
.delay_us = 2'000'000,
|
|
.callback = try_step1,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "59872",
|
|
.display_text = "Try Step 2",
|
|
.delay_us = 2'000'000,
|
|
.callback = try_step2,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "59873",
|
|
.display_text = "Try Step 3",
|
|
.delay_us = 2'000'000,
|
|
.callback = try_step3,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "59874",
|
|
.display_text = "Try Step 4",
|
|
.delay_us = 2'000'000,
|
|
.callback = try_step4,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "59875",
|
|
.display_text = "Try Step 5",
|
|
.delay_us = 2'000'000,
|
|
.callback = try_step5,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "59876",
|
|
.display_text = "Try Step 6",
|
|
.delay_us = 2'000'000,
|
|
.callback = try_step6,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "59881",
|
|
.display_text = "Skip To Step 1",
|
|
.delay_us = 2'000'000,
|
|
.callback = skip_to_step1,
|
|
.triggered_sem = continue_sem,
|
|
},
|
|
{
|
|
.code = "59882",
|
|
.display_text = "Skip To Step 2",
|
|
.delay_us = 2'000'000,
|
|
.callback = skip_to_step2,
|
|
.triggered_sem = continue_sem,
|
|
},
|
|
{
|
|
.code = "59883",
|
|
.display_text = "Skip To Step 3",
|
|
.delay_us = 2'000'000,
|
|
.callback = skip_to_step3,
|
|
.triggered_sem = continue_sem,
|
|
},
|
|
{
|
|
.code = "59884",
|
|
.display_text = "Skip To Step 4",
|
|
.delay_us = 2'000'000,
|
|
.callback = skip_to_step4,
|
|
.triggered_sem = continue_sem,
|
|
},
|
|
{
|
|
.code = "59885",
|
|
.display_text = "Skip To Step 5",
|
|
.delay_us = 2'000'000,
|
|
.callback = skip_to_step5,
|
|
.triggered_sem = continue_sem,
|
|
},
|
|
{
|
|
.code = "59886",
|
|
.display_text = "Skip To Step 6",
|
|
.delay_us = 2'000'000,
|
|
.callback = skip_to_step6,
|
|
.triggered_sem = continue_sem,
|
|
},
|
|
{
|
|
.code = "1111",
|
|
.display_text = "Issue Strike",
|
|
.delay_us = 2'000'000,
|
|
.callback = issue_strike,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "1112",
|
|
.display_text = "????",
|
|
.delay_us = 2'000'000,
|
|
.callback = flashbang,
|
|
.triggered_sem = nullptr,
|
|
},
|
|
{
|
|
.code = "1113",
|
|
.display_text = "replay",
|
|
.delay_us = 2'000'000,
|
|
.callback = replay_last,
|
|
.triggered_sem = continue_sem,
|
|
},
|
|
};
|
|
size_t len = sizeof(star_codes)/sizeof(star_codes[0]);
|
|
|
|
add_star_codes(star_codes, len);
|
|
xSemaphoreTake(continue_sem, portMAX_DELAY);
|
|
rm_star_codes(star_codes, len);
|
|
vSemaphoreDelete(continue_sem);
|
|
}
|
|
|
|
static const int CURSOR_POS_MAP[5] = {1, 3, 4, 6, 7};
|
|
static char str_buf[18] = {0};
|
|
static void _update_display(uint8_t* digits, uint8_t cursor_pos) {
|
|
sprintf(str_buf, "%d:%d%d:%d%d", digits[0], digits[1], digits[2], digits[3], digits[4]);
|
|
lcd_clear();
|
|
lcd_print(1, 1, str_buf);
|
|
cursor_pos = MAX(0, MIN(4, cursor_pos));
|
|
int mapped_cursor_pos = CURSOR_POS_MAP[cursor_pos];
|
|
// TODO: find some way to indicate without a cursor.
|
|
// lcd_set_cursor_pos(mapped_cursor_pos, 1);
|
|
}
|
|
|
|
static void set_game_time() {
|
|
uint8_t hours = (initial_game_time / (1000*60*60)) % 10;
|
|
uint8_t minutes = (initial_game_time / (1000*60)) % 60;
|
|
uint8_t seconds = (initial_game_time / (1000)) % 60;
|
|
uint8_t digits[5] = {hours, (uint8_t)(minutes / 10), (uint8_t)(minutes % 10), (uint8_t)(seconds / 10), (uint8_t)(seconds % 10)};
|
|
uint8_t cursor_pos = 0;
|
|
lcd_set_cursor_vis(true);
|
|
|
|
_update_display(digits, cursor_pos);
|
|
|
|
KeypadKey key;
|
|
ButtonKey button;
|
|
while (1) {
|
|
while (get_keypad_pressed(&key)) {
|
|
if (key == KeypadKey::star) {
|
|
digits[0] = 0;
|
|
digits[1] = 0;
|
|
digits[2] = 0;
|
|
digits[3] = 0;
|
|
digits[4] = 0;
|
|
cursor_pos = 0;
|
|
} else if (key == KeypadKey::pound) {
|
|
// submit
|
|
if (digits[0] != 0 || digits[1] != 0 || digits[2] != 0 || digits[3] != 0 || digits[4] != 0) {
|
|
uint32_t new_game_time = 0;
|
|
new_game_time += digits[0] * (1000*60*60);
|
|
new_game_time += (digits[1] * 10 + digits[2]) * (1000*60);
|
|
new_game_time += (digits[3] * 10 + digits[4]) * (1000);
|
|
initial_game_time = new_game_time;
|
|
}
|
|
|
|
clean_bomb();
|
|
led_set(IndicatorLED::LED_SPEAKER, LEDColor::LED_COLOR_BLUE);
|
|
leds_flush();
|
|
return;
|
|
} else {
|
|
int just_pressed = -1;
|
|
switch (key) {
|
|
case KeypadKey::k0:
|
|
just_pressed = 0;
|
|
break;
|
|
case KeypadKey::k1:
|
|
just_pressed = 1;
|
|
break;
|
|
case KeypadKey::k2:
|
|
just_pressed = 2;
|
|
break;
|
|
case KeypadKey::k3:
|
|
just_pressed = 3;
|
|
break;
|
|
case KeypadKey::k4:
|
|
just_pressed = 4;
|
|
break;
|
|
case KeypadKey::k5:
|
|
just_pressed = 5;
|
|
break;
|
|
case KeypadKey::k6:
|
|
just_pressed = 6;
|
|
break;
|
|
case KeypadKey::k7:
|
|
just_pressed = 7;
|
|
break;
|
|
case KeypadKey::k8:
|
|
just_pressed = 8;
|
|
break;
|
|
case KeypadKey::k9:
|
|
just_pressed = 9;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (just_pressed != -1) {
|
|
digits[cursor_pos] = just_pressed;
|
|
cursor_pos = MIN(4, cursor_pos+1);
|
|
}
|
|
}
|
|
|
|
_update_display(digits, cursor_pos);
|
|
}
|
|
|
|
while (get_button_pressed(&button)) {
|
|
if (button == ButtonKey::b1) {
|
|
cursor_pos = MAX(0, cursor_pos-1);
|
|
} else if (button == ButtonKey::b2) {
|
|
cursor_pos = MIN(4, cursor_pos+1);
|
|
}
|
|
_update_display(digits, cursor_pos);
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
}
|
|
}
|
|
|
|
|
|
static void print_4bin_rev(char* out_str, uint8_t n) {
|
|
out_str[0] = ((n & 0b0001) ? '1' : '0');
|
|
out_str[1] = ((n & 0b0010) ? '1' : '0');
|
|
out_str[2] = ((n & 0b0100) ? '1' : '0');
|
|
out_str[3] = ((n & 0b1000) ? '1' : '0');
|
|
out_str[4] = '\0';
|
|
}
|
|
|
|
static void debug_switches() {
|
|
clean_bomb();
|
|
uint8_t switch_state = 0xFF;
|
|
uint8_t switch_touch_state = 0xFF;
|
|
uint8_t button_state = 0xFF;
|
|
|
|
char bin_buf[5] = {0};
|
|
char buf[21] = {0};
|
|
|
|
KeypadKey key;
|
|
ButtonKey button;
|
|
SwitchKey switch_;
|
|
while (1) {
|
|
if (get_button_pressed(&button)) {
|
|
sprintf(buf, "Button Pressed: %d ", button);
|
|
lcd_print(3, 0, buf);
|
|
ESP_LOGI(TAG, "%s", buf);
|
|
}
|
|
if (get_button_released(&button)) {
|
|
sprintf(buf, "Button Released: %d", button);
|
|
lcd_print(3, 0, buf);
|
|
ESP_LOGI(TAG, "%s", buf);
|
|
}
|
|
if (get_switch_flipped_down(&switch_)) {
|
|
sprintf(buf, "Switch Down: %d ", switch_);
|
|
lcd_print(3, 0, buf);
|
|
ESP_LOGI(TAG, "%s", buf);
|
|
}
|
|
if (get_switch_flipped_up(&switch_)) {
|
|
sprintf(buf, "Switch Up: %d ", switch_);
|
|
lcd_print(3, 0, buf);
|
|
ESP_LOGI(TAG, "%s", buf);
|
|
}
|
|
if (get_switch_touch_pressed(&switch_)) {
|
|
sprintf(buf, "Switch Touch: %d ", switch_);
|
|
lcd_print(3, 0, buf);
|
|
ESP_LOGI(TAG, "%s", buf);
|
|
}
|
|
if (get_switch_touch_released(&switch_)) {
|
|
sprintf(buf, "Switch Un-touch: %d", switch_);
|
|
lcd_print(3, 0, buf);
|
|
ESP_LOGI(TAG, "%s", buf);
|
|
}
|
|
|
|
uint8_t new_switch_touch_state = get_switch_touch_state();
|
|
if (new_switch_touch_state != switch_touch_state) {
|
|
switch_touch_state = new_switch_touch_state;
|
|
print_4bin_rev(bin_buf, switch_touch_state);
|
|
sprintf(buf, "t: %s", bin_buf);
|
|
lcd_print(0, 1, buf);
|
|
ESP_LOGI(TAG, "%s", buf);
|
|
}
|
|
|
|
uint8_t new_switch_state = get_switch_state();
|
|
if (new_switch_state != switch_state) {
|
|
switch_state = new_switch_state;
|
|
print_4bin_rev(bin_buf, switch_state);
|
|
sprintf(buf, "s: %s", bin_buf);
|
|
lcd_print(1, 1, buf);
|
|
ESP_LOGI(TAG, "%s", buf);
|
|
}
|
|
|
|
uint8_t new_button_state = get_button_state();
|
|
if (new_button_state != button_state) {
|
|
button_state = new_button_state;
|
|
print_4bin_rev(bin_buf, button_state);
|
|
sprintf(buf, "b: %s", bin_buf);
|
|
lcd_print(2, 1, buf);
|
|
ESP_LOGI(TAG, "%s", buf);
|
|
}
|
|
|
|
|
|
if (get_keypad_pressed(&key) && key == KeypadKey::pound) {
|
|
return;
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
}
|
|
}
|
|
|
|
static void flashbang() {
|
|
play_clip_wav(MOUNT_POINT "/flash.wav", true, false, 1, 0);
|
|
vTaskDelay(pdMS_TO_TICKS(4000));
|
|
|
|
for (int bright = 255; bright >= 0; bright -= 2) {
|
|
for (int led_idx = 0; led_idx < IndicatorLED::LED_MAX; led_idx++) {
|
|
led_set(led_idx, bright, bright, bright);
|
|
}
|
|
leds_flush();
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
}
|
|
leds_clear();
|
|
leds_flush();
|
|
}
|
|
|