#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]; 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(0, 3, buf); ESP_LOGI(TAG, "%s", buf); } if (get_button_released(&button)) { sprintf(buf, "Button Released: %d", button); lcd_print(0, 3, buf); ESP_LOGI(TAG, "%s", buf); } if (get_switch_flipped_down(&switch_)) { sprintf(buf, "Switch Down: %d ", switch_); lcd_print(0, 3, buf); ESP_LOGI(TAG, "%s", buf); } if (get_switch_flipped_up(&switch_)) { sprintf(buf, "Switch Up: %d ", switch_); lcd_print(0, 3, buf); ESP_LOGI(TAG, "%s", buf); } if (get_switch_touch_pressed(&switch_)) { sprintf(buf, "Switch Touch: %d ", switch_); lcd_print(0, 3, buf); ESP_LOGI(TAG, "%s", buf); } if (get_switch_touch_released(&switch_)) { sprintf(buf, "Switch Un-touch: %d", switch_); lcd_print(0, 3, 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(1, 0, 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(1, 2, 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(); }