Compare commits
27
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ffc2b609b | ||
|
|
3b2f8957e4 | ||
|
|
852939830c | ||
|
|
f5c938d61f | ||
|
|
2f1ff23678 | ||
|
|
bff0bb30dd | ||
|
|
6508358ddf | ||
|
|
361a14aa09 | ||
|
|
232c9ddce1 | ||
|
|
6a798e96e9 | ||
|
|
a198ae4225 | ||
|
|
c359ecb544 | ||
|
|
4f2f0fccda | ||
|
|
579a7559c1 | ||
|
|
758b16aa0d | ||
|
|
54ff226694 | ||
|
|
8cd5d09933 | ||
|
|
00fa493943 | ||
|
|
12eedf9722 | ||
|
|
43b01f0b2b | ||
|
|
295b764d40 | ||
|
|
6530ed56c6 | ||
|
|
83915efc33 | ||
|
|
41113ccafe | ||
|
|
cc8dcfacb3 | ||
|
|
62b82eba2b | ||
|
|
babe2f828e |
@@ -1,53 +1,19 @@
|
|||||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | Linux |
|
# BLK_BOX_TC
|
||||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | ----- |
|
|
||||||
|
|
||||||
# Hello World Example
|
ESP-IDF version `v5.3.2`
|
||||||
|
|
||||||
Starts a FreeRTOS task to print "Hello World".
|
Firmware for the BLK_BOX Top control board for the puzzle `PDE001`.
|
||||||
|
|
||||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
## Resources
|
||||||
|
|
||||||
## How to use example
|
All the files in the `resources/` folder should be loaded onto a micro SD card placed in the BLK_BOX.
|
||||||
|
|
||||||
Follow detailed instructions provided specifically for this example.
|
Developer Note: You can convert mp3 files to 44100Hz mono signed 16 uncompressed .wav files with the following command:
|
||||||
|
```ffmpeg -i input.mp3 -ac 1 -ar 44100 -sample_fmt s16 output.wav```
|
||||||
|
|
||||||
Select the instructions depending on Espressif chip installed on your development board:
|
File names must be no longer than `8` characters not including the extention
|
||||||
|
File extentions must be no longer than `3` characters.
|
||||||
|
|
||||||
- [ESP32 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/index.html)
|
To build images, use the lvgl image converter [`https://lvgl.io/tools/imageconverter`].
|
||||||
- [ESP32-S2 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html)
|
Use v8.
|
||||||
|
I have had the best luck with `CF_RGB565A8`.
|
||||||
|
|
||||||
## Example folder contents
|
|
||||||
|
|
||||||
The project **hello_world** contains one source file in C language [hello_world_main.c](main/hello_world_main.c). The file is located in folder [main](main).
|
|
||||||
|
|
||||||
ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt` files that provide set of directives and instructions describing the project's source files and targets (executable, library, or both).
|
|
||||||
|
|
||||||
Below is short explanation of remaining files in the project folder.
|
|
||||||
|
|
||||||
```
|
|
||||||
├── CMakeLists.txt
|
|
||||||
├── pytest_hello_world.py Python script used for automated testing
|
|
||||||
├── main
|
|
||||||
│ ├── CMakeLists.txt
|
|
||||||
│ └── hello_world_main.c
|
|
||||||
└── README.md This is the file you are currently reading
|
|
||||||
```
|
|
||||||
|
|
||||||
For more information on structure and contents of ESP-IDF projects, please refer to Section [Build System](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html) of the ESP-IDF Programming Guide.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
* Program upload failure
|
|
||||||
|
|
||||||
* Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs.
|
|
||||||
* The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again.
|
|
||||||
|
|
||||||
## Technical support and feedback
|
|
||||||
|
|
||||||
Please use the following feedback channels:
|
|
||||||
|
|
||||||
* For technical queries, go to the [esp32.com](https://esp32.com/) forum
|
|
||||||
* For a feature request or bug report, create a [GitHub issue](https://github.com/espressif/esp-idf/issues)
|
|
||||||
|
|
||||||
We will get back to you as soon as possible.
|
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ set(SOURCES
|
|||||||
"TM1640/TM1640.cpp"
|
"TM1640/TM1640.cpp"
|
||||||
"SparkFunBQ27441/SparkFunBQ27441.cpp"
|
"SparkFunBQ27441/SparkFunBQ27441.cpp"
|
||||||
"esp_lcd_ili9488/esp_lcd_ili9488.c"
|
"esp_lcd_ili9488/esp_lcd_ili9488.c"
|
||||||
"bottom_half.cpp"
|
# "bottom_half.cpp"
|
||||||
|
"event_based_bottom_half.cpp"
|
||||||
|
"inputs.cpp"
|
||||||
"char_lcd.cpp"
|
"char_lcd.cpp"
|
||||||
"game_timer.cpp"
|
"game_timer.cpp"
|
||||||
"i2c_lcd_pcf8574.c"
|
"i2c_lcd_pcf8574.c"
|
||||||
@@ -13,6 +15,7 @@ set(SOURCES
|
|||||||
"sd.cpp"
|
"sd.cpp"
|
||||||
"speaker.cpp"
|
"speaker.cpp"
|
||||||
"sseg.cpp"
|
"sseg.cpp"
|
||||||
|
"state_tracking.cpp"
|
||||||
"tft.cpp"
|
"tft.cpp"
|
||||||
"wires.cpp"
|
"wires.cpp"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,7 +11,11 @@ void init_drivers() {
|
|||||||
init_bottom_half();
|
init_bottom_half();
|
||||||
init_sd();
|
init_sd();
|
||||||
init_speaker();
|
init_speaker();
|
||||||
|
init_sseg();
|
||||||
|
init_game_timers();
|
||||||
|
init_tft();
|
||||||
|
init_leds();
|
||||||
|
init_power_board();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Initializes I2C_NUM_0.
|
/// @brief Initializes I2C_NUM_0.
|
||||||
@@ -28,8 +32,8 @@ static void init_i2c() {
|
|||||||
|
|
||||||
i2c_config_t conf = {
|
i2c_config_t conf = {
|
||||||
.mode = I2C_MODE_MASTER,
|
.mode = I2C_MODE_MASTER,
|
||||||
.sda_io_num = GPIO_NUM_5,
|
.sda_io_num = PIN_I2C_SDA,
|
||||||
.scl_io_num = GPIO_NUM_6,
|
.scl_io_num = PIN_I2C_SCL,
|
||||||
.sda_pullup_en = GPIO_PULLUP_DISABLE,
|
.sda_pullup_en = GPIO_PULLUP_DISABLE,
|
||||||
.scl_pullup_en = GPIO_PULLUP_DISABLE,
|
.scl_pullup_en = GPIO_PULLUP_DISABLE,
|
||||||
// .sda_pullup_en = GPIO_PULLUP_ENABLE,
|
// .sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||||
|
|||||||
+8
-12
@@ -1,21 +1,17 @@
|
|||||||
#ifndef ALL_H
|
#ifndef ALL_H
|
||||||
#define ALL_H
|
#define ALL_H
|
||||||
|
|
||||||
// #include "driver/uart.h"
|
#define PIN_I2C_SDA GPIO_NUM_7
|
||||||
// #include "driver/i2c.h"
|
#define PIN_I2C_SCL GPIO_NUM_15
|
||||||
// #include "drivers/tft.h"
|
|
||||||
// #include "drivers/wires.h"
|
|
||||||
// #include "drivers/sd.h"
|
|
||||||
// #include "drivers/game_timer.h"
|
|
||||||
// #include "drivers/speaker.h"
|
|
||||||
// #include "drivers/char_lcd.h"
|
|
||||||
// #include "drivers/leds.h"
|
|
||||||
// #include "drivers/power.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "char_lcd.h"
|
#include "char_lcd.h"
|
||||||
#include "drivers/bottom_half.h"
|
#include "bottom_half.h"
|
||||||
#include "sd.h"
|
#include "sd.h"
|
||||||
|
#include "speaker.h"
|
||||||
|
#include "game_timer.h"
|
||||||
|
#include "drivers/tft.h"
|
||||||
|
#include "drivers/leds.h"
|
||||||
|
#include "drivers/power.h"
|
||||||
|
|
||||||
void init_drivers();
|
void init_drivers();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
#include "bottom_half.h"
|
#include "bottom_half.h"
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include "state_tracking.h"
|
||||||
|
|
||||||
static const char *TAG = "bottom_half";
|
static const char *TAG = "bottom_half";
|
||||||
|
|
||||||
@@ -28,6 +30,11 @@ static void receive_keypad();
|
|||||||
static void receive_button_switch();
|
static void receive_button_switch();
|
||||||
static void receive_touch();
|
static void receive_touch();
|
||||||
|
|
||||||
|
static bool replay_handler(const char* event, char* arg) {
|
||||||
|
// no reply neccesary
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: add intrupt on bottom half delta pin
|
// TODO: add intrupt on bottom half delta pin
|
||||||
// static void IRAM_ATTR gpio_isr_handler(void* arg)
|
// static void IRAM_ATTR gpio_isr_handler(void* arg)
|
||||||
// {
|
// {
|
||||||
@@ -55,6 +62,8 @@ void init_bottom_half() {
|
|||||||
|
|
||||||
xTaskCreate(poll_bottom_task, "poll_bottom", 4096, NULL, 10, NULL);
|
xTaskCreate(poll_bottom_task, "poll_bottom", 4096, NULL, 10, NULL);
|
||||||
|
|
||||||
|
register_replay_fn(replay_handler);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Bottom half initialized!");
|
ESP_LOGI(TAG, "Bottom half initialized!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,9 +83,19 @@ static void receive_keypad(void) {
|
|||||||
|
|
||||||
uint16_t just_pressed = new_keypad_state & ~keypad_state;
|
uint16_t just_pressed = new_keypad_state & ~keypad_state;
|
||||||
keypad_pressed |= just_pressed;
|
keypad_pressed |= just_pressed;
|
||||||
|
if (is_state_tracking() && just_pressed) {
|
||||||
|
char buf[6];
|
||||||
|
sprintf(buf, "%d", just_pressed);
|
||||||
|
event_occured("KP_PRESS", buf);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t just_released = ~new_keypad_state & keypad_state;
|
uint16_t just_released = ~new_keypad_state & keypad_state;
|
||||||
keypad_released |= just_released;
|
keypad_released |= just_released;
|
||||||
|
if (is_state_tracking() && just_released) {
|
||||||
|
char buf[6];
|
||||||
|
sprintf(buf, "%d", just_released);
|
||||||
|
event_occured("KP_RELEASE", buf);
|
||||||
|
}
|
||||||
|
|
||||||
keypad_state = new_keypad_state;
|
keypad_state = new_keypad_state;
|
||||||
}
|
}
|
||||||
@@ -91,27 +110,57 @@ static void receive_button_switch(void) {
|
|||||||
// button
|
// button
|
||||||
uint8_t just_pressed = new_button_state & ~button_state;
|
uint8_t just_pressed = new_button_state & ~button_state;
|
||||||
button_pressed |= just_pressed;
|
button_pressed |= just_pressed;
|
||||||
|
if (is_state_tracking() && just_pressed) {
|
||||||
|
char buf[4];
|
||||||
|
sprintf(buf, "%d", just_pressed);
|
||||||
|
event_occured("BTN_PRESS", buf);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t just_released = ~new_button_state & button_state;
|
uint8_t just_released = ~new_button_state & button_state;
|
||||||
button_released |= just_released;
|
button_released |= just_released;
|
||||||
|
if (is_state_tracking() && just_released) {
|
||||||
|
char buf[4];
|
||||||
|
sprintf(buf, "%d", just_released);
|
||||||
|
event_occured("BTN_RELEASE", buf);
|
||||||
|
}
|
||||||
|
|
||||||
button_state = new_button_state;
|
button_state = new_button_state;
|
||||||
|
|
||||||
// switch
|
// switch
|
||||||
uint8_t just_flipped_up = new_switch_state & ~switch_state;
|
uint8_t just_flipped_up = new_switch_state & ~switch_state;
|
||||||
switch_flipped_up |= just_flipped_up;
|
switch_flipped_up |= just_flipped_up;
|
||||||
|
if (is_state_tracking() && just_flipped_up) {
|
||||||
|
char buf[4];
|
||||||
|
sprintf(buf, "%d", just_flipped_up);
|
||||||
|
event_occured("SW_UP", buf);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t just_flipped_down = ~new_switch_state & switch_state;
|
uint8_t just_flipped_down = ~new_switch_state & switch_state;
|
||||||
switch_flipped_down |= just_flipped_down;
|
switch_flipped_down |= just_flipped_down;
|
||||||
|
if (is_state_tracking() && just_flipped_down) {
|
||||||
|
char buf[4];
|
||||||
|
sprintf(buf, "%d", just_flipped_down);
|
||||||
|
event_occured("SW_DOWN", buf);
|
||||||
|
}
|
||||||
|
|
||||||
switch_state = new_switch_state;
|
switch_state = new_switch_state;
|
||||||
|
|
||||||
// switch touch
|
// switch touch
|
||||||
uint8_t touch_just_pressed = new_switch_touch_state & ~switch_touch_state;
|
uint8_t touch_just_pressed = new_switch_touch_state & ~switch_touch_state;
|
||||||
switch_touch_pressed |= touch_just_pressed;
|
switch_touch_pressed |= touch_just_pressed;
|
||||||
|
if (is_state_tracking() && touch_just_pressed) {
|
||||||
|
char buf[4];
|
||||||
|
sprintf(buf, "%d", touch_just_pressed);
|
||||||
|
event_occured("SW_TOUCH", buf);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t touch_just_released = ~new_switch_touch_state & switch_touch_state;
|
uint8_t touch_just_released = ~new_switch_touch_state & switch_touch_state;
|
||||||
switch_touch_released |= touch_just_released;
|
switch_touch_released |= touch_just_released;
|
||||||
|
if (is_state_tracking() && touch_just_released) {
|
||||||
|
char buf[4];
|
||||||
|
sprintf(buf, "%d", touch_just_released);
|
||||||
|
event_occured("SW_UNTOUCH", buf);
|
||||||
|
}
|
||||||
|
|
||||||
switch_touch_state = new_switch_touch_state;
|
switch_touch_state = new_switch_touch_state;
|
||||||
}
|
}
|
||||||
@@ -124,9 +173,15 @@ static void receive_touch(void) {
|
|||||||
|
|
||||||
bool just_pressed = new_touch_state & !touch_state;
|
bool just_pressed = new_touch_state & !touch_state;
|
||||||
touch_pressed |= just_pressed;
|
touch_pressed |= just_pressed;
|
||||||
|
if (is_state_tracking() && just_pressed) {
|
||||||
|
event_occured("FINGER_TOUCHED", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
bool just_released = (!new_touch_state) & touch_state;
|
bool just_released = (!new_touch_state) & touch_state;
|
||||||
touch_released |= just_released;
|
touch_released |= just_released;
|
||||||
|
if (is_state_tracking() && just_released) {
|
||||||
|
event_occured("FINGER_UNTOUCHED", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
touch_state = new_touch_state;
|
touch_state = new_touch_state;
|
||||||
}
|
}
|
||||||
@@ -135,10 +190,12 @@ static void poll_bottom_task(void *arg) {
|
|||||||
// TODO: if using an interupt, switch this to use a queue
|
// TODO: if using an interupt, switch this to use a queue
|
||||||
while (1) {
|
while (1) {
|
||||||
bool new_data = gpio_get_level(BOTTOM_PIN_INTERUPT) == 0;
|
bool new_data = gpio_get_level(BOTTOM_PIN_INTERUPT) == 0;
|
||||||
|
// bool new_data = 1;
|
||||||
if (new_data) {
|
if (new_data) {
|
||||||
uint8_t delta = receive_delta();
|
uint8_t delta = receive_delta();
|
||||||
// ESP_LOGI(_TAG, "delta: %d", delta);
|
// ESP_LOGI(_TAG, "delta: %d", delta);
|
||||||
if (delta == 0) ESP_LOGW(TAG, "delta pin was low, but delta register returned 0");
|
// if (delta == 0) ESP_LOGW(TAG, "delta pin was low, but delta register returned 0");
|
||||||
|
if (delta != 0) ESP_LOGI(TAG, "delta!");
|
||||||
|
|
||||||
if (delta & (1 << DELTA_BIT_KP)) receive_keypad();
|
if (delta & (1 << DELTA_BIT_KP)) receive_keypad();
|
||||||
if (delta & (1 << DELTA_BIT_BUTTON_SWITCH)) receive_button_switch();
|
if (delta & (1 << DELTA_BIT_BUTTON_SWITCH)) receive_button_switch();
|
||||||
@@ -285,8 +342,8 @@ bool get_switch_flipped(SwitchKey* switch_) {
|
|||||||
*switch_ = (SwitchKey) i;
|
*switch_ = (SwitchKey) i;
|
||||||
}
|
}
|
||||||
// clear bit
|
// clear bit
|
||||||
button_pressed &= ~bit_selector;
|
switch_flipped_up &= ~bit_selector;
|
||||||
button_released &= ~bit_selector;
|
switch_flipped_down &= ~bit_selector;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,7 +363,6 @@ uint8_t get_switch_touch_state(){
|
|||||||
return switch_touch_state;
|
return switch_touch_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool get_touch_state(void) {
|
bool get_touch_state(void) {
|
||||||
return touch_state;
|
return touch_state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,10 @@
|
|||||||
|
|
||||||
#include "driver/i2c.h"
|
#include "driver/i2c.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_log.h"
|
|
||||||
|
|
||||||
#define BOTTOM_I2C_NUM I2C_NUM_0
|
#define BOTTOM_I2C_NUM I2C_NUM_0
|
||||||
#define BOTTOM_I2C_ADDR 126
|
#define BOTTOM_I2C_ADDR 126
|
||||||
#define BOTTOM_PIN_INTERUPT GPIO_NUM_0
|
#define BOTTOM_PIN_INTERUPT GPIO_NUM_13
|
||||||
|
|
||||||
#define DELTA_BIT_KP 0
|
#define DELTA_BIT_KP 0
|
||||||
#define DELTA_BIT_BUTTON_SWITCH 1
|
#define DELTA_BIT_BUTTON_SWITCH 1
|
||||||
|
|||||||
+154
-4
@@ -2,11 +2,92 @@
|
|||||||
|
|
||||||
#include "./i2c_lcd_pcf8574.h"
|
#include "./i2c_lcd_pcf8574.h"
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
|
#include "state_tracking.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
i2c_lcd_pcf8574_handle_t lcd;
|
i2c_lcd_pcf8574_handle_t lcd;
|
||||||
|
|
||||||
static const char *TAG = "char_lcd";
|
static const char *TAG = "char_lcd";
|
||||||
|
|
||||||
|
static char buf[65];
|
||||||
|
|
||||||
|
static bool replay_handler(const char* event, char* arg) {
|
||||||
|
if (strcmp(event, "LCD_CLEAR") == 0) {
|
||||||
|
lcd_clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_CURSOR") == 0) {
|
||||||
|
char* col_str = strtok(arg, ",");
|
||||||
|
char* row_str = strtok(NULL, ",");
|
||||||
|
uint32_t col = atoi(col_str);
|
||||||
|
uint32_t row = atoi(row_str);
|
||||||
|
lcd_set_cursor_pos(col, row);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_SET_DISPLAY") == 0) {
|
||||||
|
lcd_set_display(strcmp(arg, "true") == 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_CURSOR_VIS") == 0) {
|
||||||
|
lcd_set_cursor_vis(strcmp(arg, "true") == 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_CURSOR_BLINK") == 0) {
|
||||||
|
lcd_set_cursor_blink(strcmp(arg, "true") == 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_SCROLL_DISPLAY_LEFT") == 0) {
|
||||||
|
lcd_scroll_display_left();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_SCROLL_DISPLAY_RIGHT") == 0) {
|
||||||
|
lcd_scroll_display_right();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_LEFT_TO_RIGHT") == 0) {
|
||||||
|
lcd_left_to_right();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_RIGHT_TO_LEFT") == 0) {
|
||||||
|
lcd_right_to_left();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_AUTOSCROLL") == 0) {
|
||||||
|
lcd_set_autoscroll(strcmp(arg, "true") == 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_BACKLIGHT") == 0) {
|
||||||
|
uint32_t brightness = atoi(arg);
|
||||||
|
lcd_set_backlight(brightness);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_CREATE_CHAR") == 0) {
|
||||||
|
char* location_str = strtok(arg, ",");
|
||||||
|
uint8_t location = atoi(location_str);
|
||||||
|
|
||||||
|
uint8_t charmap[8];
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
char* str = strtok(NULL, ",");
|
||||||
|
charmap[i] = atoi(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd_create_char(location, charmap);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_WRITE") == 0) {
|
||||||
|
uint8_t value = atoi(arg);
|
||||||
|
lcd_write(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LCD_PRINT") == 0) {
|
||||||
|
// TODO: handle \r and \n
|
||||||
|
lcd_print(arg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void init_lcd() {
|
void init_lcd() {
|
||||||
ESP_LOGI(TAG, "Initializing LCD...");
|
ESP_LOGI(TAG, "Initializing LCD...");
|
||||||
|
|
||||||
@@ -15,20 +96,34 @@ void init_lcd() {
|
|||||||
|
|
||||||
lcd_set_backlight(&lcd, 255);
|
lcd_set_backlight(&lcd, 255);
|
||||||
|
|
||||||
|
register_replay_fn(replay_handler);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "LCD initialized!");
|
ESP_LOGI(TAG, "LCD initialized!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lcd_clear() {
|
void lcd_clear() {
|
||||||
lcd_clear(&lcd);
|
lcd_clear(&lcd);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LCD_CLEAR", NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_cursor_home() {
|
void lcd_cursor_home() {
|
||||||
lcd_home(&lcd);
|
lcd_home(&lcd);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LCD_CURSOR", "0,0");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_cursor_pos(uint8_t col, uint8_t row) {
|
void lcd_set_cursor_pos(uint8_t col, uint8_t row) {
|
||||||
lcd_set_cursor(&lcd, col, row);
|
lcd_set_cursor(&lcd, col, row);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
sprintf(buf, "%d,%d", col, row);
|
||||||
|
event_occured("LCD_CURSOR", buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_display(bool display) {
|
void lcd_set_display(bool display) {
|
||||||
@@ -37,6 +132,10 @@ void lcd_set_display(bool display) {
|
|||||||
} else {
|
} else {
|
||||||
lcd_no_display(&lcd);
|
lcd_no_display(&lcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LCD_SET_DISPLAY", display ? "true" : "false");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_cursor_vis(bool cursor) {
|
void lcd_set_cursor_vis(bool cursor) {
|
||||||
@@ -45,6 +144,10 @@ void lcd_set_cursor_vis(bool cursor) {
|
|||||||
} else {
|
} else {
|
||||||
lcd_no_cursor(&lcd);
|
lcd_no_cursor(&lcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LCD_CURSOR_VIS", cursor ? "true" : "false");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_cursor_blink(bool blink) {
|
void lcd_set_cursor_blink(bool blink) {
|
||||||
@@ -53,20 +156,40 @@ void lcd_set_cursor_blink(bool blink) {
|
|||||||
} else {
|
} else {
|
||||||
lcd_no_blink(&lcd);
|
lcd_no_blink(&lcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LCD_CURSOR_BLINK", blink ? "true" : "false");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_scroll_display_left() {
|
void lcd_scroll_display_left() {
|
||||||
lcd_scroll_display_left(&lcd);
|
lcd_scroll_display_left(&lcd);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LCD_SCROLL_DISPLAY_LEFT", NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void lcd_scroll_display_right() {
|
void lcd_scroll_display_right() {
|
||||||
lcd_scroll_display_right(&lcd);
|
lcd_scroll_display_right(&lcd);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LCD_SCROLL_DISPLAY_RIGHT", NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_left_to_right() {
|
void lcd_left_to_right() {
|
||||||
lcd_left_to_right(&lcd);
|
lcd_left_to_right(&lcd);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LCD_LEFT_TO_RIGHT", NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void lcd_right_to_left() {
|
void lcd_right_to_left() {
|
||||||
lcd_right_to_left(&lcd);
|
lcd_right_to_left(&lcd);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LCD_RIGHT_TO_LEFT", NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_autoscroll(bool autoscroll) {
|
void lcd_set_autoscroll(bool autoscroll) {
|
||||||
@@ -75,25 +198,52 @@ void lcd_set_autoscroll(bool autoscroll) {
|
|||||||
} else {
|
} else {
|
||||||
lcd_no_autoscroll(&lcd);
|
lcd_no_autoscroll(&lcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LCD_AUTOSCROLL", autoscroll ? "true" : "false");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_backlight(uint8_t brightness) {
|
void lcd_set_backlight(uint8_t brightness) {
|
||||||
lcd_set_backlight(&lcd, brightness);
|
lcd_set_backlight(&lcd, brightness);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
sprintf(buf, "%d", brightness);
|
||||||
|
event_occured("LCD_BACKLIGHT", buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_create_char(uint8_t location, uint8_t charmap[]) {
|
void lcd_create_char(uint8_t location, uint8_t* charmap) {
|
||||||
lcd_create_char(&lcd, location, charmap);
|
lcd_create_char(&lcd, location, charmap);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
snprintf(buf, 65,
|
||||||
|
"%d,%d,%d,%d,%d,%d,%d,%d,%d", location,
|
||||||
|
charmap[0], charmap[1], charmap[2], charmap[3], charmap[4], charmap[5], charmap[6], charmap[7]
|
||||||
|
);
|
||||||
|
event_occured("LCD_CREATE_CHAR", buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_write(uint8_t value) {
|
void lcd_write(uint8_t value) {
|
||||||
lcd_write(&lcd, value);
|
lcd_write(&lcd, value);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
sprintf(buf, "%d", value);
|
||||||
|
event_occured("LCD_WRITE", buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_print(const char* str) {
|
void lcd_print(const char* str) {
|
||||||
lcd_print(&lcd, str);
|
lcd_print(&lcd, str);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
// TODO: handle \r and \n
|
||||||
|
event_occured("LCD_PRINT", str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_print(uint8_t col, uint8_t row, const char* str) {
|
void lcd_print(uint8_t col, uint8_t row, const char* str) {
|
||||||
lcd_set_cursor_pos(col, row);
|
lcd_set_cursor_pos(col, row);
|
||||||
lcd_print(&lcd, str);
|
lcd_print(str);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ static esp_err_t panel_ili9488_init(esp_lcd_panel_t *panel)
|
|||||||
// ORIGINAL
|
// ORIGINAL
|
||||||
lcd_init_cmd_t ili9488_init[] =
|
lcd_init_cmd_t ili9488_init[] =
|
||||||
{
|
{
|
||||||
#if CONFIG_USE_NEW_DISPLAY
|
#if CONFIG_USE_NEW_DISPLAY || 1
|
||||||
{ ILI9488_POSITIVE_GAMMA_CTL, { 0x00, 0x08, 0x0c, 0x02, 0x0e, 0x04, 0x30, 0x45, 0x47, 0x04, 0x0C, 0x0a, 0x2e, 0x34, 0x0F }, 15 },
|
{ ILI9488_POSITIVE_GAMMA_CTL, { 0x00, 0x08, 0x0c, 0x02, 0x0e, 0x04, 0x30, 0x45, 0x47, 0x04, 0x0C, 0x0a, 0x2e, 0x34, 0x0F }, 15 },
|
||||||
{ ILI9488_NEGATIVE_GAMMA_CTL, { 0x00, 0x11, 0x0d, 0x01, 0x0f, 0x05, 0x39, 0x36, 0x51, 0x06, 0x0f, 0x0d, 0x33, 0x37, 0x0F }, 15 },
|
{ ILI9488_NEGATIVE_GAMMA_CTL, { 0x00, 0x11, 0x0d, 0x01, 0x0f, 0x05, 0x39, 0x36, 0x51, 0x06, 0x0f, 0x0d, 0x33, 0x37, 0x0F }, 15 },
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -0,0 +1,326 @@
|
|||||||
|
#include "bottom_half.h"
|
||||||
|
#include "inputs.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
static uint8_t reverse_4_bits(uint8_t value) {
|
||||||
|
return static_cast<uint8_t>(((value & 0x1) << 3) |
|
||||||
|
((value & 0x2) << 1) |
|
||||||
|
((value & 0x4) >> 1) |
|
||||||
|
((value & 0x8) >> 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
static KeypadKey map_input_keypad_key(InputKeypadKey key) {
|
||||||
|
switch (key) {
|
||||||
|
case InputKeypadKey::K0: return KeypadKey::k0;
|
||||||
|
case InputKeypadKey::K1: return KeypadKey::k1;
|
||||||
|
case InputKeypadKey::K2: return KeypadKey::k2;
|
||||||
|
case InputKeypadKey::K3: return KeypadKey::k3;
|
||||||
|
case InputKeypadKey::K4: return KeypadKey::k4;
|
||||||
|
case InputKeypadKey::K5: return KeypadKey::k5;
|
||||||
|
case InputKeypadKey::K6: return KeypadKey::k6;
|
||||||
|
case InputKeypadKey::K7: return KeypadKey::k7;
|
||||||
|
case InputKeypadKey::K8: return KeypadKey::k8;
|
||||||
|
case InputKeypadKey::K9: return KeypadKey::k9;
|
||||||
|
case InputKeypadKey::A: return KeypadKey::ka;
|
||||||
|
case InputKeypadKey::B: return KeypadKey::kb;
|
||||||
|
case InputKeypadKey::C: return KeypadKey::kc;
|
||||||
|
case InputKeypadKey::D: return KeypadKey::kd;
|
||||||
|
case InputKeypadKey::STAR: return KeypadKey::star;
|
||||||
|
case InputKeypadKey::POUND: return KeypadKey::pound;
|
||||||
|
default: return KeypadKey::k0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t get_fingerprint_touch_state() {
|
||||||
|
InputsState current = InputsController::get_input_state();
|
||||||
|
return static_cast<uint8_t>((current.touch_state >> 4) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool touch_state_initialized = false;
|
||||||
|
static bool touch_state_last = false;
|
||||||
|
|
||||||
|
static bool update_fingerprint_transition(bool want_pressed) {
|
||||||
|
bool current = get_fingerprint_touch_state();
|
||||||
|
if (!touch_state_initialized) {
|
||||||
|
touch_state_last = current;
|
||||||
|
touch_state_initialized = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool transition = want_pressed ? (current && !touch_state_last)
|
||||||
|
: (!current && touch_state_last);
|
||||||
|
touch_state_last = current;
|
||||||
|
return transition;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::array<SwitchFlip, 8> pending_switch_flips;
|
||||||
|
static size_t pending_switch_flip_count = 0;
|
||||||
|
|
||||||
|
static void push_pending_switch_flip(const SwitchFlip& event) {
|
||||||
|
if (pending_switch_flip_count < pending_switch_flips.size()) {
|
||||||
|
pending_switch_flips[pending_switch_flip_count++] = event;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop the oldest event if the buffer is full.
|
||||||
|
for (size_t i = 1; i < pending_switch_flips.size(); ++i) {
|
||||||
|
pending_switch_flips[i - 1] = pending_switch_flips[i];
|
||||||
|
}
|
||||||
|
pending_switch_flips.back() = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool pop_pending_switch_flip(bool want_up, SwitchFlip& out) {
|
||||||
|
for (size_t i = 0; i < pending_switch_flip_count; ++i) {
|
||||||
|
if (pending_switch_flips[i].is_up() == want_up) {
|
||||||
|
out = pending_switch_flips[i];
|
||||||
|
for (size_t j = i + 1; j < pending_switch_flip_count; ++j) {
|
||||||
|
pending_switch_flips[j - 1] = pending_switch_flips[j];
|
||||||
|
}
|
||||||
|
--pending_switch_flip_count;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_pending_switch_flips() {
|
||||||
|
pending_switch_flip_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::array<SwitchTouch, 8> pending_switch_touches;
|
||||||
|
static size_t pending_switch_touch_count = 0;
|
||||||
|
|
||||||
|
static void push_pending_switch_touch(const SwitchTouch& event) {
|
||||||
|
if (pending_switch_touch_count < pending_switch_touches.size()) {
|
||||||
|
pending_switch_touches[pending_switch_touch_count++] = event;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < pending_switch_touches.size(); ++i) {
|
||||||
|
pending_switch_touches[i - 1] = pending_switch_touches[i];
|
||||||
|
}
|
||||||
|
pending_switch_touches.back() = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool pop_pending_switch_touch(bool want_touched, SwitchTouch& out) {
|
||||||
|
for (size_t i = 0; i < pending_switch_touch_count; ++i) {
|
||||||
|
if (pending_switch_touches[i].is_touched() == want_touched) {
|
||||||
|
out = pending_switch_touches[i];
|
||||||
|
for (size_t j = i + 1; j < pending_switch_touch_count; ++j) {
|
||||||
|
pending_switch_touches[j - 1] = pending_switch_touches[j];
|
||||||
|
}
|
||||||
|
--pending_switch_touch_count;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_pending_switch_touches() {
|
||||||
|
pending_switch_touch_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_bottom_half() {
|
||||||
|
init_expander();
|
||||||
|
clear_all_pressed_released();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_all_pressed_released() {
|
||||||
|
InputsController::clear_all_events();
|
||||||
|
clear_pending_switch_flips();
|
||||||
|
clear_pending_switch_touches();
|
||||||
|
touch_state_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_keypad_pressed(KeypadKey* kp) {
|
||||||
|
auto opt = InputsController::get_keypad_press();
|
||||||
|
if (!opt.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kp != nullptr) {
|
||||||
|
*kp = map_input_keypad_key(opt.value());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_keypad_released(KeypadKey* kp) {
|
||||||
|
auto opt = InputsController::get_keypad_release();
|
||||||
|
if (!opt.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kp != nullptr) {
|
||||||
|
*kp = map_input_keypad_key(opt.value());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char char_of_keypad_key(KeypadKey kp) {
|
||||||
|
switch (kp) {
|
||||||
|
case KeypadKey::k1: return '1';
|
||||||
|
case KeypadKey::k2: return '2';
|
||||||
|
case KeypadKey::k3: return '3';
|
||||||
|
case KeypadKey::k4: return '4';
|
||||||
|
case KeypadKey::k5: return '5';
|
||||||
|
case KeypadKey::k6: return '6';
|
||||||
|
case KeypadKey::k7: return '7';
|
||||||
|
case KeypadKey::k8: return '8';
|
||||||
|
case KeypadKey::k9: return '9';
|
||||||
|
case KeypadKey::k0: return '0';
|
||||||
|
case KeypadKey::ka: return 'A';
|
||||||
|
case KeypadKey::kb: return 'B';
|
||||||
|
case KeypadKey::kc: return 'C';
|
||||||
|
case KeypadKey::kd: return 'D';
|
||||||
|
case KeypadKey::star: return '*';
|
||||||
|
case KeypadKey::pound: return '#';
|
||||||
|
default: return ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool take_button(ButtonKey* button, std::optional<Button> opt) {
|
||||||
|
if (!opt.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (button != nullptr) {
|
||||||
|
*button = static_cast<ButtonKey>(static_cast<uint8_t>(opt.value()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_button_pressed(ButtonKey* button) {
|
||||||
|
return take_button(button, InputsController::get_button_press());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_button_released(ButtonKey* button) {
|
||||||
|
return take_button(button, InputsController::get_button_release());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t get_button_state() {
|
||||||
|
return reverse_4_bits(InputsController::button_state() & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool take_switch_key(SwitchKey* switch_, const SwitchFlip& event) {
|
||||||
|
if (switch_ != nullptr) {
|
||||||
|
*switch_ = static_cast<SwitchKey>(static_cast<uint8_t>(event.get_switch()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_switch_flipped_up(SwitchKey* switch_) {
|
||||||
|
SwitchFlip event;
|
||||||
|
if (pop_pending_switch_flip(true, event)) {
|
||||||
|
return take_switch_key(switch_, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto opt = InputsController::get_switch_flip();
|
||||||
|
if (!opt.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (opt->is_up()) {
|
||||||
|
return take_switch_key(switch_, *opt);
|
||||||
|
}
|
||||||
|
push_pending_switch_flip(*opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_switch_flipped_down(SwitchKey* switch_) {
|
||||||
|
SwitchFlip event;
|
||||||
|
if (pop_pending_switch_flip(false, event)) {
|
||||||
|
return take_switch_key(switch_, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto opt = InputsController::get_switch_flip();
|
||||||
|
if (!opt.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!opt->is_up()) {
|
||||||
|
return take_switch_key(switch_, *opt);
|
||||||
|
}
|
||||||
|
push_pending_switch_flip(*opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_switch_flipped(SwitchKey* switch_) {
|
||||||
|
if (pending_switch_flip_count > 0) {
|
||||||
|
SwitchFlip event = pending_switch_flips[0];
|
||||||
|
for (size_t i = 1; i < pending_switch_flip_count; ++i) {
|
||||||
|
pending_switch_flips[i - 1] = pending_switch_flips[i];
|
||||||
|
}
|
||||||
|
--pending_switch_flip_count;
|
||||||
|
return take_switch_key(switch_, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto opt = InputsController::get_switch_flip();
|
||||||
|
if (!opt.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return take_switch_key(switch_, *opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t get_switch_state() {
|
||||||
|
return reverse_4_bits(InputsController::switch_state() & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool take_switch_touch(SwitchKey* switch_, const SwitchTouch& event) {
|
||||||
|
if (switch_ != nullptr) {
|
||||||
|
*switch_ = static_cast<SwitchKey>(static_cast<uint8_t>(event.get_switch()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_switch_touch_pressed(SwitchKey* switch_) {
|
||||||
|
SwitchTouch event;
|
||||||
|
if (pop_pending_switch_touch(true, event)) {
|
||||||
|
return take_switch_touch(switch_, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto opt = InputsController::get_switch_touch();
|
||||||
|
if (!opt.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (opt->is_touched()) {
|
||||||
|
return take_switch_touch(switch_, *opt);
|
||||||
|
}
|
||||||
|
push_pending_switch_touch(*opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_switch_touch_released(SwitchKey* switch_) {
|
||||||
|
SwitchTouch event;
|
||||||
|
if (pop_pending_switch_touch(false, event)) {
|
||||||
|
return take_switch_touch(switch_, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto opt = InputsController::get_switch_touch();
|
||||||
|
if (!opt.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!opt->is_touched()) {
|
||||||
|
return take_switch_touch(switch_, *opt);
|
||||||
|
}
|
||||||
|
push_pending_switch_touch(*opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t get_switch_touch_state() {
|
||||||
|
return reverse_4_bits(InputsController::switch_touch_state() & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_touch_state() {
|
||||||
|
return get_fingerprint_touch_state() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_touch_pressed() {
|
||||||
|
return update_fingerprint_transition(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_touch_released() {
|
||||||
|
return update_fingerprint_transition(false);
|
||||||
|
}
|
||||||
+17
-12
@@ -1,4 +1,7 @@
|
|||||||
#include "game_timer.h"
|
#include "game_timer.h"
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
static const char* TAG = "game_timer";
|
||||||
|
|
||||||
static bool is_module_playing;
|
static bool is_module_playing;
|
||||||
static bool is_game_playing;
|
static bool is_game_playing;
|
||||||
@@ -12,6 +15,14 @@ static uint32_t module_time_left;
|
|||||||
static void game_timer_task(void *arg);
|
static void game_timer_task(void *arg);
|
||||||
static uint32_t sat_sub(uint32_t x, uint32_t y);
|
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) {
|
static void write_game_time(uint32_t millis) {
|
||||||
if (millis > 60'000) {
|
if (millis > 60'000) {
|
||||||
int disp_time = (millis / 60'000) * 100;
|
int disp_time = (millis / 60'000) * 100;
|
||||||
@@ -31,23 +42,19 @@ static void write_module_time(uint32_t millis) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_game_module_timer(void) {
|
void start_game_timer() {
|
||||||
xTaskCreate(game_timer_task, "game_module_timer", 4096, NULL, 10, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void start_game_timer(void) {
|
|
||||||
is_game_playing = true;
|
is_game_playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_game_timer(void) {
|
void stop_game_timer() {
|
||||||
is_game_playing = false;
|
is_game_playing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_module_timer(void) {
|
void start_module_timer() {
|
||||||
is_module_playing = true;
|
is_module_playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_module_timer(void) {
|
void stop_module_timer() {
|
||||||
is_module_playing = false;
|
is_module_playing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,8 +98,7 @@ void time_penalty(uint32_t penalty) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void game_timer_task(void *arg)
|
static void game_timer_task(void *arg) {
|
||||||
{
|
|
||||||
TickType_t lastWakeTime = xTaskGetTickCount();
|
TickType_t lastWakeTime = xTaskGetTickCount();
|
||||||
|
|
||||||
const uint32_t frequency = 100;
|
const uint32_t frequency = 100;
|
||||||
@@ -118,8 +124,7 @@ static void game_timer_task(void *arg)
|
|||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t sat_sub(uint32_t x, uint32_t y)
|
static uint32_t sat_sub(uint32_t x, uint32_t y) {
|
||||||
{
|
|
||||||
uint32_t res = x - y;
|
uint32_t res = x - y;
|
||||||
res &= -(res <= x);
|
res &= -(res <= x);
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -5,17 +5,17 @@
|
|||||||
#include "sseg.h"
|
#include "sseg.h"
|
||||||
|
|
||||||
/// Initializes the game and module timers.
|
/// Initializes the game and module timers.
|
||||||
void init_game_module_timer(void);
|
void init_game_timers();
|
||||||
|
|
||||||
/// Starts the game timer
|
/// Starts the game timer
|
||||||
void start_game_timer(void);
|
void start_game_timer();
|
||||||
/// Stops the game timer
|
/// Stops the game timer
|
||||||
void stop_game_timer(void);
|
void stop_game_timer();
|
||||||
|
|
||||||
/// Starts the module timer
|
/// Starts the module timer
|
||||||
void start_module_timer(void);
|
void start_module_timer();
|
||||||
/// Stops the module timer
|
/// Stops the module timer
|
||||||
void stop_module_timer(void);
|
void stop_module_timer();
|
||||||
|
|
||||||
/// Sets the game time in ms
|
/// Sets the game time in ms
|
||||||
void set_game_time(int32_t new_time);
|
void set_game_time(int32_t new_time);
|
||||||
|
|||||||
@@ -0,0 +1,475 @@
|
|||||||
|
#include "inputs.hpp"
|
||||||
|
#include "pins.h"
|
||||||
|
#include "driver/i2c.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
static const char *TAG = "INPUTS";
|
||||||
|
|
||||||
|
static TaskHandle_t expander_task_handle = NULL;
|
||||||
|
|
||||||
|
const static uint8_t REG_WHOAMI = 0x01;
|
||||||
|
const static uint8_t REG_SW_VERSION = 0x02;
|
||||||
|
const static uint8_t REG_EVENT_QUEUE_POP = 0x10;
|
||||||
|
const static uint8_t REG_EVENT_QUEUE_LEN = 0x11;
|
||||||
|
const static uint8_t REG_STATE_BUTTONS = 0x20;
|
||||||
|
const static uint8_t REG_STATE_SWITCHES = 0x21;
|
||||||
|
const static uint8_t REG_STATE_KEYPAD = 0x22;
|
||||||
|
const static uint8_t REG_STATE_TOUCH = 0x23;
|
||||||
|
const static uint8_t REG_STATE_RFID = 0x24;
|
||||||
|
const static uint8_t REG_STATE_HALL = 0x25;
|
||||||
|
const static uint8_t REG_STATE_CLOSE = 0x26;
|
||||||
|
const static uint8_t REG_RESET = 0x30;
|
||||||
|
const static uint8_t REG_HALL_SENSITIVITY = 0x31;
|
||||||
|
const static uint8_t REG_CLOSE_SENSITIVITY = 0x32;
|
||||||
|
const static uint8_t REG_SWITCH_TOUCH_EVENT = 0x33;
|
||||||
|
|
||||||
|
/// The global data for the expander peripheral.
|
||||||
|
class ExpanderPeripheral {
|
||||||
|
// TODO: change these to private
|
||||||
|
// or even make this class hidden
|
||||||
|
public:
|
||||||
|
SemaphoreHandle_t state_mutex;
|
||||||
|
InputsState state;
|
||||||
|
|
||||||
|
// channels
|
||||||
|
QueueHandle_t button_press_events;
|
||||||
|
QueueHandle_t button_release_events;
|
||||||
|
QueueHandle_t switch_flip_events;
|
||||||
|
QueueHandle_t switch_touch_events;
|
||||||
|
QueueHandle_t touch_events;
|
||||||
|
QueueHandle_t keypad_press_events;
|
||||||
|
QueueHandle_t keypad_release_events;
|
||||||
|
};
|
||||||
|
|
||||||
|
ExpanderPeripheral expander_peripheral_singleton;
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
static void get_events();
|
||||||
|
static void handle_event(uint8_t event);
|
||||||
|
static void handle_button_switch_event(uint8_t event);
|
||||||
|
static void handle_keypad_event(uint8_t event);
|
||||||
|
static void handle_touch_event(uint8_t event);
|
||||||
|
static void handle_rfid_event(uint8_t event);
|
||||||
|
static void handle_close_hal_event(uint8_t event);
|
||||||
|
static void expander_task(void *arg);
|
||||||
|
|
||||||
|
// ISR handler
|
||||||
|
static void IRAM_ATTR expander_isr_handler(void *arg) {
|
||||||
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
|
||||||
|
if (expander_task_handle != NULL) {
|
||||||
|
vTaskNotifyGiveFromISR(expander_task_handle, &xHigherPriorityTaskWoken);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||||
|
portYIELD_FROM_ISR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_expander() {
|
||||||
|
ESP_LOGI(TAG, "Initializing expander...");
|
||||||
|
|
||||||
|
// legacy I2C driver: use the shared I2C_NUM_0 bus already configured elsewhere.
|
||||||
|
// TODO: replace all these ESP_ERROR_CHECK with proper error handling that doesn't just crash the program
|
||||||
|
|
||||||
|
// setup interrupt on PIN_EXPANDER_INT
|
||||||
|
gpio_config_t io_conf = {
|
||||||
|
.pin_bit_mask = (1ULL << PIN_EXPANDER_INT),
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||||
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
|
.intr_type = GPIO_INTR_NEGEDGE
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(gpio_config(&io_conf));
|
||||||
|
|
||||||
|
// Install ISR service (only call once in your program)
|
||||||
|
ESP_ERROR_CHECK(gpio_install_isr_service(0));
|
||||||
|
|
||||||
|
// Attach the ISR to the expander pin
|
||||||
|
ESP_ERROR_CHECK(gpio_isr_handler_add(PIN_EXPANDER_INT, expander_isr_handler, NULL));
|
||||||
|
|
||||||
|
// verify the expander connection status by reading the WHOAMI register
|
||||||
|
uint8_t read_buf[2] = {0};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(i2c_master_write_read_device(I2C_NUM_0, EXPANDER_I2C_ADDR, ®_WHOAMI, 1, read_buf, 1, pdMS_TO_TICKS(EXPANDER_TIMEOUT_MS)));
|
||||||
|
|
||||||
|
if (read_buf[0] != EXPANDER_WHOAMI_VALUE) {
|
||||||
|
ESP_LOGE(TAG, "WHOAMI mismatch, expected 0x%02X, got 0x%02X", EXPANDER_WHOAMI_VALUE, read_buf[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Expander WHOAMI check passed");
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(i2c_master_write_read_device(I2C_NUM_0, EXPANDER_I2C_ADDR, ®_SW_VERSION, 1, read_buf, 2, pdMS_TO_TICKS(EXPANDER_TIMEOUT_MS)));
|
||||||
|
|
||||||
|
// init the peripheral struct
|
||||||
|
expander_peripheral_singleton.state_mutex = xSemaphoreCreateMutex();
|
||||||
|
expander_peripheral_singleton.button_press_events= xQueueCreate(EXPANDER_EVENT_QUEUE_SIZE, sizeof(Button));
|
||||||
|
expander_peripheral_singleton.button_release_events= xQueueCreate(EXPANDER_EVENT_QUEUE_SIZE, sizeof(Button));
|
||||||
|
expander_peripheral_singleton.switch_flip_events= xQueueCreate(EXPANDER_EVENT_QUEUE_SIZE, sizeof(SwitchFlip));
|
||||||
|
expander_peripheral_singleton.switch_touch_events= xQueueCreate(EXPANDER_EVENT_QUEUE_SIZE, sizeof(SwitchTouch));
|
||||||
|
expander_peripheral_singleton.touch_events= xQueueCreate(EXPANDER_EVENT_QUEUE_SIZE, sizeof(TouchedReleased));
|
||||||
|
expander_peripheral_singleton.keypad_press_events= xQueueCreate(EXPANDER_KEYPAD_QUEUE_SIZE, sizeof(InputKeypadKey));
|
||||||
|
expander_peripheral_singleton.keypad_release_events= xQueueCreate(EXPANDER_KEYPAD_QUEUE_SIZE, sizeof(InputKeypadKey));
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Expander initialized! SW version: v%d.%d", read_buf[0], read_buf[1]);
|
||||||
|
|
||||||
|
// Create the expander background worker task
|
||||||
|
BaseType_t task_created = xTaskCreate(
|
||||||
|
expander_task,
|
||||||
|
"expander_task",
|
||||||
|
4096,
|
||||||
|
NULL,
|
||||||
|
tskIDLE_PRIORITY + 1,
|
||||||
|
&expander_task_handle
|
||||||
|
);
|
||||||
|
|
||||||
|
if (task_created != pdPASS) {
|
||||||
|
ESP_LOGE(TAG, "Failed to create expander task");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void expander_task(void *arg) {
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
get_events();
|
||||||
|
|
||||||
|
// Wait for interrupt notification (signal is sent when INT falls)
|
||||||
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_events() {
|
||||||
|
uint8_t recv;
|
||||||
|
while (gpio_get_level(PIN_EXPANDER_INT) == 0) {
|
||||||
|
ESP_ERROR_CHECK(i2c_master_write_read_device(I2C_NUM_0, EXPANDER_I2C_ADDR, ®_EVENT_QUEUE_POP, 1, &recv, 1, pdMS_TO_TICKS(EXPANDER_TIMEOUT_MS)));
|
||||||
|
handle_event(recv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_event(uint8_t event) {
|
||||||
|
const uint8_t BUTTON_SWITCH = 0b000;
|
||||||
|
const uint8_t KEYPAD = 0b001;
|
||||||
|
const uint8_t TOUCH = 0b010;
|
||||||
|
const uint8_t RFID = 0b011;
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Expander event: 0b%08b (0x%02X)", event, event);
|
||||||
|
|
||||||
|
if (event == 0) {
|
||||||
|
ESP_LOGE(TAG, "We read from event queue while it was empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t type_bits = event >> 5;
|
||||||
|
|
||||||
|
switch (type_bits) {
|
||||||
|
case BUTTON_SWITCH:
|
||||||
|
handle_button_switch_event(event);
|
||||||
|
break;
|
||||||
|
case KEYPAD:
|
||||||
|
handle_keypad_event(event);
|
||||||
|
break;
|
||||||
|
case TOUCH:
|
||||||
|
handle_touch_event(event);
|
||||||
|
break;
|
||||||
|
case RFID:
|
||||||
|
handle_rfid_event(event);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
handle_close_hal_event(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_button_switch_event(uint8_t event) {
|
||||||
|
const uint8_t PRESSED_NOT_RELEASED_BIT = 0b10000;
|
||||||
|
const uint8_t SWITCH_NOT_BUTTON_BIT = 0b01000;
|
||||||
|
const uint8_t SWITCH_UP_NOT_DOWN_BIT = 0b00100;
|
||||||
|
const uint8_t NUMBER_MASK = 0b00011;
|
||||||
|
|
||||||
|
bool pressed = (event & PRESSED_NOT_RELEASED_BIT) != 0;
|
||||||
|
uint8_t number = event & NUMBER_MASK;
|
||||||
|
|
||||||
|
if ((event & SWITCH_NOT_BUTTON_BIT) != 0) {
|
||||||
|
// For now, we support two position switches by only looking at the switch up events
|
||||||
|
bool switch_up = (event & SWITCH_UP_NOT_DOWN_BIT) != 0;
|
||||||
|
if (!switch_up) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Switch sw = static_cast<Switch>(number);
|
||||||
|
SwitchFlip sw_flip = SwitchFlip(sw, pressed);
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.switch_flip_events, &sw_flip, 0);
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
if (pressed) {
|
||||||
|
// set
|
||||||
|
expander_peripheral_singleton.state.switch_state |= 1 << number;
|
||||||
|
} else {
|
||||||
|
// clear
|
||||||
|
expander_peripheral_singleton.state.switch_state &= ~(1 << number);
|
||||||
|
}
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
} else {
|
||||||
|
// button
|
||||||
|
Button button = static_cast<Button>(number);
|
||||||
|
if (pressed) {
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.button_press_events, &button, 0);
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
expander_peripheral_singleton.state.button_state |= 1 << number;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
} else {
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.button_release_events, &button, 0);
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
expander_peripheral_singleton.state.button_state &= ~(1 << number);
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_keypad_event(uint8_t event) {
|
||||||
|
const uint8_t PRESSED_NOT_RELEASED_BIT = 0b10000;
|
||||||
|
const uint8_t KEY_MASK = 0b1111;
|
||||||
|
|
||||||
|
bool pressed = (event & PRESSED_NOT_RELEASED_BIT) != 0;
|
||||||
|
uint8_t number = event & KEY_MASK;
|
||||||
|
InputKeypadKey key = static_cast<InputKeypadKey>(number);
|
||||||
|
|
||||||
|
// starcode system gets first dibs
|
||||||
|
// TODO: do starcode inbetweener
|
||||||
|
// if starcode_handle_keypad(key, pressed).await {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (pressed) {
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.keypad_press_events, &key, 0);
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
expander_peripheral_singleton.state.keypad_state |= 1 << number;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
} else {
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.keypad_release_events, &key, 0);
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
expander_peripheral_singleton.state.keypad_state &= ~(1 << number);
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_touch_event(uint8_t event) {
|
||||||
|
const uint8_t TOUCHED_NOT_UNTOUCHED_BIT = 0b10000;
|
||||||
|
const uint8_t SENSOR_MASK = 0b0111;
|
||||||
|
const uint8_t FINGERPRINT_BIT = 0b0100;
|
||||||
|
|
||||||
|
bool touched = (event & TOUCHED_NOT_UNTOUCHED_BIT) != 0;
|
||||||
|
uint8_t sensor = event & SENSOR_MASK;
|
||||||
|
|
||||||
|
if ((sensor & FINGERPRINT_BIT) != 0) {
|
||||||
|
TouchedReleased touch_state = static_cast<TouchedReleased>(touched);
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.touch_events, &touch_state, 0);
|
||||||
|
} else {
|
||||||
|
Switch sw = static_cast<Switch>(sensor);
|
||||||
|
SwitchTouch sw_touch = SwitchTouch(sw, touched);
|
||||||
|
xQueueSendToBack(expander_peripheral_singleton.switch_touch_events, &sw_touch, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
if (touched) {
|
||||||
|
expander_peripheral_singleton.state.touch_state |= 1 << sensor;
|
||||||
|
} else {
|
||||||
|
expander_peripheral_singleton.state.touch_state &= ~(1 << sensor);
|
||||||
|
}
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_rfid_event(uint8_t event) {
|
||||||
|
// TODO: impl
|
||||||
|
(void)event;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_close_hal_event(uint8_t event) {
|
||||||
|
// TODO: impl
|
||||||
|
(void)event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// InputsController implementations
|
||||||
|
|
||||||
|
/// Clears all events waiting in the queues.
|
||||||
|
void InputsController::clear_all_events() {
|
||||||
|
xQueueReset(expander_peripheral_singleton.button_press_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.button_release_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.switch_flip_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.switch_touch_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.touch_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.keypad_press_events);
|
||||||
|
xQueueReset(expander_peripheral_singleton.keypad_release_events);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputsState InputsController::get_input_state() {
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
InputsState state_copy = expander_peripheral_singleton.state;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
return state_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a button press event waiting.
|
||||||
|
bool InputsController::has_button_press() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.button_press_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next button press event (if any).
|
||||||
|
std::optional<Button> InputsController::get_button_press() {
|
||||||
|
Button b;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.button_press_events, &b, 0) == pdTRUE) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next button press event, waiting if neccesary.
|
||||||
|
Button InputsController::wait_button_press() {
|
||||||
|
Button b;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.button_press_events, &b, portMAX_DELAY);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the current state of the buttons.
|
||||||
|
uint8_t InputsController::button_state() {
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
uint8_t value = expander_peripheral_singleton.state.button_state;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a button release event waiting.
|
||||||
|
bool InputsController::has_button_release() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.button_release_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next button release event (if any).
|
||||||
|
std::optional<Button> InputsController::get_button_release() {
|
||||||
|
Button b;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.button_release_events, &b, 0) == pdTRUE) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next button release event, waiting if neccesary.
|
||||||
|
Button InputsController::wait_button_release() {
|
||||||
|
Button b;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.button_release_events, &b, portMAX_DELAY);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a switch flip event waiting.
|
||||||
|
bool InputsController::has_switch_flip() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.switch_flip_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next switch flip event (if any).
|
||||||
|
std::optional<SwitchFlip> InputsController::get_switch_flip() {
|
||||||
|
SwitchFlip s;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.switch_flip_events, &s, 0) == pdTRUE) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next switch flip event, waiting if neccesary.
|
||||||
|
SwitchFlip InputsController::wait_switch_flip() {
|
||||||
|
SwitchFlip s;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.switch_flip_events, &s, portMAX_DELAY);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the current state of the switches.
|
||||||
|
uint8_t InputsController::switch_state() {
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
uint8_t value = expander_peripheral_singleton.state.switch_state;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a switch touch event waiting.
|
||||||
|
bool InputsController::has_switch_touch() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.switch_touch_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next switch touch event (if any).
|
||||||
|
std::optional<SwitchTouch> InputsController::get_switch_touch() {
|
||||||
|
SwitchTouch s;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.switch_touch_events, &s, 0) == pdTRUE) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next switch touch event, waiting if neccesary.
|
||||||
|
SwitchTouch InputsController::wait_switch_touch() {
|
||||||
|
SwitchTouch s;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.switch_touch_events, &s, portMAX_DELAY);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the current state of the touch sensors.
|
||||||
|
uint8_t InputsController::switch_touch_state() {
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
uint8_t value = expander_peripheral_singleton.state.touch_state;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a keypad press event waiting.
|
||||||
|
bool InputsController::has_keypad_press() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.keypad_press_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next keypad press event (if any).
|
||||||
|
std::optional<InputKeypadKey> InputsController::get_keypad_press() {
|
||||||
|
InputKeypadKey k;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.keypad_press_events, &k, 0) == pdTRUE) {
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next keypad press event, waiting if neccesary.
|
||||||
|
InputKeypadKey InputsController::wait_keypad_press() {
|
||||||
|
InputKeypadKey k;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.keypad_press_events, &k, portMAX_DELAY);
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` iff there is a keypad release event waiting.
|
||||||
|
bool InputsController::has_keypad_release() {
|
||||||
|
return uxQueueMessagesWaiting(expander_peripheral_singleton.keypad_release_events) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next keypad release event (if any).
|
||||||
|
std::optional<InputKeypadKey> InputsController::get_keypad_release() {
|
||||||
|
InputKeypadKey k;
|
||||||
|
if (xQueueReceive(expander_peripheral_singleton.keypad_release_events, &k, 0) == pdTRUE) {
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the next keypad release event, waiting if neccesary.
|
||||||
|
InputKeypadKey InputsController::wait_keypad_release() {
|
||||||
|
InputKeypadKey k;
|
||||||
|
xQueueReceive(expander_peripheral_singleton.keypad_release_events, &k, portMAX_DELAY);
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the current state of the keypad.
|
||||||
|
uint16_t InputsController::keypad_state() {
|
||||||
|
xSemaphoreTake(expander_peripheral_singleton.state_mutex, portMAX_DELAY);
|
||||||
|
uint16_t value = expander_peripheral_singleton.state.keypad_state;
|
||||||
|
xSemaphoreGive(expander_peripheral_singleton.state_mutex);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,275 @@
|
|||||||
|
#ifndef INPUTS_H
|
||||||
|
#define INPUTS_H
|
||||||
|
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <freertos/queue.h>
|
||||||
|
#include <freertos/semphr.h>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#define EXPANDER_I2C_ADDR (0x7E)
|
||||||
|
#define EXPANDER_I2C_SPEED (400000)
|
||||||
|
// the actual transaction takes ~0.3ms, but for some reason a timout of ~10 or lower causes issues.
|
||||||
|
#define EXPANDER_TIMEOUT_MS (100)
|
||||||
|
|
||||||
|
#define EXPANDER_WHOAMI_VALUE (0x85)
|
||||||
|
|
||||||
|
// queue sizes
|
||||||
|
#define EXPANDER_EVENT_QUEUE_SIZE 4
|
||||||
|
#define EXPANDER_KEYPAD_QUEUE_SIZE 16
|
||||||
|
|
||||||
|
void init_expander();
|
||||||
|
|
||||||
|
/// The four buttons on the bottom half.
|
||||||
|
enum class Button: uint8_t {
|
||||||
|
B1 = 0,
|
||||||
|
B2 = 1,
|
||||||
|
B3 = 2,
|
||||||
|
B4 = 3,
|
||||||
|
GREEN = 0,
|
||||||
|
RED = 1,
|
||||||
|
YELLOW = 2,
|
||||||
|
BLUE = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint8_t raw_value(Button v) { return static_cast<uint8_t>(v); }
|
||||||
|
constexpr Button button_from_raw(uint8_t raw) { return static_cast<Button>(raw & 0b11); }
|
||||||
|
|
||||||
|
/// The four switches on the bottom half.
|
||||||
|
enum class Switch: uint8_t {
|
||||||
|
S1 = 0,
|
||||||
|
S2 = 1,
|
||||||
|
S3 = 2,
|
||||||
|
S4 = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint8_t raw_value(Switch v) { return static_cast<uint8_t>(v); }
|
||||||
|
constexpr Switch switch_from_raw(uint8_t raw) { return static_cast<Switch>(raw & 0b11); }
|
||||||
|
|
||||||
|
enum class TouchedReleased: uint8_t {
|
||||||
|
Released = 0,
|
||||||
|
Touched = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint8_t raw_value(TouchedReleased v) { return static_cast<uint8_t>(v); }
|
||||||
|
constexpr TouchedReleased touched_released_from_raw(uint8_t raw) { return static_cast<TouchedReleased>(raw & 0b1); }
|
||||||
|
|
||||||
|
/// One of the keys on the keypad.
|
||||||
|
enum class InputKeypadKey: uint8_t {
|
||||||
|
K0 = 0,
|
||||||
|
K1 = 1,
|
||||||
|
K2 = 2,
|
||||||
|
K3 = 3,
|
||||||
|
K4 = 4,
|
||||||
|
K5 = 5,
|
||||||
|
K6 = 6,
|
||||||
|
K7 = 7,
|
||||||
|
K8 = 8,
|
||||||
|
K9 = 9,
|
||||||
|
A = 10,
|
||||||
|
B = 11,
|
||||||
|
C = 12,
|
||||||
|
D = 13,
|
||||||
|
STAR = 14,
|
||||||
|
POUND = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint8_t raw_value(InputKeypadKey v) { return static_cast<uint8_t>(v); }
|
||||||
|
constexpr InputKeypadKey keypad_key_from_raw(uint8_t raw) { return static_cast<InputKeypadKey>(raw & 0b1111); }
|
||||||
|
|
||||||
|
constexpr char keypad_key_to_char(InputKeypadKey key) {
|
||||||
|
static constexpr char lookup[16] = {
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', 'A', 'B', 'C', 'D', '*', '#'
|
||||||
|
};
|
||||||
|
return lookup[static_cast<uint8_t>(key) & 0b1111];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct SwitchFlip {
|
||||||
|
private:
|
||||||
|
// [bit2: up] [bit1-0: switch]
|
||||||
|
uint8_t data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
SwitchFlip(Switch sw, bool up)
|
||||||
|
: data((static_cast<uint8_t>(sw) & 0b11) |
|
||||||
|
((up ? 1 : 0) << 2)) {}
|
||||||
|
|
||||||
|
// Default constructor
|
||||||
|
SwitchFlip() : data(0) {}
|
||||||
|
|
||||||
|
// Raw value constructor
|
||||||
|
explicit SwitchFlip(uint8_t raw_data) : data(raw_data) {}
|
||||||
|
|
||||||
|
// Raw value getter
|
||||||
|
uint8_t raw() const { return data; }
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
Switch get_switch() const {
|
||||||
|
return static_cast<Switch>(data & 0b11);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_up() const {
|
||||||
|
return (data >> 2) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setters
|
||||||
|
void set_switch(Switch sw) {
|
||||||
|
data = (data & ~0b11) | (static_cast<uint8_t>(sw) & 0b11);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_up(bool up) {
|
||||||
|
data = (data & ~(1 << 2)) | ((up ? 1 : 0) << 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwitchFlip) == 1);
|
||||||
|
|
||||||
|
struct SwitchTouch {
|
||||||
|
private:
|
||||||
|
// [bit2: touched] [bit1-0: switch]
|
||||||
|
uint8_t data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
SwitchTouch(Switch sw, bool touched)
|
||||||
|
: data((static_cast<uint8_t>(sw) & 0b11) |
|
||||||
|
((touched ? 1 : 0) << 2)) {}
|
||||||
|
|
||||||
|
// Default constructor
|
||||||
|
SwitchTouch() : data(0) {}
|
||||||
|
|
||||||
|
// Raw value constructor
|
||||||
|
explicit SwitchTouch(uint8_t raw_data) : data(raw_data) {}
|
||||||
|
|
||||||
|
// Raw value getter
|
||||||
|
uint8_t raw() const { return data; }
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
Switch get_switch() const {
|
||||||
|
return static_cast<Switch>(data & 0b11);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_touched() const {
|
||||||
|
return (data >> 2) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setters
|
||||||
|
void set_switch(Switch sw) {
|
||||||
|
data = (data & ~0b11) | (static_cast<uint8_t>(sw) & 0b11);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_touched(bool touched) {
|
||||||
|
data = (data & ~(1 << 2)) | ((touched ? 1 : 0) << 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SwitchTouch) == 1);
|
||||||
|
|
||||||
|
struct ButtonOrSwitch {
|
||||||
|
private:
|
||||||
|
// [bit2: is_switch] [bit1-0: number]
|
||||||
|
uint8_t data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
ButtonOrSwitch(uint8_t number, bool is_switch)
|
||||||
|
: data((number & 0b11) |
|
||||||
|
((is_switch ? 1 : 0) << 2)) {}
|
||||||
|
|
||||||
|
ButtonOrSwitch() : data(0) {}
|
||||||
|
|
||||||
|
// Raw value constructor
|
||||||
|
explicit ButtonOrSwitch(uint8_t raw_data) : data(raw_data) {}
|
||||||
|
|
||||||
|
// Raw value getter
|
||||||
|
uint8_t raw() const { return data; }
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
uint8_t number() const {
|
||||||
|
return data & 0b11;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_switch() const {
|
||||||
|
return (data >> 2) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setters
|
||||||
|
void set_number(uint8_t number) {
|
||||||
|
data = (data & ~0b11) | (number & 0b11);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_is_switch(bool is_switch) {
|
||||||
|
data = (data & ~(1 << 2)) | ((is_switch ? 1 : 0) << 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(ButtonOrSwitch) == 1);
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief The state of the bottom half of the box.
|
||||||
|
struct InputsState {
|
||||||
|
/// The touch state of the switches in the lower 4 bits.
|
||||||
|
/// The touch pad state in bit 4.
|
||||||
|
uint8_t touch_state;
|
||||||
|
/// The current state of the buttons in the lower 4 bits.
|
||||||
|
uint8_t button_state;
|
||||||
|
/// The current state of the switches. Up switches are stored
|
||||||
|
/// in the lower 4 bits, switches that are down are stored in
|
||||||
|
/// the upper 4 bits. If switches are in the middle, the
|
||||||
|
/// corresponding bit will be `0` in the upper and lower 4.
|
||||||
|
uint8_t switch_state;
|
||||||
|
/// The state of the keypad.
|
||||||
|
uint16_t keypad_state;
|
||||||
|
/// The sensitivity of the `hal` value to auto update.
|
||||||
|
uint16_t hal_sense;
|
||||||
|
/// The sensitivity of the `close_hal` value to auto update.
|
||||||
|
uint16_t close_hal_sense;
|
||||||
|
/// A non-exact hal value reading.
|
||||||
|
/// This only gets updated when it changes by `hal_sense`
|
||||||
|
uint16_t hal;
|
||||||
|
/// A non-exact hal value reading.
|
||||||
|
/// This only gets updated when it changes by `close_hal_sense`
|
||||||
|
uint16_t close_hal;
|
||||||
|
/// The RFID card that was presented last.
|
||||||
|
uint32_t rfid_state;
|
||||||
|
|
||||||
|
InputsState() : touch_state(0), button_state(0), switch_state(0), keypad_state(0), hal_sense(0), close_hal_sense(0), hal(0), close_hal(0), rfid_state(0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class InputsController {
|
||||||
|
public:
|
||||||
|
static void clear_all_events();
|
||||||
|
|
||||||
|
static InputsState get_input_state();
|
||||||
|
|
||||||
|
static bool has_button_press();
|
||||||
|
static std::optional<Button> get_button_press();
|
||||||
|
static Button wait_button_press();
|
||||||
|
static uint8_t button_state();
|
||||||
|
|
||||||
|
static bool has_button_release();
|
||||||
|
static std::optional<Button> get_button_release();
|
||||||
|
static Button wait_button_release();
|
||||||
|
|
||||||
|
static bool has_switch_flip();
|
||||||
|
static std::optional<SwitchFlip> get_switch_flip();
|
||||||
|
static SwitchFlip wait_switch_flip();
|
||||||
|
static uint8_t switch_state();
|
||||||
|
|
||||||
|
static bool has_switch_touch();
|
||||||
|
static std::optional<SwitchTouch> get_switch_touch();
|
||||||
|
static SwitchTouch wait_switch_touch();
|
||||||
|
static uint8_t switch_touch_state();
|
||||||
|
|
||||||
|
static bool has_keypad_press();
|
||||||
|
static std::optional<InputKeypadKey> get_keypad_press();
|
||||||
|
static InputKeypadKey wait_keypad_press();
|
||||||
|
|
||||||
|
static bool has_keypad_release();
|
||||||
|
static std::optional<InputKeypadKey> get_keypad_release();
|
||||||
|
static InputKeypadKey wait_keypad_release();
|
||||||
|
static uint16_t keypad_state();
|
||||||
|
|
||||||
|
// TODO: impl and add the hal and RFID stuff
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // INPUTS_H
|
||||||
+63
-7
@@ -1,8 +1,36 @@
|
|||||||
#include "leds.h"
|
#include "leds.h"
|
||||||
|
#include "led_strip.h"
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include "state_tracking.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
led_strip_handle_t leds;
|
static const char* TAG = "leds";
|
||||||
|
|
||||||
|
static led_strip_handle_t leds;
|
||||||
|
|
||||||
|
static bool replay_handler(const char* event, char* arg) {
|
||||||
|
if (strcmp(event, "LED_SET") == 0) {
|
||||||
|
uint32_t led = atoi(strtok(arg, ","));
|
||||||
|
uint32_t color = atoi(strtok(NULL, ","));
|
||||||
|
ESP_LOGI("leds", "color: %ld", color);
|
||||||
|
led_set(led, color);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LED_FLUSH") == 0) {
|
||||||
|
leds_flush();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "LED_CLR") == 0) {
|
||||||
|
leds_clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_leds() {
|
||||||
|
ESP_LOGI(TAG, "Initializing LEDs...");
|
||||||
|
|
||||||
void init_leds(void) {
|
|
||||||
led_strip_config_t strip_config = {
|
led_strip_config_t strip_config = {
|
||||||
.strip_gpio_num = NEOPIXEL_PIN,
|
.strip_gpio_num = NEOPIXEL_PIN,
|
||||||
.max_leds = LED_COUNT,
|
.max_leds = LED_COUNT,
|
||||||
@@ -17,11 +45,39 @@ void init_leds(void) {
|
|||||||
rmt_config.flags.with_dma = false;
|
rmt_config.flags.with_dma = false;
|
||||||
|
|
||||||
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &leds));
|
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &leds));
|
||||||
|
|
||||||
|
register_replay_fn(replay_handler);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "LEDs initialized!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void example_leds(void) {
|
void led_set(uint32_t led, uint8_t r, uint8_t g, uint8_t b) {
|
||||||
for (int i = 0; i < LED_COUNT; i++) {
|
led_strip_set_pixel(leds, led, r, g, b);
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, i, i, LED_COUNT-i, 0));
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
char buf[32];
|
||||||
|
uint32_t color = (r << 16) | (g << 8) | b;
|
||||||
|
sprintf(buf, "%ld,%ld", led, color);
|
||||||
|
event_occured("LED_SET", buf);
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
}
|
||||||
}
|
|
||||||
|
void led_set(uint32_t led, uint32_t color) {
|
||||||
|
led_set(led, (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void leds_flush() {
|
||||||
|
led_strip_refresh(leds);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LED_FLUSH", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void leds_clear() {
|
||||||
|
led_strip_clear(leds);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("LED_CLR", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+74
-28
@@ -1,40 +1,86 @@
|
|||||||
#ifndef LEDS_H
|
#ifndef LEDS_H
|
||||||
#define LEDS_H
|
#define LEDS_H
|
||||||
|
|
||||||
#include "led_strip.h"
|
#include "main.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define LED_COUNT 21
|
#define LED_COUNT 21
|
||||||
#define NEOPIXEL_PIN GPIO_NUM_7
|
|
||||||
|
#ifdef CONTROL_REV_2_0
|
||||||
|
#define NEOPIXEL_PIN GPIO_NUM_0
|
||||||
|
#endif
|
||||||
|
#ifdef CONTROL_REV_2_1
|
||||||
|
#define NEOPIXEL_PIN GPIO_NUM_21
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONTROL_REV_2_0
|
||||||
|
#ifndef CONTROL_REV_2_1
|
||||||
|
#error "define rev2.0 or rev2.1"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
// 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution)
|
// 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution)
|
||||||
#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000)
|
#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000)
|
||||||
|
|
||||||
extern led_strip_handle_t leds;
|
enum LEDColor: uint32_t {
|
||||||
|
LED_COLOR_OFF = 0x00'00'00,
|
||||||
|
LED_COLOR_RED = 0x17'00'00,
|
||||||
|
LED_COLOR_RED_STRONG = 0xFF'00'00,
|
||||||
|
LED_COLOR_ORANGE = 0x17'02'00,
|
||||||
|
LED_COLOR_ORANGE_STRONG = 0xFF'20'00,
|
||||||
|
LED_COLOR_YELLOW = 0x07'07'00,
|
||||||
|
LED_COLOR_YELLOW_STRONG = 0xFF'FF'00,
|
||||||
|
LED_COLOR_GREEN = 0x00'07'00,
|
||||||
|
LED_COLOR_GREEN_STRONG = 0x00'FF'00,
|
||||||
|
LED_COLOR_BLUE = 0x00'00'17,
|
||||||
|
LED_COLOR_BLUE_STRONG = 0x00'00'FF,
|
||||||
|
LED_COLOR_PINK = 0x10'00'04,
|
||||||
|
LED_COLOR_PINK_STRONG = 0xFF'00'80,
|
||||||
|
LED_COLOR_WHITE = 0x04'04'04,
|
||||||
|
LED_COLOR_WHITE_STRONG = 0xFF'FF'FF,
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum {
|
enum IndicatorLED {
|
||||||
shape1 = 0,
|
LED_SHAPE1 = 0u,
|
||||||
shape2 = 1,
|
LED_SHAPE2 = 1u,
|
||||||
shape3 = 2,
|
LED_SHAPE3 = 2u,
|
||||||
shape4 = 3,
|
LED_SHAPE4 = 3u,
|
||||||
module_sseg = 4,
|
LED_MODULE_SSEG = 4u,
|
||||||
game_sseg = 5,
|
LED_GAME_SSEG = 5u,
|
||||||
tft = 6,
|
LED_TFT = 6u,
|
||||||
mic = 7,
|
LED_MIC = 7u,
|
||||||
ir_led = 8,
|
LED_IR_LED = 8u,
|
||||||
speaker = 9,
|
LED_SPEAKER = 9u,
|
||||||
rfid = 10,
|
LED_RFID = 10u,
|
||||||
keypad = 11,
|
LED_KEYPAD = 11u,
|
||||||
char_lcd = 12,
|
LED_LCD = 12u,
|
||||||
switch4 = 13,
|
LED_S4 = 13u,
|
||||||
switch3 = 14,
|
LED_S3 = 14u,
|
||||||
switch2 = 15,
|
LED_S2 = 15u,
|
||||||
switch1 = 16,
|
LED_S1 = 16u,
|
||||||
button4 = 17,
|
LED_B4 = 17u,
|
||||||
button3 = 18,
|
LED_B3 = 18u,
|
||||||
button2 = 19,
|
LED_B2 = 19u,
|
||||||
button1 = 20,
|
LED_B1 = 20u,
|
||||||
} Led;
|
LED_MAX = 20u,
|
||||||
|
};
|
||||||
|
|
||||||
void init_leds(void);
|
/// @brief Initializes the indicator LEDs
|
||||||
void example_leds(void);
|
void init_leds();
|
||||||
|
|
||||||
|
/// Sets the color of an LED.
|
||||||
|
///
|
||||||
|
/// Call `flush_leds()` to send the data to the LEDs.
|
||||||
|
void led_set(uint32_t led, uint32_t color);
|
||||||
|
|
||||||
|
/// Sets the color of an LED with rgb.
|
||||||
|
///
|
||||||
|
/// Call `flush_leds()` to send the data to the LEDs.
|
||||||
|
void led_set(uint32_t led, uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
|
/// Outputs the data to the leds.
|
||||||
|
void leds_flush();
|
||||||
|
|
||||||
|
/// Clears the LEDs
|
||||||
|
void leds_clear();
|
||||||
|
|
||||||
#endif /* LEDS_H */
|
#endif /* LEDS_H */
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef PINS_H
|
||||||
|
#define PINS_H
|
||||||
|
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
// ONLY INPUTS.HPP uses this file
|
||||||
|
|
||||||
|
#define PIN_SDA (GPIO_NUM_7)
|
||||||
|
#define PIN_SCL (GPIO_NUM_15)
|
||||||
|
|
||||||
|
#define PIN_LCD_MISO (GPIO_NUM_16)
|
||||||
|
#define PIN_LCD_MOSI (GPIO_NUM_17)
|
||||||
|
#define PIN_LCD_CLK (GPIO_NUM_18)
|
||||||
|
#define PIN_LCD_RS (GPIO_NUM_8)
|
||||||
|
#define PIN_LCD_RST (GPIO_NUM_9)
|
||||||
|
|
||||||
|
#define PIN_USB_DM (GPIO_NUM_19)
|
||||||
|
#define PIN_USB_DP (GPIO_NUM_20)
|
||||||
|
|
||||||
|
#define PIN_I2S_DAT (GPIO_NUM_3)
|
||||||
|
#define PIN_I2S_BCLK (GPIO_NUM_11)
|
||||||
|
#define PIN_I2S_LRCLK (GPIO_NUM_12)
|
||||||
|
|
||||||
|
#define PIN_SSEG_DAT (GPIO_NUM_46)
|
||||||
|
#define PIN_SSEG_CLK (GPIO_NUM_48)
|
||||||
|
|
||||||
|
#define PIN_MPU_INT (GPIO_NUM_10)
|
||||||
|
#define PIN_EXPANDER_INT (GPIO_NUM_13)
|
||||||
|
|
||||||
|
#define PIN_IR_RCV (GPIO_NUM_14)
|
||||||
|
|
||||||
|
// #define PIN_NEOPIXEL (GPIO_NUM_21) // Rev 2.1
|
||||||
|
#define PIN_NEOPIXEL (GPIO_NUM_0) // Rev 2.0
|
||||||
|
|
||||||
|
#define PIN_SD_DAT0 (GPIO_NUM_38)
|
||||||
|
#define PIN_SD_DAT1 (GPIO_NUM_47)
|
||||||
|
#define PIN_SD_DAT2 (GPIO_NUM_42)
|
||||||
|
#define PIN_SD_DAT3 (GPIO_NUM_41)
|
||||||
|
#define PIN_SD_CMD (GPIO_NUM_40)
|
||||||
|
#define PIN_SD_CLK (GPIO_NUM_39)
|
||||||
|
|
||||||
|
#define PIN_PERH0 (GPIO_NUM_6)
|
||||||
|
#define PIN_PERH1 (GPIO_NUM_5)
|
||||||
|
#define PIN_PERH2 (GPIO_NUM_4)
|
||||||
|
#define PIN_PERH3 (GPIO_NUM_2)
|
||||||
|
#define PIN_PERH4 (GPIO_NUM_1)
|
||||||
|
|
||||||
|
#endif // PINS_H
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "char_lcd.h"
|
#include "char_lcd.h"
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
static const char* TAG = "POWER";
|
static const char* TAG = "power";
|
||||||
|
|
||||||
void bat_monitor_task(void* arg) {
|
void bat_monitor_task(void* arg) {
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -36,12 +37,17 @@ void bat_monitor_task(void* arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init_power_board() {
|
void init_power_board() {
|
||||||
|
ESP_LOGI(TAG, "Initializing power board...");
|
||||||
|
|
||||||
if (!lipo.begin()) {
|
if (!lipo.begin()) {
|
||||||
ESP_LOGE(TAG, "Failed to init communication with the battery gas guage");
|
ESP_LOGE(TAG, "Failed to init communication with the battery gas guage");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto voltage = lipo.voltage();
|
auto voltage = lipo.voltage();
|
||||||
ESP_LOGI(TAG, "Battery Voltage: %d", voltage);
|
ESP_LOGI(TAG, "Battery Voltage: %d", voltage);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Power board initialized!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
#define POWER_H
|
#define POWER_H
|
||||||
|
|
||||||
#include "SparkFunBQ27441/SparkFunBQ27441.h"
|
#include "SparkFunBQ27441/SparkFunBQ27441.h"
|
||||||
#include <esp_log.h>
|
|
||||||
|
|
||||||
void bat_monitor_task(void* arg);
|
void bat_monitor_task(void* arg);
|
||||||
|
|
||||||
/// Initializes the battery gas guage for getting battery stats.
|
/// Initializes the battery gas guage for getting battery stats.
|
||||||
void init_power_board();
|
void init_power_board();
|
||||||
|
|
||||||
|
/// @brief Gets the battery voltage
|
||||||
|
/// @return battery voltage in mV.
|
||||||
uint16_t get_bat_voltage();
|
uint16_t get_bat_voltage();
|
||||||
|
|
||||||
#endif /* POWER_H */
|
#endif /* POWER_H */
|
||||||
|
|||||||
+17
-8
@@ -1,6 +1,7 @@
|
|||||||
#ifndef SD_H
|
#ifndef SD_H
|
||||||
#define SD_H
|
#define SD_H
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@@ -8,22 +9,30 @@
|
|||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
#include "driver/sdmmc_host.h"
|
#include "driver/sdmmc_host.h"
|
||||||
|
|
||||||
#define MOUNT_POINT "/sdcard"
|
#define MOUNT_POINT "/sd"
|
||||||
|
|
||||||
extern sdmmc_card_t *card;
|
extern sdmmc_card_t *card;
|
||||||
|
|
||||||
#define SD_PIN_CLK GPIO_NUM_48
|
#define SD_PIN_CLK GPIO_NUM_39
|
||||||
#define SD_PIN_CMD GPIO_NUM_45
|
#define SD_PIN_CMD GPIO_NUM_40
|
||||||
#define SD_PIN_D0 GPIO_NUM_47
|
#define SD_PIN_D0 GPIO_NUM_38
|
||||||
#define SD_PIN_D1 GPIO_NUM_21
|
#define SD_PIN_D2 GPIO_NUM_42
|
||||||
#define SD_PIN_D2 GPIO_NUM_39
|
#define SD_PIN_D3 GPIO_NUM_41
|
||||||
#define SD_PIN_D3 GPIO_NUM_38
|
|
||||||
|
#ifdef CONTROL_REV_2_0
|
||||||
|
#define SD_PIN_D1 GPIO_NUM_45
|
||||||
|
#endif
|
||||||
|
#ifdef CONTROL_REV_2_1
|
||||||
|
#define SD_PIN_D1 GPIO_NUM_47
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief Initializes the SD card
|
/// @brief Initializes the SD card
|
||||||
///
|
///
|
||||||
/// This requires the char_lcd to have been initialized.
|
/// This requires the char_lcd to have been initialized.
|
||||||
/// @return
|
/// @return true if the sd card was successfully initialized
|
||||||
bool init_sd();
|
bool init_sd();
|
||||||
|
|
||||||
|
/// @brief Unmounts the sd card
|
||||||
void deinit_sd();
|
void deinit_sd();
|
||||||
|
|
||||||
#endif /* SD_H */
|
#endif /* SD_H */
|
||||||
+215
-92
@@ -1,109 +1,219 @@
|
|||||||
#include "speaker.h"
|
#include "speaker.h"
|
||||||
|
#include "state_tracking.h"
|
||||||
i2s_chan_handle_t tx_chan;
|
|
||||||
|
|
||||||
static const char *TAG = "speaker";
|
static const char *TAG = "speaker";
|
||||||
|
|
||||||
esp_err_t play_raw_stop_queue(const char *fp, QueueHandle_t stop_handle) {
|
static size_t audio_block_size = 4096;
|
||||||
FILE *fh = fopen(fp, "rb");
|
|
||||||
if (fh == NULL) {
|
typedef struct {
|
||||||
ESP_LOGE(TAG, "Failed to open file");
|
/// The path to the file being played.
|
||||||
return ESP_ERR_INVALID_ARG;
|
char* file_name;
|
||||||
|
/// The handle to the file being played.
|
||||||
|
FILE* file_handle;
|
||||||
|
/// A number that all samples will be shifted right by.
|
||||||
|
uint8_t prescaler;
|
||||||
|
/// A flag for repeating.
|
||||||
|
bool repeat;
|
||||||
|
} playing_audio_clip_t;
|
||||||
|
|
||||||
|
// It's hard to get the tx_chan's internal state, so instead, we keep track of it here.
|
||||||
|
bool channel_enabled = false;
|
||||||
|
i2s_chan_handle_t tx_chan;
|
||||||
|
|
||||||
|
/// A queue of owned `char*` to be stopped from playing.
|
||||||
|
///
|
||||||
|
/// the speaker driver system will free the given char* when it is done with it.
|
||||||
|
QueueHandle_t stop_clip_queue;
|
||||||
|
/// A queue of `audio_clip_t`s to be played once there is nothing being played
|
||||||
|
QueueHandle_t play_clip_queue;
|
||||||
|
|
||||||
|
/// The clips that are currently playing
|
||||||
|
std::vector<playing_audio_clip_t> playing_clips;
|
||||||
|
|
||||||
|
static bool replay_handler(const char* event, char* arg) {
|
||||||
|
if (strcmp(event, "PLAY_WAV") == 0) {
|
||||||
|
char* file_name = strtok(arg, ":");
|
||||||
|
char* play_immediately_str = strtok(NULL, ":");
|
||||||
|
char* repeat_str = strtok(NULL, ":");
|
||||||
|
char* prescaler_str = strtok(NULL, ":");
|
||||||
|
|
||||||
|
bool play_immediately = strcmp(play_immediately_str, "true") == 0;
|
||||||
|
bool repeat = strcmp(repeat_str, "true") == 0;
|
||||||
|
uint8_t prescaler = atoi(prescaler_str);
|
||||||
|
play_clip_wav(file_name, play_immediately, repeat, prescaler, 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "STOP_WAV") == 0) {
|
||||||
|
stop_clip(arg, 0);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a writer buffer
|
return false;
|
||||||
uint8_t *read_buf = (uint8_t*) calloc(AUDIO_BUFFER, sizeof(uint8_t));
|
|
||||||
uint16_t *write_buf = (uint16_t*) calloc(AUDIO_BUFFER, sizeof(uint16_t));
|
|
||||||
size_t bytes_read = 0;
|
|
||||||
size_t bytes_written = 0;
|
|
||||||
|
|
||||||
esp_err_t channel_enable_result = i2s_channel_enable(tx_chan);
|
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(channel_enable_result);
|
|
||||||
if (channel_enable_result != ESP_OK) {
|
|
||||||
return channel_enable_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes_read = fread(read_buf, sizeof(uint8_t), AUDIO_BUFFER, fh);
|
|
||||||
for (int i = 0; i < bytes_read; i++) {
|
|
||||||
write_buf[i] = read_buf[i] << 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// i2s_channel_enable(tx_handle);
|
|
||||||
|
|
||||||
while (bytes_read > 0) {
|
|
||||||
// write the buffer to the i2s
|
|
||||||
// ESP_LOGI(TAG, "Writing: ");
|
|
||||||
// for (int i = 0; i < words_read; i++) {
|
|
||||||
// int16_t val = buf[i];
|
|
||||||
// printf("%s0x%04X ", (val < 0 ? "-" : "+"), (val < 0 ? -val : val));
|
|
||||||
// }>
|
|
||||||
i2s_channel_write(tx_chan, write_buf, bytes_read * sizeof(int16_t), &bytes_written, portMAX_DELAY);
|
|
||||||
bytes_read = fread(read_buf, sizeof(uint8_t), AUDIO_BUFFER, fh);
|
|
||||||
for (int i = 0; i < bytes_read; i++) {
|
|
||||||
write_buf[i] = read_buf[i] << 4;
|
|
||||||
}
|
|
||||||
uint8_t recv = 0;
|
|
||||||
if (xQueueReceive(stop_handle, &recv, 0)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
i2s_channel_disable(tx_chan);
|
|
||||||
free(read_buf);
|
|
||||||
free(write_buf);
|
|
||||||
fclose(fh);
|
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t play_raw(const char *fp) {
|
static bool push_clip(audio_clip_t clip) {
|
||||||
FILE *fh = fopen(fp, "rb");
|
ESP_LOGD(TAG, "playing %s", clip.file_name);
|
||||||
if (fh == NULL)
|
FILE* fh = fopen(clip.file_name, "rb");
|
||||||
ESP_LOGE(TAG, "Failed to open file");
|
if (fh == NULL) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
ESP_LOGW(TAG, "failed to open %s", clip.file_name);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// skip the .wav header
|
||||||
|
fseek(fh, 44, SEEK_SET);
|
||||||
|
|
||||||
|
playing_audio_clip_t playing_clip = {
|
||||||
|
.file_name = clip.file_name,
|
||||||
|
.file_handle = fh,
|
||||||
|
.prescaler = clip.prescaler,
|
||||||
|
.repeat = clip.repeat,
|
||||||
|
};
|
||||||
|
playing_clips.push_back(playing_clip);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create a writer buffer
|
/// @brief Disables the channel if neccesary.
|
||||||
uint8_t *read_buf = (uint8_t*) calloc(AUDIO_BUFFER, sizeof(uint8_t));
|
static void disable_channel() {
|
||||||
uint16_t *write_buf = (uint16_t*) calloc(AUDIO_BUFFER, sizeof(uint16_t));
|
if (channel_enabled) {
|
||||||
size_t bytes_read = 0;
|
ESP_ERROR_CHECK_WITHOUT_ABORT(i2s_channel_disable(tx_chan));
|
||||||
size_t bytes_written = 0;
|
channel_enabled = false;
|
||||||
|
|
||||||
esp_err_t channel_enable_result = i2s_channel_enable(tx_chan);
|
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(channel_enable_result);
|
|
||||||
if (channel_enable_result != ESP_OK) {
|
|
||||||
return channel_enable_result;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bytes_read = fread(read_buf, sizeof(uint8_t), AUDIO_BUFFER, fh);
|
/// @brief Enables the channel if neccesary
|
||||||
for (int i = 0; i < bytes_read; i++) {
|
static void enable_channel() {
|
||||||
write_buf[i] = read_buf[i] << 4;
|
if (!channel_enabled) {
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(i2s_channel_enable(tx_chan));
|
||||||
|
channel_enabled = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// i2s_channel_enable(tx_handle);
|
static void speaker_task(void* arg) {
|
||||||
|
audio_clip_t next_clip;
|
||||||
|
char* clip_to_stop;
|
||||||
|
|
||||||
while (bytes_read > 0) {
|
int16_t* audio_buf = (int16_t*) malloc(audio_block_size * sizeof(int16_t));
|
||||||
// write the buffer to the i2s
|
int16_t* file_buf = (int16_t*) malloc(audio_block_size * sizeof(int16_t));
|
||||||
// ESP_LOGI(TAG, "Writing: ");
|
|
||||||
// for (int i = 0; i < words_read; i++) {
|
while (1) {
|
||||||
// int16_t val = buf[i];
|
// first, take all "play immediatly" clips from the queue.
|
||||||
// printf("%s0x%04X ", (val < 0 ? "-" : "+"), (val < 0 ? -val : val));
|
while (xQueuePeek(play_clip_queue, &next_clip, 0) == pdTRUE && next_clip.play_immediatly) {
|
||||||
// }>
|
if (xQueueReceive(play_clip_queue, &next_clip, 0) == pdTRUE) {
|
||||||
i2s_channel_write(tx_chan, write_buf, bytes_read * sizeof(int16_t), &bytes_written, portMAX_DELAY);
|
push_clip(next_clip);
|
||||||
bytes_read = fread(read_buf, sizeof(uint8_t), AUDIO_BUFFER, fh);
|
}
|
||||||
for (int i = 0; i < bytes_read; i++) {
|
}
|
||||||
write_buf[i] = read_buf[i] << 4;
|
|
||||||
|
// handle any stop requests
|
||||||
|
while (xQueueReceive(stop_clip_queue, &clip_to_stop, 0) == pdTRUE) {
|
||||||
|
// delete clip from list
|
||||||
|
bool found = false;
|
||||||
|
for (int clip_idx = playing_clips.size()-1; clip_idx >= 0; clip_idx--) {
|
||||||
|
playing_audio_clip_t& clip = playing_clips.at(clip_idx);
|
||||||
|
if (strcmp(clip.file_name, clip_to_stop) == 0) {
|
||||||
|
found = true;
|
||||||
|
ESP_LOGV(TAG, "stopping %s", clip.file_name);
|
||||||
|
fclose(clip.file_handle);
|
||||||
|
free(clip.file_name);
|
||||||
|
playing_clips.erase(playing_clips.begin() + clip_idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
ESP_LOGW(TAG, "Could not find clip \"%s\" to stop", clip_to_stop);
|
||||||
|
}
|
||||||
|
// free the string that was passed into the queue
|
||||||
|
free(clip_to_stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we aren't playing any clips, wait for the next one.
|
||||||
|
if (playing_clips.empty()) {
|
||||||
|
if (xQueueReceive(play_clip_queue, &next_clip, 0) == pdTRUE) {
|
||||||
|
push_clip(next_clip);
|
||||||
|
} else {
|
||||||
|
// we must wait before our next clip
|
||||||
|
disable_channel();
|
||||||
|
// now wait for next clip
|
||||||
|
if (xQueueReceive(play_clip_queue, &next_clip, portMAX_DELAY) == pdTRUE) {
|
||||||
|
push_clip(next_clip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send 1 block
|
||||||
|
std::memset(audio_buf, 0, audio_block_size * sizeof(int16_t));
|
||||||
|
|
||||||
|
for (int clip_idx = playing_clips.size()-1; clip_idx >= 0; clip_idx--) {
|
||||||
|
playing_audio_clip_t& clip = playing_clips.at(clip_idx);
|
||||||
|
|
||||||
|
size_t samples_read = fread(file_buf, sizeof(uint16_t), audio_block_size, clip.file_handle);
|
||||||
|
if (samples_read == 0) {
|
||||||
|
if (clip.repeat) {
|
||||||
|
ESP_LOGV(TAG, "repeating %s", clip.file_name);
|
||||||
|
fseek(clip.file_handle, 44, SEEK_SET);
|
||||||
|
} else {
|
||||||
|
ESP_LOGV(TAG, "finishing %s", clip.file_name);
|
||||||
|
fclose(clip.file_handle);
|
||||||
|
free(clip.file_name);
|
||||||
|
playing_clips.erase(playing_clips.begin() + clip_idx);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < samples_read; i++) {
|
||||||
|
audio_buf[i] += (file_buf[i] >> clip.prescaler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bytes_to_write = audio_block_size * sizeof(int16_t);
|
||||||
|
size_t bytes_written;
|
||||||
|
if (!channel_enabled) {
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(i2s_channel_preload_data(tx_chan, audio_buf, bytes_to_write, &bytes_written));
|
||||||
|
enable_channel();
|
||||||
|
} else {
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(i2s_channel_write(tx_chan, audio_buf, bytes_to_write, &bytes_written, portMAX_DELAY));
|
||||||
|
}
|
||||||
|
if (bytes_written != bytes_to_write) {
|
||||||
|
ESP_LOGW(TAG, "only %d bytes written to the i2s channel! (expected %d)", bytes_written, bytes_to_write);
|
||||||
}
|
}
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i2s_channel_disable(tx_chan);
|
vTaskDelete(NULL);
|
||||||
free(read_buf);
|
}
|
||||||
free(write_buf);
|
|
||||||
fclose(fh);
|
|
||||||
|
|
||||||
return ESP_OK;
|
bool play_clip_wav(const char* file_name, bool play_immediately, bool repeat, uint8_t prescaler, TickType_t ticks_to_wait) {
|
||||||
|
// clone the passed in string to the heap.
|
||||||
|
size_t len = strlen(file_name);
|
||||||
|
char* dynamic_file_name = (char*) malloc(len+1);
|
||||||
|
strcpy(dynamic_file_name, file_name);
|
||||||
|
|
||||||
|
audio_clip_t clip = {
|
||||||
|
.file_name = dynamic_file_name,
|
||||||
|
.prescaler = prescaler,
|
||||||
|
.repeat = repeat,
|
||||||
|
.play_immediatly = play_immediately,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
char buf[64];
|
||||||
|
sprintf(buf, "%s:%d:%d:%d", file_name, play_immediately, repeat, prescaler);
|
||||||
|
event_occured("PLAY_WAV", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (play_immediately) {
|
||||||
|
return xQueueSendToFront(play_clip_queue, &clip, ticks_to_wait) == pdTRUE;
|
||||||
|
}
|
||||||
|
return xQueueSend(play_clip_queue, &clip, ticks_to_wait) == pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stop_clip(const char* file_name, TickType_t ticks_to_wait) {
|
||||||
|
// clone the passed in string to the heap.
|
||||||
|
size_t len = strlen(file_name);
|
||||||
|
char* dynamic_file_name = (char*) malloc(len+1);
|
||||||
|
strcpy(dynamic_file_name, file_name);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("STOP_WAV", file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return xQueueSend(stop_clip_queue, &dynamic_file_name, ticks_to_wait) == pdTRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_speaker(void) {
|
void init_speaker(void) {
|
||||||
@@ -130,9 +240,22 @@ void init_speaker(void) {
|
|||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &tx_std_cfg));
|
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &tx_std_cfg));
|
||||||
|
|
||||||
|
i2s_chan_info_t info = {};
|
||||||
|
i2s_channel_get_info(tx_chan, &info);
|
||||||
|
if (info.total_dma_buf_size != 0) {
|
||||||
|
audio_block_size = info.total_dma_buf_size / sizeof(int16_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// init queues
|
||||||
|
play_clip_queue = xQueueCreate(CLIP_QUEUE_SIZE, sizeof(audio_clip_t));
|
||||||
|
stop_clip_queue = xQueueCreate(CLIP_QUEUE_SIZE, sizeof(char*));
|
||||||
|
|
||||||
|
// start task
|
||||||
|
xTaskCreate(speaker_task, "play_audio", 4096, NULL, 5, NULL);
|
||||||
|
|
||||||
|
play_clip_wav(MOUNT_POINT "/startup.wav", true, false, 4, 0);
|
||||||
|
|
||||||
|
register_replay_fn(replay_handler);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Speaker initialized!");
|
ESP_LOGI(TAG, "Speaker initialized!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void play_example() {
|
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(play_raw("/sdcard/o.pcm"));
|
|
||||||
}
|
|
||||||
|
|||||||
+41
-10
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
#include <vector>
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
@@ -12,21 +15,49 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "sd.h"
|
#include "sd.h"
|
||||||
|
|
||||||
#define SPEAKER_PIN_BCLK GPIO_NUM_46
|
#define SPEAKER_PIN_BCLK GPIO_NUM_11
|
||||||
#define SPEAKER_PIN_WS GPIO_NUM_9
|
#define SPEAKER_PIN_WS GPIO_NUM_12
|
||||||
#define SPEAKER_PIN_DOUT GPIO_NUM_3
|
#define SPEAKER_PIN_DOUT GPIO_NUM_3
|
||||||
#define SAMPLE_RATE 44100
|
#define SAMPLE_RATE 44100
|
||||||
#define AUDIO_BUFFER 2048
|
// The maximum number of clips that can be queued at one time.
|
||||||
|
#define CLIP_QUEUE_SIZE 64
|
||||||
|
|
||||||
extern i2s_chan_handle_t tx_chan;
|
extern i2s_chan_handle_t tx_chan;
|
||||||
|
|
||||||
/// Plays a audio file stopping when something is received on `stop_handle`
|
typedef struct {
|
||||||
///
|
/// A dynamically allocated string specifying the name of the
|
||||||
/// `stop_handle` should be of size `uint8_t`.
|
/// file to play. The speaker system will free this once it
|
||||||
esp_err_t play_raw_stop_queue(const char *fp, QueueHandle_t stop_handle);
|
/// is done.
|
||||||
esp_err_t play_raw(const char *fp);
|
char* file_name;
|
||||||
|
/// A number that all samples will be shifted right by.
|
||||||
|
uint8_t prescaler;
|
||||||
|
/// A flag for repeating.
|
||||||
|
bool repeat;
|
||||||
|
/// A flag for starting the clip immediatly,
|
||||||
|
/// even if there is another clip playing.
|
||||||
|
bool play_immediatly;
|
||||||
|
} audio_clip_t;
|
||||||
|
|
||||||
void init_speaker(void);
|
/// @brief Initalizes the speaker
|
||||||
void play_example();
|
void init_speaker();
|
||||||
|
|
||||||
|
/// @brief Plays a wav audio clip.
|
||||||
|
/// @param file_name The name of the file to play. Fully qualified with the `.wav` extention.
|
||||||
|
/// @param play_immediatly If `true`, the file will play immediatly even if there is already
|
||||||
|
/// another clip being played. The two clips will play simultaniously. If `false` the clip
|
||||||
|
/// will play once all the previous clips have finished.
|
||||||
|
/// @param repeat If `true` the clip will repeat until stopped. If `false` the clip will
|
||||||
|
/// stop when finished.
|
||||||
|
/// @param prescaler A number to shift right all samples by. This makes the music half as
|
||||||
|
/// loud. Useful for loud audio files.
|
||||||
|
/// @param ticks_to_wait The number of ticks to wait if the queue is full.
|
||||||
|
/// @return true if the clip was added to the queue.
|
||||||
|
bool play_clip_wav(const char* file_name, bool play_immediately, bool repeat, uint8_t prescaler, TickType_t ticks_to_wait);
|
||||||
|
|
||||||
|
/// @brief Stops an audio clip from playing.
|
||||||
|
/// @param file_name The file name of the audio clip that was played.
|
||||||
|
/// @param ticks_to_wait The number of ticks to wait if the queue is full.
|
||||||
|
/// @return true if the clip was added to the queue.
|
||||||
|
bool stop_clip(const char* file_name, TickType_t ticks_to_wait);
|
||||||
|
|
||||||
#endif /* SPEAKER_H */
|
#endif /* SPEAKER_H */
|
||||||
+112
-13
@@ -1,39 +1,138 @@
|
|||||||
#include "sseg.h"
|
#include "sseg.h"
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include "state_tracking.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
TM1640* sseg = nullptr;
|
TM1640* sseg = nullptr;
|
||||||
|
|
||||||
static const char *TAG = "sseg_driver";
|
static const char *TAG = "sseg";
|
||||||
|
|
||||||
|
static bool replay_handler(const char* event, char* arg) {
|
||||||
|
if (strcmp(event, "SSEG_G_RAW") == 0) {
|
||||||
|
uint8_t segments[4];
|
||||||
|
segments[0] = atoi(strtok(arg, ","));
|
||||||
|
for (int i = 1; i < 4; i++) {
|
||||||
|
segments[i] = atoi(strtok(NULL, ","));
|
||||||
|
}
|
||||||
|
set_game_sseg_raw(segments);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "SSEG_G_CLR") == 0) {
|
||||||
|
clear_game_sseg();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "SSEG_M_RAW") == 0) {
|
||||||
|
uint8_t segments[4];
|
||||||
|
segments[0] = atoi(strtok(arg, ","));
|
||||||
|
for (int i = 1; i < 4; i++) {
|
||||||
|
segments[i] = atoi(strtok(NULL, ","));
|
||||||
|
}
|
||||||
|
set_module_sseg_raw(segments);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "SSEG_M_CLR") == 0) {
|
||||||
|
clear_module_sseg();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "SSEG_G") == 0) {
|
||||||
|
uint32_t value = atoi(strtok(arg, ","));
|
||||||
|
uint8_t dot_pos = atoi(strtok(NULL, ","));
|
||||||
|
set_game_sseg_num(value, dot_pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(event, "SSEG_M") == 0) {
|
||||||
|
uint32_t value = atoi(strtok(arg, ","));
|
||||||
|
uint8_t dot_pos = atoi(strtok(NULL, ","));
|
||||||
|
set_module_sseg_num(value, dot_pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void init_sseg() {
|
void init_sseg() {
|
||||||
|
ESP_LOGI(TAG, "Initializing sseg...");
|
||||||
|
|
||||||
sseg = new TM1640(SSEG_PIN_DATA, SSEG_PIN_CLK, 8);
|
sseg = new TM1640(SSEG_PIN_DATA, SSEG_PIN_CLK, 8);
|
||||||
|
|
||||||
|
register_replay_fn(replay_handler);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Sseg initialized!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_game_sseg_raw(const uint8_t* digits) {
|
void set_game_sseg_raw(const uint8_t* segments) {
|
||||||
sseg->setSegments(digits[0], 0);
|
sseg->setSegments(segments[0], 0);
|
||||||
sseg->setSegments(digits[1], 1);
|
sseg->setSegments(segments[1], 1);
|
||||||
sseg->setSegments(digits[2], 2);
|
sseg->setSegments(segments[2], 2);
|
||||||
sseg->setSegments(digits[3], 3);
|
sseg->setSegments(segments[3], 3);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf, "%d,%d,%d,%d", segments[0], segments[1], segments[2], segments[3]);
|
||||||
|
event_occured("SSEG_G_RAW", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void clear_game_sseg() {
|
||||||
|
sseg->setSegments(0, 0);
|
||||||
|
sseg->setSegments(0, 1);
|
||||||
|
sseg->setSegments(0, 2);
|
||||||
|
sseg->setSegments(0, 3);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("SSEG_G_CLR", NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_module_sseg_raw(const uint8_t* digits) {
|
void set_module_sseg_raw(const uint8_t* segments) {
|
||||||
sseg->setSegments(digits[0], 4);
|
sseg->setSegments(segments[0], 4);
|
||||||
sseg->setSegments(digits[1], 5);
|
sseg->setSegments(segments[1], 5);
|
||||||
sseg->setSegments(digits[2], 6);
|
sseg->setSegments(segments[2], 6);
|
||||||
sseg->setSegments(digits[3], 7);
|
sseg->setSegments(segments[3], 7);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf, "%d,%d,%d,%d", segments[0], segments[1], segments[2], segments[3]);
|
||||||
|
event_occured("SSEG_M_RAW", buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_game_sseg_num(unsigned int value, int dot_pos) {
|
void clear_module_sseg() {
|
||||||
|
sseg->setSegments(0, 4);
|
||||||
|
sseg->setSegments(0, 5);
|
||||||
|
sseg->setSegments(0, 6);
|
||||||
|
sseg->setSegments(0, 7);
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
event_occured("SSEG_M_CLR", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_game_sseg_num(uint32_t value, uint8_t dot_pos) {
|
||||||
|
uint32_t initial_value = value;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
auto idx = value % 10;
|
auto idx = value % 10;
|
||||||
sseg->sendChar(3-i, TM16XX_NUMBER_FONT[idx], i == dot_pos);
|
sseg->sendChar(3-i, TM16XX_NUMBER_FONT[idx], i == dot_pos);
|
||||||
value = value / 10;
|
value = value / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
char buf[16];
|
||||||
|
sprintf(buf, "%ld,%d", initial_value, dot_pos);
|
||||||
|
event_occured("SSEG_G", buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_module_sseg_num(unsigned int value, int dot_pos) {
|
void set_module_sseg_num(uint32_t value, uint8_t dot_pos) {
|
||||||
|
uint32_t initial_value = value;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
auto idx = value % 10;
|
auto idx = value % 10;
|
||||||
sseg->sendChar(7-i, TM16XX_NUMBER_FONT[idx], i == dot_pos);
|
sseg->sendChar(7-i, TM16XX_NUMBER_FONT[idx], i == dot_pos);
|
||||||
value = value / 10;
|
value = value / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
char buf[16];
|
||||||
|
sprintf(buf, "%ld,%d", initial_value, dot_pos);
|
||||||
|
event_occured("SSEG_M", buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-8
@@ -4,32 +4,38 @@
|
|||||||
#include "TM1640/TM1640.h"
|
#include "TM1640/TM1640.h"
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
|
|
||||||
#define SSEG_PIN_DATA GPIO_NUM_10
|
#define SSEG_PIN_DATA GPIO_NUM_46
|
||||||
#define SSEG_PIN_CLK GPIO_NUM_11
|
#define SSEG_PIN_CLK GPIO_NUM_48
|
||||||
|
|
||||||
extern TM1640* sseg;
|
extern TM1640* sseg;
|
||||||
|
|
||||||
/// Initializes the seven segment driver
|
/// Initializes the seven segment driver
|
||||||
void init_sseg();
|
void init_sseg();
|
||||||
|
|
||||||
/// sets the game seven segment to the value of the digits
|
/// @brief Sets the game seven segment to the value of `segments`.
|
||||||
///
|
///
|
||||||
/// the bits 0-6 map to segments A-G, and bit 7 is DP.
|
/// the bits 0-6 map to segments A-G, and bit 7 is DP.
|
||||||
///
|
///
|
||||||
/// `digits` must have len >= 4.
|
/// `digits` must have len >= 4.
|
||||||
void set_game_sseg_raw(const uint8_t* digits);
|
void set_game_sseg_raw(const uint8_t* segments);
|
||||||
|
|
||||||
/// sets the module seven segment to the value of the digits
|
/// @brief Clears the game seven segment display.
|
||||||
|
void clear_game_sseg();
|
||||||
|
|
||||||
|
/// @brief Sets the module seven segment to the value of the `segments`.
|
||||||
///
|
///
|
||||||
/// the bits 0-6 map to segments A-G, and bit 7 is DP.
|
/// the bits 0-6 map to segments A-G, and bit 7 is DP.
|
||||||
///
|
///
|
||||||
/// `digits` must have len >= 4.
|
/// `digits` must have len >= 4.
|
||||||
void set_module_sseg_raw(const uint8_t* digits);
|
void set_module_sseg_raw(const uint8_t* segments);
|
||||||
|
|
||||||
|
/// @brief Clears the game seven segment display.
|
||||||
|
void clear_module_sseg();
|
||||||
|
|
||||||
/// sets the game timer to the given number, with the dot at position `dot_pos` from the right (0 => right-most digit).
|
/// sets the game timer to the given number, with the dot at position `dot_pos` from the right (0 => right-most digit).
|
||||||
void set_game_sseg_num(unsigned int value, int dot_pos);
|
void set_game_sseg_num(uint32_t value, uint8_t dot_pos);
|
||||||
|
|
||||||
/// sets the module timer to the given number, with the dot at position `dot_pos` from the right (0 => right-most digit).
|
/// sets the module timer to the given number, with the dot at position `dot_pos` from the right (0 => right-most digit).
|
||||||
void set_module_sseg_num(unsigned int value, int dot_pos);
|
void set_module_sseg_num(uint32_t value, uint8_t dot_pos);
|
||||||
|
|
||||||
#endif /* SSEG_H */
|
#endif /* SSEG_H */
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
#include "state_tracking.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
static const char* PLAYBACK_TAG = "playback";
|
||||||
|
|
||||||
|
enum state_t {
|
||||||
|
STATE_IDLE = 0,
|
||||||
|
STATE_RECORDING = 1,
|
||||||
|
STATE_PLAYBACK = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<bool(*)(const char*, char*)> replay_fns;
|
||||||
|
|
||||||
|
static bool should_close_recording_stream;
|
||||||
|
static FILE* recording_stream;
|
||||||
|
static uint32_t recording_start_time;
|
||||||
|
TaskHandle_t flush_file_task_handle;
|
||||||
|
|
||||||
|
static bool should_close_playback_stream;
|
||||||
|
static FILE* playback_stream;
|
||||||
|
static uint32_t playback_start_time;
|
||||||
|
TaskHandle_t playback_task_handle;
|
||||||
|
|
||||||
|
static volatile state_t state = STATE_IDLE;
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief Periodically flushes and syncs (if neccesary) the output stream.
|
||||||
|
/// @param arg unused.
|
||||||
|
static void flush_file_task(void* arg) {
|
||||||
|
while (state == STATE_RECORDING && recording_stream != nullptr) {
|
||||||
|
fflush(recording_stream);
|
||||||
|
|
||||||
|
int fd = fileno(recording_stream);
|
||||||
|
if (fd != -1) {
|
||||||
|
fsync(fd);
|
||||||
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_file_task_handle = NULL;
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void playback_task(void* arg) {
|
||||||
|
const size_t size = 16*1024;
|
||||||
|
char* buf = (char*) malloc(size*sizeof(char));
|
||||||
|
if (buf == nullptr) {
|
||||||
|
ESP_LOGE(PLAYBACK_TAG, "buf alloc failure");
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (state == STATE_PLAYBACK && playback_stream != nullptr) {
|
||||||
|
char* ret = fgets(buf, size, playback_stream);
|
||||||
|
if (ret == nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (buf[0] == '\0') {
|
||||||
|
ESP_LOGI(PLAYBACK_TAG, "playback done");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// get rid of the '\n' and possibly '\r' in the string
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
if (buf[i] == '\0') break;
|
||||||
|
if (buf[i] == '\r' || buf[i] == '\n') {
|
||||||
|
buf[i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ESP_LOGI(PLAYBACK_TAG, "handling: %s", buf);
|
||||||
|
|
||||||
|
// look for a comma, indicating the end of the "ticks" part
|
||||||
|
// TODO: replace with strtok
|
||||||
|
size_t comma_pos = 0;
|
||||||
|
for (int i = 0; i < 11; i++) {
|
||||||
|
if (buf[i] == ',') {
|
||||||
|
comma_pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (comma_pos == 0) {
|
||||||
|
ESP_LOGE(PLAYBACK_TAG, "Failed to find comma in playback line");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[comma_pos] = '\0';
|
||||||
|
uint32_t tick = atoi(buf);
|
||||||
|
|
||||||
|
// now look for the colon to indicate the end of the event name
|
||||||
|
size_t colon_pos = 0;
|
||||||
|
int i = comma_pos + 1; // start looking right after the comma
|
||||||
|
while (i < size) {
|
||||||
|
if (buf[i] == ':') {
|
||||||
|
colon_pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (colon_pos == 0) {
|
||||||
|
ESP_LOGE(PLAYBACK_TAG, "Failed to find colon in playback line");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[colon_pos] = '\0';
|
||||||
|
char* event_name = buf + (comma_pos + 1);
|
||||||
|
char* arg = buf + (colon_pos + 1);
|
||||||
|
|
||||||
|
int32_t ticks_to_wait = ((int32_t) tick) - (int32_t)(xTaskGetTickCount() - playback_start_time);
|
||||||
|
|
||||||
|
if (ticks_to_wait < 0) {
|
||||||
|
ESP_LOGW(PLAYBACK_TAG, "Playback is behind by %ld ticks!", ticks_to_wait);
|
||||||
|
}
|
||||||
|
if (ticks_to_wait > 0) {
|
||||||
|
vTaskDelay(ticks_to_wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matched = false;
|
||||||
|
for (const auto& fn : replay_fns) {
|
||||||
|
matched = (fn)(event_name, arg);
|
||||||
|
if (matched) break;
|
||||||
|
}
|
||||||
|
if (!matched) {
|
||||||
|
ESP_LOGW(PLAYBACK_TAG, "Failed to match event: %s!", event_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
playback_task_handle = NULL;
|
||||||
|
|
||||||
|
stop_playback();
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_replay_fn(bool (*replay_fn)(const char*, char*)) {
|
||||||
|
replay_fns.push_back(replay_fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void event_occured(const char* name, const char* arg) {
|
||||||
|
if (state != STATE_RECORDING) return;
|
||||||
|
if (name == nullptr) return;
|
||||||
|
if (recording_stream == nullptr) {
|
||||||
|
ESP_LOGE("state_tracking", "We are in state recording, but recording stream is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg = (arg == nullptr) ? "" : arg;
|
||||||
|
uint32_t ticks = xTaskGetTickCount() - recording_start_time;
|
||||||
|
fprintf(recording_stream, "%ld,%s:%s\n", ticks, name, (arg == nullptr) ? "" : arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool set_recording_source(FILE* stream, bool should_close) {
|
||||||
|
if (state == STATE_RECORDING) return false;
|
||||||
|
|
||||||
|
recording_stream = stream;
|
||||||
|
should_close_recording_stream = should_close;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool set_playback_source(FILE* stream, bool should_close) {
|
||||||
|
if (state == STATE_PLAYBACK) return false;
|
||||||
|
|
||||||
|
playback_stream = stream;
|
||||||
|
should_close_playback_stream = should_close;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool start_recording() {
|
||||||
|
if (state != STATE_IDLE) return false;
|
||||||
|
if (recording_stream == nullptr) return false;
|
||||||
|
|
||||||
|
state = STATE_RECORDING;
|
||||||
|
recording_start_time = xTaskGetTickCount();
|
||||||
|
xTaskCreate(flush_file_task, "flush_recording", 2048, NULL, 2, &flush_file_task_handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stop_recording() {
|
||||||
|
if (state != STATE_RECORDING) return false;
|
||||||
|
|
||||||
|
state = STATE_IDLE;
|
||||||
|
fflush(recording_stream);
|
||||||
|
if (should_close_recording_stream) {
|
||||||
|
fclose(recording_stream);
|
||||||
|
recording_stream = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flush_file_task_handle != nullptr) {
|
||||||
|
vTaskDelete(flush_file_task_handle);
|
||||||
|
flush_file_task_handle = NULL;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool start_playback() {
|
||||||
|
if (state != STATE_IDLE) return false;
|
||||||
|
if (playback_stream == nullptr) return false;
|
||||||
|
|
||||||
|
state = STATE_PLAYBACK;
|
||||||
|
playback_start_time = xTaskGetTickCount();
|
||||||
|
xTaskCreate(playback_task, "playback", 4096, NULL, 2, &playback_task_handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stop_playback() {
|
||||||
|
if (state != STATE_PLAYBACK) return false;
|
||||||
|
|
||||||
|
state = STATE_IDLE;
|
||||||
|
if (should_close_playback_stream) {
|
||||||
|
fclose(playback_stream);
|
||||||
|
playback_stream = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playback_task_handle != nullptr) {
|
||||||
|
// TODO: NO!! This leaks the malloc. Instead, use a queue to request a graceful stop
|
||||||
|
vTaskDelete(playback_task_handle);
|
||||||
|
playback_task_handle = NULL;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_state_tracking() {
|
||||||
|
return state == STATE_RECORDING;
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#ifndef STATE_TRACKING_H
|
||||||
|
#define STATE_TRACKING_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "esp_vfs_fat.h"
|
||||||
|
|
||||||
|
/// @brief Registers function to be called on replay.
|
||||||
|
/// @param replay_callback A function to call to playback the event.
|
||||||
|
void register_replay_fn(bool (*replay_fn)(const char*, char*));
|
||||||
|
|
||||||
|
// TODO: add one for generically responding to all events.
|
||||||
|
|
||||||
|
/// @brief Call this to indicate that the bomb state has transitioned.
|
||||||
|
/// @param name The name of the event that has occured.
|
||||||
|
/// @param arg The serialized data associated with the event.
|
||||||
|
/// This must not contain newline characters such as '\n' or '\r'
|
||||||
|
void event_occured(const char* name, const char* arg);
|
||||||
|
|
||||||
|
/// @brief Sets the recording source.
|
||||||
|
/// @param stream The stream to record to.
|
||||||
|
/// @param should_close whether or not the stream should be closed when finished.
|
||||||
|
/// @return true if the source was updated.
|
||||||
|
bool set_recording_source(FILE* stream, bool should_close);
|
||||||
|
|
||||||
|
/// @brief Sets the playback source.
|
||||||
|
/// @param stream The stream to playback from.
|
||||||
|
/// @param should_close whether or not the stream should be closed when finished.
|
||||||
|
/// @return true if the source was updated.
|
||||||
|
bool set_playback_source(FILE* stream, bool should_close);
|
||||||
|
|
||||||
|
/// @brief Starts recording to the stream specified by `set_recording_source()`.
|
||||||
|
/// @return true if starting recording is successful.
|
||||||
|
bool start_recording();
|
||||||
|
|
||||||
|
/// @brief Stops recording the state.
|
||||||
|
/// @return true if stopping the recording is successful.
|
||||||
|
bool stop_recording();
|
||||||
|
|
||||||
|
/// @brief Starts playing back the recording specified by `set_playback_source()`.
|
||||||
|
/// @return true if starting playback is successful.
|
||||||
|
bool start_playback();
|
||||||
|
|
||||||
|
/// @brief Stops playing back the recording.
|
||||||
|
/// @return true if stopping the playback is successful.
|
||||||
|
bool stop_playback();
|
||||||
|
|
||||||
|
/// @brief Gets weather or not we are tracking the state
|
||||||
|
/// This can be helpful to conditionally do extra computation only
|
||||||
|
/// when we are tracking the state.
|
||||||
|
/// @return
|
||||||
|
bool is_state_tracking();
|
||||||
|
|
||||||
|
#endif /* STATE_TRACKING_H */
|
||||||
+58
-12
@@ -1,4 +1,5 @@
|
|||||||
#include "tft.h"
|
#include "tft.h"
|
||||||
|
#include "state_tracking.h"
|
||||||
|
|
||||||
static const char* TAG = "tft";
|
static const char* TAG = "tft";
|
||||||
|
|
||||||
@@ -16,6 +17,10 @@ static lv_style_t style_screen;
|
|||||||
|
|
||||||
SemaphoreHandle_t xGuiSemaphore;
|
SemaphoreHandle_t xGuiSemaphore;
|
||||||
|
|
||||||
|
static bool replay_handler(const char* event, char* arg) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool notify_lvgl_flush_ready(
|
static bool notify_lvgl_flush_ready(
|
||||||
esp_lcd_panel_io_handle_t panel_io,
|
esp_lcd_panel_io_handle_t panel_io,
|
||||||
esp_lcd_panel_io_event_data_t *edata,
|
esp_lcd_panel_io_event_data_t *edata,
|
||||||
@@ -26,6 +31,14 @@ static bool notify_lvgl_flush_ready(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
/// Base 64 encodes a u16... sort of. This doesn't do any of the fancy padding stuff.
|
||||||
|
static void encode_base64(char* buf, size_t start_idx, uint16_t value) {
|
||||||
|
buf[start_idx+0] = base64_chars[(value >> 10) & 0x3F];
|
||||||
|
buf[start_idx+1] = base64_chars[(value >> 4) & 0x3F];
|
||||||
|
buf[start_idx+2] = base64_chars[(value << 2) & 0x3F];
|
||||||
|
}
|
||||||
|
|
||||||
static void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) {
|
static void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) {
|
||||||
esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data;
|
esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data;
|
||||||
|
|
||||||
@@ -33,7 +46,46 @@ static void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t
|
|||||||
int offsetx2 = area->x2;
|
int offsetx2 = area->x2;
|
||||||
int offsety1 = area->y1;
|
int offsety1 = area->y1;
|
||||||
int offsety2 = area->y2;
|
int offsety2 = area->y2;
|
||||||
|
|
||||||
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
|
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
|
||||||
|
|
||||||
|
// TODO: change this to be a kconfig value
|
||||||
|
#if false
|
||||||
|
|
||||||
|
if (is_state_tracking()) {
|
||||||
|
size_t size = (offsetx2 + 1 - offsetx1) * (offsety2 + 1 - offsety1) + 1;
|
||||||
|
// if (size > 1024) {
|
||||||
|
// ESP_LOGW("tft_track_state", "Write too big (%d)! truncating to 1024!", size);
|
||||||
|
// }
|
||||||
|
// size = MIN(1024, size);
|
||||||
|
|
||||||
|
|
||||||
|
// 24 bytes for the offsets
|
||||||
|
// 3 bytes per encoded color
|
||||||
|
// 1 byte for null terminator
|
||||||
|
size_t alloc_size = 24 + size * 3 + 1;
|
||||||
|
char* buf = (char*)malloc(alloc_size);
|
||||||
|
|
||||||
|
if (buf != nullptr) {
|
||||||
|
size_t initial_offset = sprintf(buf, "%d,%d,%d,%d:", offsetx1, offsety1, offsetx2 + 1, offsety2 + 1);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
size_t index = initial_offset + i * 3;
|
||||||
|
|
||||||
|
// we assume that the size of the color data is 16b
|
||||||
|
static_assert(sizeof(lv_color_t) == sizeof(uint16_t), "lv_color_t must be 16b wide");
|
||||||
|
encode_base64(buf, index, color_map[i].full);
|
||||||
|
}
|
||||||
|
buf[initial_offset + (size-1) * 3 + 1] = '\0';
|
||||||
|
|
||||||
|
event_occured("TFT_W", buf);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE("tft_track_state", "buffer alloc failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR lv_tick_task(void *param) {
|
static void IRAM_ATTR lv_tick_task(void *param) {
|
||||||
@@ -150,10 +202,10 @@ static void guiTask(void *pvParameter) {
|
|||||||
ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &periodic_timer));
|
ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &periodic_timer));
|
||||||
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LVGL_UPDATE_PERIOD_MS * 1000));
|
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LVGL_UPDATE_PERIOD_MS * 1000));
|
||||||
|
|
||||||
screen = lv_disp_get_scr_act(NULL);
|
screen = lv_scr_act();
|
||||||
lv_style_init(&style_screen);
|
lv_style_init(&style_screen);
|
||||||
lv_style_set_bg_color(&style_screen, lv_color_black());
|
lv_style_set_bg_color(&style_screen, lv_color_black());
|
||||||
lv_obj_add_style(lv_scr_act(), &style_screen, LV_STATE_DEFAULT);
|
lv_obj_add_style(screen, &style_screen, LV_STATE_DEFAULT);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
|
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
|
||||||
@@ -169,20 +221,14 @@ static void guiTask(void *pvParameter) {
|
|||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tick_timer_task(void* arg) {
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
lv_task_handler();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_tft() {
|
void init_tft() {
|
||||||
|
ESP_LOGI(TAG, "Initializing TFT...");
|
||||||
|
|
||||||
initialize_spi();
|
initialize_spi();
|
||||||
initialize_display();
|
initialize_display();
|
||||||
xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 5, NULL, 1);
|
xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 5, NULL, 1);
|
||||||
|
|
||||||
// xTaskCreatePinnedToCore(tick_timer_task, "tick_lvgl", 4096, NULL, 5, NULL, 1);
|
register_replay_fn(replay_handler);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "TFT initialization Successful");
|
ESP_LOGI(TAG, "TFT initialized!");
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -44,11 +44,11 @@
|
|||||||
#define SPI_MAX_TRANSFER_SIZE 32768
|
#define SPI_MAX_TRANSFER_SIZE 32768
|
||||||
|
|
||||||
#define TFT_PIN_MOSI GPIO_NUM_17
|
#define TFT_PIN_MOSI GPIO_NUM_17
|
||||||
#define TFT_PIN_MISO GPIO_NUM_18
|
#define TFT_PIN_MISO GPIO_NUM_16
|
||||||
#define TFT_PIN_CLK GPIO_NUM_16
|
#define TFT_PIN_CLK GPIO_NUM_18
|
||||||
#define TFT_PIN_CS GPIO_NUM_NC
|
#define TFT_PIN_CS GPIO_NUM_NC
|
||||||
#define TFT_PIN_DC GPIO_NUM_15
|
#define TFT_PIN_DC GPIO_NUM_8
|
||||||
#define TFT_PIN_RESET GPIO_NUM_8
|
#define TFT_PIN_RESET GPIO_NUM_9
|
||||||
|
|
||||||
#define TFT_INVERT_COLOR false
|
#define TFT_INVERT_COLOR false
|
||||||
|
|
||||||
|
|||||||
+13
-6
@@ -1,10 +1,14 @@
|
|||||||
#include "wires.h"
|
#include "wires.h"
|
||||||
|
|
||||||
|
extern uint32_t current_step;
|
||||||
|
|
||||||
uint32_t total_strikes;
|
uint32_t total_strikes;
|
||||||
|
uint32_t step_strikes[N_STEPS] = {0};
|
||||||
|
uint32_t step_finish_times[N_STEPS] = {0};
|
||||||
|
|
||||||
static const char *TAG = "wires";
|
static const char *TAG = "wires";
|
||||||
|
|
||||||
static const uint32_t STRIKE_TIME_PENALTY = 30'000;
|
const uint32_t STRIKE_TIME_PENALTY = 30'000;
|
||||||
|
|
||||||
static bool button_state;
|
static bool button_state;
|
||||||
static bool button_pressed;
|
static bool button_pressed;
|
||||||
@@ -22,8 +26,8 @@ static void receive_button(void);
|
|||||||
void init_wires(void) {
|
void init_wires(void) {
|
||||||
i2c_config_t wires_conf = {
|
i2c_config_t wires_conf = {
|
||||||
.mode = I2C_MODE_MASTER,
|
.mode = I2C_MODE_MASTER,
|
||||||
.sda_io_num = GPIO_NUM_41,
|
.sda_io_num = PIN_WIRES_SDA,
|
||||||
.scl_io_num = GPIO_NUM_42,
|
.scl_io_num = PIN_WIRES_SCL,
|
||||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||||
.master = {
|
.master = {
|
||||||
@@ -31,8 +35,8 @@ void init_wires(void) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gpio_reset_pin(GPIO_NUM_41);
|
gpio_reset_pin(PIN_WIRES_SDA);
|
||||||
gpio_reset_pin(GPIO_NUM_42);
|
gpio_reset_pin(PIN_WIRES_SCL);
|
||||||
|
|
||||||
ESP_ERROR_CHECK(i2c_param_config(WIRES_I2C_NUM, &wires_conf));
|
ESP_ERROR_CHECK(i2c_param_config(WIRES_I2C_NUM, &wires_conf));
|
||||||
ESP_ERROR_CHECK(i2c_driver_install(WIRES_I2C_NUM, wires_conf.mode, 0, 0, 0));
|
ESP_ERROR_CHECK(i2c_driver_install(WIRES_I2C_NUM, wires_conf.mode, 0, 0, 0));
|
||||||
@@ -83,7 +87,10 @@ void strike(const char* reason) {
|
|||||||
ESP_LOGW("strike!", "%s", reason);
|
ESP_LOGW("strike!", "%s", reason);
|
||||||
lcd_print(0, 3, reason);
|
lcd_print(0, 3, reason);
|
||||||
time_penalty(STRIKE_TIME_PENALTY);
|
time_penalty(STRIKE_TIME_PENALTY);
|
||||||
total_strikes += 1;
|
if (current_step > 0 && current_step <= N_STEPS) {
|
||||||
|
total_strikes += 1;
|
||||||
|
step_strikes[current_step - 1] += 1;
|
||||||
|
}
|
||||||
uint8_t reg = 6;
|
uint8_t reg = 6;
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_to_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, ®, 1, (100 / portTICK_PERIOD_MS)));
|
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_to_device(WIRES_I2C_NUM, WIRES_I2C_ADDR, ®, 1, (100 / portTICK_PERIOD_MS)));
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-1
@@ -7,14 +7,28 @@
|
|||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
#include "drivers/char_lcd.h"
|
#include "drivers/char_lcd.h"
|
||||||
#include "drivers/game_timer.h"
|
#include "drivers/game_timer.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
#define WIRES_PIN_DELTA GPIO_NUM_2
|
|
||||||
|
#define PIN_PERH0 GPIO_NUM_6
|
||||||
|
#define PIN_PERH1 GPIO_NUM_5
|
||||||
|
#define PIN_PERH2 GPIO_NUM_4
|
||||||
|
#define PIN_PERH3 GPIO_NUM_2
|
||||||
|
#define PIN_PERH4 GPIO_NUM_1
|
||||||
|
|
||||||
|
#define WIRES_PIN_DELTA PIN_PERH3
|
||||||
|
#define PIN_WIRES_SDA PIN_PERH1
|
||||||
|
#define PIN_WIRES_SCL PIN_PERH2
|
||||||
#define WIRES_I2C_NUM I2C_NUM_1
|
#define WIRES_I2C_NUM I2C_NUM_1
|
||||||
#define WIRES_I2C_ADDR 125
|
#define WIRES_I2C_ADDR 125
|
||||||
|
|
||||||
#define DELTA_BIT_WIRES 0
|
#define DELTA_BIT_WIRES 0
|
||||||
#define DELTA_BIT_BUTTON 1
|
#define DELTA_BIT_BUTTON 1
|
||||||
|
|
||||||
|
extern const uint32_t STRIKE_TIME_PENALTY;
|
||||||
|
extern uint32_t step_strikes[N_STEPS];
|
||||||
|
extern uint32_t step_finish_times[N_STEPS];
|
||||||
|
|
||||||
extern uint32_t total_strikes;
|
extern uint32_t total_strikes;
|
||||||
|
|
||||||
void init_wires(void);
|
void init_wires(void);
|
||||||
|
|||||||
+90
-24
@@ -7,8 +7,8 @@ void clean_bomb(void) {
|
|||||||
clear_wires_pressed_released_cut();
|
clear_wires_pressed_released_cut();
|
||||||
|
|
||||||
// clear leds
|
// clear leds
|
||||||
led_strip_clear(leds);
|
leds_clear();
|
||||||
led_strip_refresh(leds);
|
leds_flush();
|
||||||
|
|
||||||
// clear module timer
|
// clear module timer
|
||||||
stop_module_timer();
|
stop_module_timer();
|
||||||
@@ -89,40 +89,106 @@ void do_star_codes(StarCodeHandler* star_codes, int star_codes_len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static lv_obj_t* old_scr;
|
||||||
|
static lv_obj_t* scr;
|
||||||
|
|
||||||
static lv_style_t game_results_style;
|
static lv_style_t game_results_style;
|
||||||
static lv_obj_t* game_results_label;
|
static lv_obj_t* overall_results_label;
|
||||||
|
static lv_obj_t* breakdown_results_label;
|
||||||
|
static lv_obj_t* strike_numbers_label;
|
||||||
|
static lv_obj_t* step_times_label;
|
||||||
|
|
||||||
|
static void write_time(char* buf, int32_t game_time) {
|
||||||
|
char minus[2] = "\0";
|
||||||
|
if (game_time < 0) {
|
||||||
|
minus[0] = '-';
|
||||||
|
game_time = -game_time;
|
||||||
|
}
|
||||||
|
|
||||||
static char str_buf[10] = {0};
|
|
||||||
static char* write_time(uint32_t game_time) {
|
|
||||||
uint8_t hours = (game_time / (1000*60*60)) % 10;
|
uint8_t hours = (game_time / (1000*60*60)) % 10;
|
||||||
uint8_t minutes = (game_time / (1000*60)) % 60;
|
uint8_t minutes = (game_time / (1000*60)) % 60;
|
||||||
uint8_t seconds = (game_time / (1000)) % 60;
|
uint8_t seconds = (game_time / (1000)) % 60;
|
||||||
|
|
||||||
sprintf(str_buf, "%d:%02d:%02d", hours, minutes, seconds);
|
sprintf(buf, "%s%d:%02d:%02d", minus, hours, minutes, seconds);
|
||||||
return str_buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uint32_t initial_game_time;
|
extern uint32_t initial_game_time;
|
||||||
void display_game_results(void) {
|
void display_game_results(void) {
|
||||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
while (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdFALSE) vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
lv_style_init(&game_results_style);
|
scr = lv_obj_create(NULL);
|
||||||
lv_style_set_text_color(&game_results_style, lv_color_white());
|
lv_obj_set_style_bg_color(scr, lv_color_black(), LV_STATE_DEFAULT);
|
||||||
lv_style_set_bg_color(&game_results_style, lv_color_black());
|
|
||||||
lv_style_set_bg_opa(&game_results_style, LV_OPA_100);
|
lv_style_init(&game_results_style);
|
||||||
lv_style_set_text_align(&game_results_style, LV_TEXT_ALIGN_CENTER);
|
lv_style_set_text_color(&game_results_style, lv_color_white());
|
||||||
|
// lv_style_set_bg_color(&game_results_style, lv_color_black());
|
||||||
|
lv_style_set_text_align(&game_results_style, LV_TEXT_ALIGN_LEFT);
|
||||||
|
|
||||||
game_results_label = lv_label_create(lv_scr_act());
|
overall_results_label = lv_label_create(scr);
|
||||||
lv_obj_align(game_results_label, LV_ALIGN_CENTER, 0, 0);
|
lv_obj_align(overall_results_label, LV_ALIGN_TOP_LEFT, 20, 20);
|
||||||
lv_obj_add_style(game_results_label, &game_results_style, LV_STATE_DEFAULT);
|
lv_obj_set_size(overall_results_label, 460, 140);
|
||||||
|
lv_obj_add_style(overall_results_label, &game_results_style, LV_STATE_DEFAULT);
|
||||||
|
|
||||||
char buf[100] = {0};
|
breakdown_results_label = lv_label_create(scr);
|
||||||
int32_t time_s = get_game_time();
|
lv_obj_align(breakdown_results_label, LV_ALIGN_BOTTOM_LEFT, 20, 0);
|
||||||
int32_t time_spent = initial_game_time - time_s;
|
lv_obj_set_size(breakdown_results_label, 460, 140);
|
||||||
char* time = write_time(time_spent);
|
lv_obj_add_style(breakdown_results_label, &game_results_style, LV_STATE_DEFAULT);
|
||||||
sprintf(buf, "Finished!\nTotal Time (w/ penalties): %s\nTotal Strikes: %ld", time, total_strikes);
|
|
||||||
|
|
||||||
lv_label_set_text(game_results_label, buf);
|
strike_numbers_label = lv_label_create(scr);
|
||||||
|
lv_obj_align(strike_numbers_label, LV_ALIGN_BOTTOM_LEFT, 90, 0);
|
||||||
|
lv_obj_set_size(strike_numbers_label, 60, 140);
|
||||||
|
lv_obj_add_style(strike_numbers_label, &game_results_style, LV_STATE_DEFAULT);
|
||||||
|
lv_obj_set_style_text_align(strike_numbers_label, LV_TEXT_ALIGN_RIGHT, LV_STATE_DEFAULT);
|
||||||
|
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
step_times_label = lv_label_create(scr);
|
||||||
}
|
lv_obj_align(step_times_label, LV_ALIGN_BOTTOM_LEFT, 140, 0);
|
||||||
|
lv_obj_set_size(step_times_label, 80, 140);
|
||||||
|
lv_obj_add_style(step_times_label, &game_results_style, LV_STATE_DEFAULT);
|
||||||
|
lv_obj_set_style_text_align(step_times_label, LV_TEXT_ALIGN_RIGHT, LV_STATE_DEFAULT);
|
||||||
|
|
||||||
|
char buf[1024] = {0};
|
||||||
|
|
||||||
|
char time_buf_1[32] = {0};
|
||||||
|
char time_buf_2[32] = {0};
|
||||||
|
char time_buf_3[32] = {0};
|
||||||
|
char time_buf_4[32] = {0};
|
||||||
|
char time_buf_5[32] = {0};
|
||||||
|
char time_buf_6[32] = {0};
|
||||||
|
|
||||||
|
int32_t time_left = get_game_time();
|
||||||
|
int32_t time_spent = initial_game_time - time_left;
|
||||||
|
int32_t true_time_spent = time_spent - (total_strikes * STRIKE_TIME_PENALTY);
|
||||||
|
write_time(time_buf_1, time_left);
|
||||||
|
write_time(time_buf_2, time_spent);
|
||||||
|
write_time(time_buf_3, true_time_spent);
|
||||||
|
|
||||||
|
sprintf(buf,
|
||||||
|
"Finished!\n\tTotal Strikes: %ld\n\tTime Left (w/ penalties): %s\n\tTime Spent (w/ penalties): %s\n\tTrue Time Spent: %s\n\n",
|
||||||
|
total_strikes, time_buf_1, time_buf_2, time_buf_3
|
||||||
|
);
|
||||||
|
lv_label_set_text(overall_results_label, buf);
|
||||||
|
|
||||||
|
lv_label_set_text(breakdown_results_label, "Step Breakdown:\n\tStep 1: \n\tStep 2:\n\tStep 3:\n\tStep 4:\n\tStep 5:\n\tStep 6:");
|
||||||
|
|
||||||
|
sprintf(buf,
|
||||||
|
"\n%ld strikes\n%ld strikes\n%ld strikes\n%ld strikes\n%ld strikes\n%ld strikes",
|
||||||
|
step_strikes[0], step_strikes[1], step_strikes[2], step_strikes[3], step_strikes[4], step_strikes[5]
|
||||||
|
);
|
||||||
|
lv_label_set_text(strike_numbers_label, buf);
|
||||||
|
|
||||||
|
write_time(time_buf_1, initial_game_time - step_finish_times[0]);
|
||||||
|
write_time(time_buf_2, step_finish_times[0] - step_finish_times[1]);
|
||||||
|
write_time(time_buf_3, step_finish_times[1] - step_finish_times[2]);
|
||||||
|
write_time(time_buf_4, step_finish_times[2] - step_finish_times[3]);
|
||||||
|
write_time(time_buf_5, step_finish_times[3] - step_finish_times[4]);
|
||||||
|
write_time(time_buf_6, step_finish_times[4] - step_finish_times[5]);
|
||||||
|
sprintf(buf,
|
||||||
|
"\n%s\n%s\n%s\n%s\n%s\n%s",
|
||||||
|
time_buf_1, time_buf_2, time_buf_3, time_buf_4, time_buf_5, time_buf_6
|
||||||
|
);
|
||||||
|
lv_label_set_text(step_times_label, buf);
|
||||||
|
|
||||||
|
old_scr = lv_scr_act();
|
||||||
|
lv_scr_load(scr);
|
||||||
|
|
||||||
|
xSemaphoreGive(xGuiSemaphore);
|
||||||
}
|
}
|
||||||
|
|||||||
+107
-33
@@ -1,58 +1,132 @@
|
|||||||
|
#include "main.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "esp_rom_gpio.h"
|
#include "esp_rom_gpio.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
|
||||||
#include "drivers/all.h"
|
#include "drivers/all.h"
|
||||||
|
#include "drivers/state_tracking.h"
|
||||||
|
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
|
||||||
#include "steps/step0.h"
|
#include "steps/step0.h"
|
||||||
#include "steps/step1.h"
|
#include "steps/p001_step1.h"
|
||||||
#include "steps/step2.h"
|
#include "steps/p001_step2.h"
|
||||||
#include "steps/step3.h"
|
#include "steps/p001_step3.h"
|
||||||
#include "steps/step4.h"
|
#include "steps/p001_step4.h"
|
||||||
#include "steps/step5.h"
|
#include "steps/p001_step5.h"
|
||||||
#include "steps/step6.h"
|
#include "steps/p001_step6.h"
|
||||||
|
#include "steps/p002_step1.h"
|
||||||
|
#include "steps/p002_step2.h"
|
||||||
|
#include "steps/p002_step3.h"
|
||||||
|
#include "steps/p002_step4.h"
|
||||||
|
#include "steps/p002_step5.h"
|
||||||
|
#include "steps/p002_step6.h"
|
||||||
|
|
||||||
|
bool play_modified;
|
||||||
|
|
||||||
static const char *TAG = "main";
|
static const char *TAG = "main";
|
||||||
uint32_t initial_game_time = 90*60*1000;
|
uint32_t initial_game_time = 90*60*1000 + 1000;
|
||||||
uint32_t skip_to_step = 0;
|
uint32_t skip_to_step = 0;
|
||||||
|
uint32_t current_step = 0;
|
||||||
|
uint32_t puzzle = 0;
|
||||||
|
extern uint32_t total_strikes;
|
||||||
|
|
||||||
|
static void do_p001() {
|
||||||
|
set_game_time(initial_game_time);
|
||||||
|
start_game_timer();
|
||||||
|
total_strikes = 0;
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 1;
|
||||||
|
if (skip_to_step <= 1) p001_step1();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 2;
|
||||||
|
if (skip_to_step <= 2) p001_step2();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 3;
|
||||||
|
if (skip_to_step <= 3) p001_step3();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 4;
|
||||||
|
if (skip_to_step <= 4) p001_step4();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 5;
|
||||||
|
if (skip_to_step <= 5) p001_step5();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 6;
|
||||||
|
if (skip_to_step <= 6) p001_step6();
|
||||||
|
start_game_timer();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
|
||||||
|
stop_game_timer();
|
||||||
|
ESP_LOGI(TAG, "Bomb has been diffused. Counter-Terrorists win.");
|
||||||
|
play_clip_wav(MOUNT_POINT "/diffuse.wav", true, false, 3, 0);
|
||||||
|
|
||||||
|
display_game_results();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_p002() {
|
||||||
|
set_game_time(initial_game_time);
|
||||||
|
start_game_timer();
|
||||||
|
total_strikes = 0;
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 1;
|
||||||
|
if (skip_to_step <= 1) p002_step1();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 2;
|
||||||
|
if (skip_to_step <= 2) p002_step2();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 3;
|
||||||
|
if (skip_to_step <= 3) p002_step3();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 4;
|
||||||
|
if (skip_to_step <= 4) p002_step4();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 5;
|
||||||
|
if (skip_to_step <= 5) p002_step5();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
current_step = 6;
|
||||||
|
if (skip_to_step <= 6) p002_step6();
|
||||||
|
start_game_timer();
|
||||||
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
|
clean_bomb();
|
||||||
|
|
||||||
|
stop_game_timer();
|
||||||
|
ESP_LOGI(TAG, "Bomb has been diffused. Counter-Terrorists win.");
|
||||||
|
play_clip_wav(MOUNT_POINT "/diffuse.wav", true, false, 3, 0);
|
||||||
|
|
||||||
|
display_game_results();
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void app_main(void) {
|
extern "C" void app_main(void) {
|
||||||
printf("app_main\n");
|
printf("app_main\n");
|
||||||
|
|
||||||
init_drivers();
|
init_drivers();
|
||||||
init_tft();
|
|
||||||
init_sseg();
|
// TODO: get wires out of the drivers
|
||||||
init_game_module_timer();
|
// TODO: generify the strike system out of wires
|
||||||
init_leds();
|
|
||||||
init_wires();
|
init_wires();
|
||||||
init_power_board();
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
|
||||||
clean_bomb();
|
clean_bomb();
|
||||||
step0();
|
step0();
|
||||||
set_game_time(initial_game_time + 1000);
|
|
||||||
start_game_timer();
|
|
||||||
clean_bomb();
|
|
||||||
if (skip_to_step <= 1) step1();
|
|
||||||
clean_bomb();
|
|
||||||
if (skip_to_step <= 2) step2();
|
|
||||||
clean_bomb();
|
|
||||||
if (skip_to_step <= 3) step3();
|
|
||||||
clean_bomb();
|
|
||||||
if (skip_to_step <= 4) step4();
|
|
||||||
clean_bomb();
|
|
||||||
if (skip_to_step <= 5) step5();
|
|
||||||
clean_bomb();
|
|
||||||
if (skip_to_step <= 6) step6();
|
|
||||||
clean_bomb();
|
|
||||||
|
|
||||||
stop_game_timer();
|
if (puzzle == 1) {
|
||||||
ESP_LOGI(TAG, "Bomb has been diffused. Counter-Terrorists win.");
|
do_p001();
|
||||||
ESP_ERROR_CHECK_WITHOUT_ABORT(play_raw("/sdcard/diffused.pcm"));
|
} else {
|
||||||
|
do_p002();
|
||||||
display_game_results();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef MAIN_H
|
||||||
|
#define MAIN_H
|
||||||
|
|
||||||
|
#define CONTROL_REV_2_0
|
||||||
|
// #define CONTROL_REV_2_1
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
extern bool play_modified;
|
||||||
|
|
||||||
|
constexpr size_t N_STEPS = 6;
|
||||||
|
|
||||||
|
#endif /* MAIN_H */
|
||||||
@@ -1,13 +1,21 @@
|
|||||||
set(SOURCES
|
set(SOURCES
|
||||||
"setup_wires.cpp"
|
"setup_wires.cpp"
|
||||||
"step0.cpp"
|
"step0.cpp"
|
||||||
"step1.cpp"
|
"p001_step1.cpp"
|
||||||
"step2.cpp"
|
"p001_step2.cpp"
|
||||||
"step3.cpp"
|
"p001_step3.cpp"
|
||||||
"step4.cpp"
|
"p001_step4.cpp"
|
||||||
"step5.cpp"
|
"p001_step5.cpp"
|
||||||
"step6.cpp"
|
"p001_step6.cpp"
|
||||||
|
"p002_step1.cpp"
|
||||||
|
"p002_step2.cpp"
|
||||||
|
"p002_step3.cpp"
|
||||||
|
"p002_step4.cpp"
|
||||||
|
"p002_step5.cpp"
|
||||||
|
"p002_step6.cpp"
|
||||||
"wires_puzzle.cpp"
|
"wires_puzzle.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_subdirectory(tetris_resources)
|
||||||
|
|
||||||
target_sources(${COMPONENT_LIB} PRIVATE ${SOURCES})
|
target_sources(${COMPONENT_LIB} PRIVATE ${SOURCES})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "step1.h"
|
#include "p001_step1.h"
|
||||||
|
|
||||||
__attribute__((unused))
|
__attribute__((unused))
|
||||||
static const char *TAG = "step1";
|
static const char *TAG = "step1";
|
||||||
@@ -17,11 +17,11 @@ static const char* NUM_NAMES[] = {
|
|||||||
"four"
|
"four"
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint8_t NEOPIXEL_COLORS[4][3] = {
|
static uint32_t NEOPIXEL_COLORS[4] = {
|
||||||
{0, 20, 0},
|
LEDColor::LED_COLOR_GREEN,
|
||||||
{20, 0, 0},
|
LEDColor::LED_COLOR_RED,
|
||||||
{20, 20, 0},
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
{0, 0, 20},
|
LEDColor::LED_COLOR_BLUE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::random_device my_rd;
|
static std::random_device my_rd;
|
||||||
@@ -30,6 +30,7 @@ static std::uniform_int_distribution<> zero_to_one(0, 1);
|
|||||||
static std::uniform_int_distribution<> zero_to_two(0, 2);
|
static std::uniform_int_distribution<> zero_to_two(0, 2);
|
||||||
static std::uniform_int_distribution<> zero_to_three(0, 3);
|
static std::uniform_int_distribution<> zero_to_three(0, 3);
|
||||||
|
|
||||||
|
static lv_obj_t *old_scr;
|
||||||
static lv_obj_t *scr;
|
static lv_obj_t *scr;
|
||||||
static lv_obj_t *text = NULL;
|
static lv_obj_t *text = NULL;
|
||||||
|
|
||||||
@@ -58,13 +59,13 @@ static int part = 0;
|
|||||||
|
|
||||||
static void init_step(void) {
|
static void init_step(void) {
|
||||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||||
scr = lv_disp_get_scr_act(NULL);
|
scr = lv_obj_create(NULL);
|
||||||
|
|
||||||
// Set the background color of the display to black.
|
// Set the background color of the display to black.
|
||||||
lv_style_init(&style_screen);
|
lv_style_init(&style_screen);
|
||||||
lv_style_set_bg_color(&style_screen, lv_color_black());
|
lv_style_set_bg_color(&style_screen, lv_color_black());
|
||||||
lv_style_set_text_font(&style_screen, &lv_font_montserrat_32);
|
lv_style_set_text_font(&style_screen, &lv_font_montserrat_32);
|
||||||
lv_obj_add_style(lv_scr_act(), &style_screen, LV_STATE_DEFAULT);
|
lv_obj_add_style(scr, &style_screen, LV_STATE_DEFAULT);
|
||||||
|
|
||||||
// rgb565
|
// rgb565
|
||||||
lv_color_t green = { .full = 0x0560 };
|
lv_color_t green = { .full = 0x0560 };
|
||||||
@@ -85,15 +86,18 @@ static void init_step(void) {
|
|||||||
lv_style_set_text_color(&blue_text, blue);
|
lv_style_set_text_color(&blue_text, blue);
|
||||||
|
|
||||||
text = lv_label_create(scr);
|
text = lv_label_create(scr);
|
||||||
|
|
||||||
|
old_scr = lv_scr_act();
|
||||||
|
lv_scr_load(scr);
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
xSemaphoreGive(xGuiSemaphore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clean_up_step(void) {
|
static void clean_up_step(void) {
|
||||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
while (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdFALSE) vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
lv_obj_clean(scr);
|
lv_scr_load(old_scr);
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
lv_obj_del(scr);
|
||||||
}
|
xSemaphoreGive(xGuiSemaphore);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generate_switch_leds(void) {
|
static void generate_switch_leds(void) {
|
||||||
@@ -114,10 +118,9 @@ static void generate_switch_leds(void) {
|
|||||||
switch_leds[3] = colors[0];
|
switch_leds[3] = colors[0];
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
uint8_t* rgb = NEOPIXEL_COLORS[switch_leds[i]];
|
led_set(IndicatorLED::LED_S1 - i, NEOPIXEL_COLORS[switch_leds[i]]);
|
||||||
led_strip_set_pixel(leds, Led::switch1 - i, rgb[0], rgb[1], rgb[2]);
|
|
||||||
}
|
}
|
||||||
led_strip_refresh(leds);
|
leds_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_text_and_color(const char* text_str, int color) {
|
static void set_text_and_color(const char* text_str, int color) {
|
||||||
@@ -200,7 +203,6 @@ static void update_lcd_count(int times) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool play_part(uint32_t time) {
|
static bool play_part(uint32_t time) {
|
||||||
stop_module_timer();
|
|
||||||
set_module_time(time);
|
set_module_time(time);
|
||||||
|
|
||||||
lcd_clear();
|
lcd_clear();
|
||||||
@@ -208,18 +210,18 @@ static bool play_part(uint32_t time) {
|
|||||||
switch (part) {
|
switch (part) {
|
||||||
case 0:
|
case 0:
|
||||||
lcd_print("COLOR");
|
lcd_print("COLOR");
|
||||||
led_strip_set_pixel(leds, Led::char_lcd, 20, 0, 20);
|
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_PINK);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
lcd_print("NUMBER");
|
lcd_print("NUMBER");
|
||||||
led_strip_set_pixel(leds, Led::char_lcd, 0, 0, 30);
|
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_BLUE);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
lcd_print("SWITCH");
|
lcd_print("SWITCH");
|
||||||
led_strip_set_pixel(leds, Led::char_lcd, 20, 20, 0);
|
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_YELLOW);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
led_strip_refresh(leds);
|
leds_flush();
|
||||||
|
|
||||||
int times = 0;
|
int times = 0;
|
||||||
int correct = generate_part();
|
int correct = generate_part();
|
||||||
@@ -253,22 +255,28 @@ static bool play_part(uint32_t time) {
|
|||||||
}
|
}
|
||||||
if (get_module_time() <= 0) {
|
if (get_module_time() <= 0) {
|
||||||
strike("Out of time");
|
strike("Out of time");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stop_module_timer();
|
||||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||||
lv_label_set_text(text, "");
|
lv_label_set_text(text, "");
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
xSemaphoreGive(xGuiSemaphore);
|
||||||
}
|
}
|
||||||
vTaskDelay(pdMS_TO_TICKS(80));
|
if (part < 2) {
|
||||||
play_raw(MOUNT_POINT "/correct.pcm");
|
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
} else {
|
||||||
|
play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void step1(void) {
|
void p001_step1(void) {
|
||||||
while (get_switch_flipped(nullptr));
|
while (get_switch_flipped(nullptr));
|
||||||
|
|
||||||
init_step();
|
init_step();
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef P001_STEP_1_H
|
||||||
|
#define P001_STEP_1_H
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
#include "../drivers/all.h"
|
||||||
|
#include "../helper.h"
|
||||||
|
|
||||||
|
void p001_step1(void);
|
||||||
|
|
||||||
|
#endif /* P001_STEP_1_H */
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "step2.h"
|
#include "p001_step2.h"
|
||||||
|
|
||||||
__attribute__((unused))
|
__attribute__((unused))
|
||||||
static const char *TAG = "step2";
|
static const char *TAG = "step2";
|
||||||
@@ -16,9 +16,13 @@ static const uint8_t SSEG_MAPS[5][4] = {
|
|||||||
{0b01000111, 0b00011001, 0b01111000, 0b00111110}
|
{0b01000111, 0b00011001, 0b01111000, 0b00111110}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int INDICATOR_RED[5] = {15, 0, 0, 10, 5};
|
static const uint32_t INDICATOR_COLORS[5] = {
|
||||||
static const int INDICATOR_GREEN[5] = {0, 0, 10, 5, 7};
|
LEDColor::LED_COLOR_RED,
|
||||||
static const int INDICATOR_BLUE[5] = {0, 10, 0, 0, 5};
|
LEDColor::LED_COLOR_BLUE,
|
||||||
|
LEDColor::LED_COLOR_GREEN,
|
||||||
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
|
LEDColor::LED_COLOR_WHITE,
|
||||||
|
};
|
||||||
|
|
||||||
// random number generators
|
// random number generators
|
||||||
static std::random_device rd;
|
static std::random_device rd;
|
||||||
@@ -48,8 +52,8 @@ std::map<int, int> number_map = {
|
|||||||
static void new_puzzle(void) {
|
static void new_puzzle(void) {
|
||||||
// scramble lights
|
// scramble lights
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
led_strip_set_pixel(leds, 9, INDICATOR_RED[map_dist(gen)], INDICATOR_GREEN[map_dist(gen)], INDICATOR_BLUE[map_dist(gen)]);
|
led_set(IndicatorLED::LED_SPEAKER, INDICATOR_COLORS[map_dist(gen)]);
|
||||||
led_strip_refresh(leds);
|
leds_flush();
|
||||||
|
|
||||||
uint8_t random_segments[4] = {0, 0, 0, 0};
|
uint8_t random_segments[4] = {0, 0, 0, 0};
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
@@ -72,8 +76,8 @@ static void new_puzzle(void) {
|
|||||||
}
|
}
|
||||||
// ESP_LOGI(TAG, "Chosen Map: %i", chosen_map);
|
// ESP_LOGI(TAG, "Chosen Map: %i", chosen_map);
|
||||||
|
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, 9, INDICATOR_RED[chosen_map], INDICATOR_GREEN[chosen_map], INDICATOR_BLUE[chosen_map]));
|
led_set(IndicatorLED::LED_SPEAKER, INDICATOR_COLORS[chosen_map]);
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
bool bit = (answer_sseg >> i) & 1;
|
bool bit = (answer_sseg >> i) & 1;
|
||||||
@@ -84,9 +88,10 @@ static void new_puzzle(void) {
|
|||||||
// ESP_LOGI(TAG, "Flipping bit %i on display %i", i, display);
|
// ESP_LOGI(TAG, "Flipping bit %i on display %i", i, display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
set_module_sseg_raw(display_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
void step2(void) {
|
void p001_step2(void) {
|
||||||
KeypadKey key;
|
KeypadKey key;
|
||||||
int solved_times = 0;
|
int solved_times = 0;
|
||||||
|
|
||||||
@@ -94,20 +99,19 @@ void step2(void) {
|
|||||||
int strike_time = 0;
|
int strike_time = 0;
|
||||||
while(solved_times < NUM_SOLVES) {
|
while(solved_times < NUM_SOLVES) {
|
||||||
// for every bit in the answer-
|
// for every bit in the answer-
|
||||||
set_module_sseg_raw(display_map);
|
|
||||||
if (get_keypad_pressed(&key)) {
|
if (get_keypad_pressed(&key)) {
|
||||||
lcd_clear();
|
lcd_clear();
|
||||||
char c = char_of_keypad_key(key);
|
char c = char_of_keypad_key(key);
|
||||||
// ESP_LOGI(TAG, "Pressed: %c", c);
|
// ESP_LOGI(TAG, "Pressed: %c", c);
|
||||||
if (c == answer_char) {
|
if (c == answer_char) {
|
||||||
play_raw(MOUNT_POINT "/correct.pcm");
|
|
||||||
solved_times++;
|
solved_times++;
|
||||||
if (solved_times < NUM_SOLVES) {
|
if (solved_times < NUM_SOLVES) {
|
||||||
|
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
|
||||||
clean_bomb();
|
clean_bomb();
|
||||||
new_puzzle();
|
new_puzzle();
|
||||||
} else {
|
} else {
|
||||||
uint8_t display_tmp[4] = {0b00000000, 0b00000000, 0b00000000, 0b00000000};
|
play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0);
|
||||||
set_module_sseg_raw(display_tmp);
|
clear_module_sseg();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strike_time = xTaskGetTickCount();
|
strike_time = xTaskGetTickCount();
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef STEP_2_H
|
#ifndef P001_STEP_2_H
|
||||||
#define STEP_2_H
|
#define P001_STEP_2_H
|
||||||
|
|
||||||
#include "../drivers/bottom_half.h"
|
#include "../drivers/bottom_half.h"
|
||||||
#include "../drivers/wires.h"
|
#include "../drivers/wires.h"
|
||||||
@@ -11,6 +11,6 @@
|
|||||||
#include <random>
|
#include <random>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
void step2(void);
|
void p001_step2(void);
|
||||||
|
|
||||||
#endif /* STEP_2_H */
|
#endif /* P001_STEP_2_H */
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "step3.h"
|
#include "p001_step3.h"
|
||||||
|
|
||||||
#define ONE_SECOND_TIME 90'000
|
#define ONE_SECOND_TIME 90'000
|
||||||
#define THREE_SECOND_TIME 90'000
|
#define THREE_SECOND_TIME 90'000
|
||||||
@@ -13,12 +13,12 @@ static int tone = 0;
|
|||||||
static int times = 0;
|
static int times = 0;
|
||||||
|
|
||||||
static const char* TONE_FILES[] = {
|
static const char* TONE_FILES[] = {
|
||||||
MOUNT_POINT "/low-1.pcm",
|
MOUNT_POINT "/low-1.wav",
|
||||||
MOUNT_POINT "/low-3.pcm",
|
MOUNT_POINT "/low-3.wav",
|
||||||
MOUNT_POINT "/low-6.pcm",
|
MOUNT_POINT "/low-6.wav",
|
||||||
MOUNT_POINT "/high-1.pcm",
|
MOUNT_POINT "/high-1.wav",
|
||||||
MOUNT_POINT "/high-3.pcm",
|
MOUNT_POINT "/high-3.wav",
|
||||||
MOUNT_POINT "/high-6.pcm",
|
MOUNT_POINT "/high-6.wav",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* LCD_STRINGS[] = {
|
static const char* LCD_STRINGS[] = {
|
||||||
@@ -49,21 +49,21 @@ static std::uniform_int_distribution<> lcd_rand_char_dist(0, sizeof(lcd_random_c
|
|||||||
static std::uniform_int_distribution<> has_coconut_dist(0, 2);
|
static std::uniform_int_distribution<> has_coconut_dist(0, 2);
|
||||||
static std::uniform_int_distribution<> coconut_position_dist(0, 13);
|
static std::uniform_int_distribution<> coconut_position_dist(0, 13);
|
||||||
|
|
||||||
static uint8_t NEOPIXEL_COLORS[7][3] = {
|
static uint32_t NEOPIXEL_COLORS[7] = {
|
||||||
{20, 0, 0}, // red
|
LEDColor::LED_COLOR_RED,
|
||||||
{20, 10, 0}, // orange
|
LEDColor::LED_COLOR_ORANGE,
|
||||||
{20, 20, 0}, // yellow
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
{0, 20, 0}, // green
|
LEDColor::LED_COLOR_GREEN,
|
||||||
{0, 0, 20}, // blue
|
LEDColor::LED_COLOR_BLUE,
|
||||||
{20, 0, 20}, // purple
|
LEDColor::LED_COLOR_PINK,
|
||||||
{0, 0, 0}, // off
|
LEDColor::LED_COLOR_OFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool one_second();
|
static bool one_second();
|
||||||
static bool three_second();
|
static bool three_second();
|
||||||
static bool six_second();
|
static bool six_second();
|
||||||
|
|
||||||
void step3(void) {
|
void p001_step3(void) {
|
||||||
StarCodeHandler star_codes[] = {
|
StarCodeHandler star_codes[] = {
|
||||||
{
|
{
|
||||||
.code = "*1642",
|
.code = "*1642",
|
||||||
@@ -80,8 +80,9 @@ void step3(void) {
|
|||||||
// tone = 2;
|
// tone = 2;
|
||||||
while (get_button_pressed(nullptr)) vTaskDelay(pdMS_TO_TICKS(10));
|
while (get_button_pressed(nullptr)) vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
|
||||||
play_raw(MOUNT_POINT "/que.pcm");
|
play_clip_wav(MOUNT_POINT "/ready.wav", true, false, 3, 0);
|
||||||
play_raw(TONE_FILES[tone]);
|
// The high pitched tones need to be scaled down by 3 more
|
||||||
|
play_clip_wav(TONE_FILES[tone], false, false, 2 + (tone/3) * 3, 0);
|
||||||
|
|
||||||
bool correct = false;
|
bool correct = false;
|
||||||
switch (tone % 3) {
|
switch (tone % 3) {
|
||||||
@@ -98,7 +99,11 @@ void step3(void) {
|
|||||||
if (correct) {
|
if (correct) {
|
||||||
times++;
|
times++;
|
||||||
clean_bomb();
|
clean_bomb();
|
||||||
play_raw(MOUNT_POINT "/correct.pcm");
|
if (times < TIMES_TO_COMPLETE) {
|
||||||
|
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
|
||||||
|
} else {
|
||||||
|
play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
vTaskDelay(pdMS_TO_TICKS(1500));
|
vTaskDelay(pdMS_TO_TICKS(1500));
|
||||||
}
|
}
|
||||||
@@ -134,10 +139,9 @@ static void rng_leds() {
|
|||||||
static void write_leds() {
|
static void write_leds() {
|
||||||
// update all the leds
|
// update all the leds
|
||||||
for (int i = 0; i < LED_COUNT; i++) {
|
for (int i = 0; i < LED_COUNT; i++) {
|
||||||
auto colors = NEOPIXEL_COLORS[indicator_led_idxs[i]];
|
led_set(i, NEOPIXEL_COLORS[indicator_led_idxs[i]]);
|
||||||
led_strip_set_pixel(leds, i, colors[0], colors[1], colors[2]);
|
|
||||||
}
|
}
|
||||||
led_strip_refresh(leds);
|
leds_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t four_bit_flag(bool b0, bool b1, bool b2, bool b3) {
|
static uint8_t four_bit_flag(bool b0, bool b1, bool b2, bool b3) {
|
||||||
@@ -207,7 +211,7 @@ static bool one_second() {
|
|||||||
start_module_timer();
|
start_module_timer();
|
||||||
|
|
||||||
rng_leds();
|
rng_leds();
|
||||||
int speaker_color = indicator_led_idxs[Led::speaker];
|
int speaker_color = indicator_led_idxs[IndicatorLED::LED_SPEAKER];
|
||||||
int lcd_string_idx = lcd_string_dist(gen);
|
int lcd_string_idx = lcd_string_dist(gen);
|
||||||
bool was_high = (tone / 3) == 1;
|
bool was_high = (tone / 3) == 1;
|
||||||
write_leds();
|
write_leds();
|
||||||
@@ -233,10 +237,10 @@ static bool one_second() {
|
|||||||
|
|
||||||
uint8_t correct_button_mask = 0b1011;
|
uint8_t correct_button_mask = 0b1011;
|
||||||
uint8_t correct_buttons = four_bit_flag(
|
uint8_t correct_buttons = four_bit_flag(
|
||||||
indicator_led_idxs[Led::char_lcd] != 6, // green
|
indicator_led_idxs[IndicatorLED::LED_LCD] != 6, // green
|
||||||
red_led_count > blue_led_count, // red
|
red_led_count > blue_led_count, // red
|
||||||
0, // yellow UNCHECKED
|
0, // yellow UNCHECKED
|
||||||
indicator_led_idxs[Led::rfid] == 4 || indicator_led_idxs[Led::rfid] == 6 // blue
|
indicator_led_idxs[IndicatorLED::LED_RFID] == 4 || indicator_led_idxs[IndicatorLED::LED_RFID] == 6 // blue
|
||||||
);
|
);
|
||||||
|
|
||||||
debug_correct_values(correct_buttons, correct_button_mask, correct_switches);
|
debug_correct_values(correct_buttons, correct_button_mask, correct_switches);
|
||||||
@@ -341,7 +345,7 @@ static bool six_second() {
|
|||||||
|
|
||||||
bool was_high = (tone / 3) == 1;
|
bool was_high = (tone / 3) == 1;
|
||||||
|
|
||||||
bool second_switch_correct_state = (indicator_led_idxs[Led::switch2] == 0) || (indicator_led_idxs[Led::switch2] == 6);
|
bool second_switch_correct_state = (indicator_led_idxs[IndicatorLED::LED_S2] == 0) || (indicator_led_idxs[IndicatorLED::LED_S2] == 6);
|
||||||
second_switch_correct_state = second_switch_correct_state || was_high;
|
second_switch_correct_state = second_switch_correct_state || was_high;
|
||||||
|
|
||||||
rng_leds();
|
rng_leds();
|
||||||
@@ -357,10 +361,10 @@ static bool six_second() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int purple_led_on_bottom_count = 0;
|
int pink_led_on_bottom_count = 0;
|
||||||
for (int i = Led::rfid; i < LED_COUNT; i++) {
|
for (int i = IndicatorLED::LED_RFID; i < LED_COUNT; i++) {
|
||||||
if (indicator_led_idxs[i] == 5) {
|
if (indicator_led_idxs[i] == 5) {
|
||||||
purple_led_on_bottom_count++;
|
pink_led_on_bottom_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,12 +372,12 @@ static bool six_second() {
|
|||||||
vowels > 7,
|
vowels > 7,
|
||||||
second_switch_correct_state,
|
second_switch_correct_state,
|
||||||
true,
|
true,
|
||||||
!(purple_led_on_bottom_count > 1)
|
!(pink_led_on_bottom_count > 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
uint8_t correct_button_mask = 0b1101;
|
uint8_t correct_button_mask = 0b1101;
|
||||||
uint8_t correct_buttons = four_bit_flag(
|
uint8_t correct_buttons = four_bit_flag(
|
||||||
(!was_high) || (green_led_count >= 2) || indicator_led_idxs[Led::keypad] == 4, // green
|
(!was_high) || (green_led_count >= 2) || indicator_led_idxs[IndicatorLED::LED_KEYPAD] == 4, // green
|
||||||
0, // red UNCHECKED
|
0, // red UNCHECKED
|
||||||
blue_led_count >= 3, // yellow
|
blue_led_count >= 3, // yellow
|
||||||
contains_coconut // blue
|
contains_coconut // blue
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef P001_STEP_3_H
|
||||||
|
#define P001_STEP_3_H
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
#include "../drivers/all.h"
|
||||||
|
#include "../helper.h"
|
||||||
|
|
||||||
|
void p001_step3(void);
|
||||||
|
|
||||||
|
#endif /* P001_STEP_3_H */
|
||||||
@@ -1,41 +1,68 @@
|
|||||||
#include "step4.h"
|
#include "p001_step4.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
__attribute__((unused))
|
__attribute__((unused))
|
||||||
static const char *TAG = "step4";
|
static const char *TAG = "step4";
|
||||||
|
|
||||||
|
static lv_obj_t *old_scr;
|
||||||
|
static lv_obj_t* scr;
|
||||||
static lv_obj_t* img;
|
static lv_obj_t* img;
|
||||||
|
|
||||||
static bool invisible_blocks = false;
|
|
||||||
static bool text_output = false;
|
|
||||||
|
|
||||||
static const int height = 22;
|
static const int height = 22;
|
||||||
static const int width = 10;
|
static const int width = 10;
|
||||||
|
|
||||||
static int board[height][width] = {0};
|
static int board[height][width] = {0};
|
||||||
// static lv_obj_t* visual_board[height][width] = {0};
|
static lv_obj_t* visual_board[height][width] = {0};
|
||||||
|
|
||||||
static lv_obj_t* line_clear_img;
|
static lv_obj_t* line_clear_img;
|
||||||
static lv_style_t game_over_style;
|
static lv_style_t game_over_style;
|
||||||
static lv_obj_t* game_over_label;
|
static lv_obj_t* game_over_label;
|
||||||
|
|
||||||
static const void* LINE_CLEAR_SRC = (void*)"A:/sdcard/clear.bin";
|
#define MUSIC_FILE MOUNT_POINT "/piano.wav"
|
||||||
static const void* BACKGROUND_SRC = (void*)"A:/sdcard/bg.bin";
|
|
||||||
// LV_IMG_DECLARE(background);
|
|
||||||
// static const void* BACKGROUND_SRC = (void*)&background;
|
|
||||||
|
|
||||||
static QueueHandle_t stop_music;
|
#ifdef TETRIS_USE_FLASH_BG_IMG
|
||||||
static bool playing_music = true;
|
LV_IMG_DECLARE(bg);
|
||||||
|
static const void* BACKGROUND_SRC = (void*) &bg;
|
||||||
|
#else
|
||||||
|
static const void* BACKGROUND_SRC = (void*)"A:" MOUNT_POINT "/bg.bin";
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char* PIECE_IMG_SRC[] = {
|
#ifdef TETRIS_USE_FLASH_IMG
|
||||||
|
LV_IMG_DECLARE(clear);
|
||||||
|
LV_IMG_DECLARE(db);
|
||||||
|
LV_IMG_DECLARE(green);
|
||||||
|
LV_IMG_DECLARE(lb);
|
||||||
|
LV_IMG_DECLARE(orange);
|
||||||
|
LV_IMG_DECLARE(purple);
|
||||||
|
LV_IMG_DECLARE(red);
|
||||||
|
LV_IMG_DECLARE(yellow);
|
||||||
|
|
||||||
|
static const void* LINE_CLEAR_SRC = (void*) &clear;
|
||||||
|
|
||||||
|
static const void* PIECE_IMG_SRC[] = {
|
||||||
NULL,
|
NULL,
|
||||||
"A:/sdcard/lb.bin",
|
&lb,
|
||||||
"A:/sdcard/db.bin",
|
&db,
|
||||||
"A:/sdcard/orange.bin",
|
&orange,
|
||||||
"A:/sdcard/yellow.bin",
|
&yellow,
|
||||||
"A:/sdcard/green.bin",
|
&green,
|
||||||
"A:/sdcard/purple.bin",
|
&purple,
|
||||||
"A:/sdcard/red.bin",
|
&red,
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
static const void* LINE_CLEAR_SRC = (void*)"A:" MOUNT_POINT "/clear.bin";
|
||||||
|
|
||||||
|
static const void* PIECE_IMG_SRC[] = {
|
||||||
|
NULL,
|
||||||
|
"A:" MOUNT_POINT "/lb.bin",
|
||||||
|
"A:" MOUNT_POINT "/db.bin",
|
||||||
|
"A:" MOUNT_POINT "/orange.bin",
|
||||||
|
"A:" MOUNT_POINT "/yellow.bin",
|
||||||
|
"A:" MOUNT_POINT "/green.bin",
|
||||||
|
"A:" MOUNT_POINT "/purple.bin",
|
||||||
|
"A:" MOUNT_POINT "/red.bin",
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool game = true;
|
static bool game = true;
|
||||||
|
|
||||||
@@ -54,27 +81,27 @@ static int piece_nodes[4][2] = {
|
|||||||
|
|
||||||
lv_obj_t* piece_imgs[4] = {};
|
lv_obj_t* piece_imgs[4] = {};
|
||||||
|
|
||||||
TaskHandle_t music_handle;
|
static bool music_playing;
|
||||||
|
|
||||||
static std::random_device rd;
|
static std::random_device rd;
|
||||||
static std::mt19937 gen(rd());
|
static std::mt19937 gen(rd());
|
||||||
static std::uniform_int_distribution<> piece_dist(2, 7);
|
static std::uniform_int_distribution<> piece_dist(2, 7);
|
||||||
|
|
||||||
static void generate_block(void);
|
static void generate_block();
|
||||||
static void show_board(void);
|
static void show_board();
|
||||||
static void get_node_locations(void);
|
static void get_node_locations();
|
||||||
static bool check_overlap(void);
|
static bool check_overlap();
|
||||||
|
|
||||||
static void line_clear(int hi);
|
static void line_clear(int hi);
|
||||||
static void check_line_clears(void);
|
static void check_line_clears();
|
||||||
static void place_piece(void);
|
static void place_piece();
|
||||||
|
|
||||||
static void move_left(void);
|
static void move_left();
|
||||||
static void move_right(void);
|
static void move_right();
|
||||||
static void drop(void);
|
static void drop();
|
||||||
static void rotate_block(void);
|
static void rotate_block();
|
||||||
static void update_score(void);
|
static void update_score();
|
||||||
static void clear_board(void);
|
static void clear_board();
|
||||||
|
|
||||||
|
|
||||||
static int bbcc(int i) { // [0,1,2,3] -> [ 0, 0,+1,+1]
|
static int bbcc(int i) { // [0,1,2,3] -> [ 0, 0,+1,+1]
|
||||||
@@ -123,29 +150,16 @@ static int bdca(int i) { // [0,1,2,3] -> [ 0,+2,+1,-1]
|
|||||||
const int map[] = {0, 2, 1, -1};
|
const int map[] = {0, 2, 1, -1};
|
||||||
return map[i];
|
return map[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void music_task(void* arg) {
|
|
||||||
stop_music = xQueueCreate(2, sizeof (uint8_t));
|
|
||||||
if (stop_music == 0) {
|
|
||||||
ESP_LOGW(TAG, "Could not create stop_music queue!");
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (playing_music) {
|
static void init_screen() {
|
||||||
play_raw_stop_queue(MOUNT_POINT "/tetris.pcm", stop_music);
|
|
||||||
}
|
|
||||||
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_screen(void) {
|
|
||||||
while (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdFALSE) vTaskDelay(pdMS_TO_TICKS(10));
|
while (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdFALSE) vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
scr = lv_obj_create(NULL);
|
||||||
img = lv_img_create(lv_scr_act());
|
|
||||||
|
img = lv_img_create(scr);
|
||||||
lv_img_set_src(img, BACKGROUND_SRC);
|
lv_img_set_src(img, BACKGROUND_SRC);
|
||||||
lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
|
lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
|
||||||
line_clear_img = lv_img_create(lv_scr_act());
|
line_clear_img = lv_img_create(scr);
|
||||||
lv_obj_add_flag(line_clear_img, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(line_clear_img, LV_OBJ_FLAG_HIDDEN);
|
||||||
lv_img_set_src(line_clear_img, LINE_CLEAR_SRC);
|
lv_img_set_src(line_clear_img, LINE_CLEAR_SRC);
|
||||||
lv_obj_align(line_clear_img, LV_ALIGN_BOTTOM_LEFT, 159, -(height*16));
|
lv_obj_align(line_clear_img, LV_ALIGN_BOTTOM_LEFT, 159, -(height*16));
|
||||||
@@ -156,39 +170,62 @@ static void init_screen(void) {
|
|||||||
lv_style_set_bg_opa(&game_over_style, LV_OPA_100);
|
lv_style_set_bg_opa(&game_over_style, LV_OPA_100);
|
||||||
lv_style_set_text_align(&game_over_style, LV_TEXT_ALIGN_CENTER);
|
lv_style_set_text_align(&game_over_style, LV_TEXT_ALIGN_CENTER);
|
||||||
|
|
||||||
game_over_label = lv_label_create(lv_scr_act());
|
game_over_label = lv_label_create(scr);
|
||||||
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
lv_obj_align(game_over_label, LV_ALIGN_CENTER, 0, 0);
|
lv_obj_align(game_over_label, LV_ALIGN_LEFT_MID, 0, 0);
|
||||||
|
lv_obj_set_width(game_over_label, 160);
|
||||||
lv_obj_add_style(game_over_label, &game_over_style, LV_STATE_DEFAULT);
|
lv_obj_add_style(game_over_label, &game_over_style, LV_STATE_DEFAULT);
|
||||||
|
|
||||||
// for (int h = 0; h < height; h++) {
|
for (int h = 0; h < height; h++) {
|
||||||
// for (int w = 0; w < width; w++) {
|
for (int w = 0; w < width; w++) {
|
||||||
// visual_board[h][w] = lv_img_create(lv_scr_act());
|
visual_board[h][w] = lv_img_create(scr);
|
||||||
// lv_obj_align(visual_board[h][w], LV_ALIGN_BOTTOM_LEFT, 159 + w*16, -(h*16));
|
lv_obj_align(visual_board[h][w], LV_ALIGN_BOTTOM_LEFT, 159 + w*16, -(h*16));
|
||||||
// lv_img_set_src(visual_board[h][w], PIECE_IMG_SRC[((w+h)%7)+1]);
|
lv_obj_add_flag(visual_board[h][w], LV_OBJ_FLAG_HIDDEN);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
piece_imgs[i] = lv_img_create(lv_scr_act());
|
piece_imgs[i] = lv_img_create(scr);
|
||||||
lv_obj_align(piece_imgs[i], LV_ALIGN_BOTTOM_LEFT, 159, -320);
|
lv_obj_align(piece_imgs[i], LV_ALIGN_BOTTOM_LEFT, 159, -320);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
old_scr = lv_scr_act();
|
||||||
|
lv_scr_load(scr);
|
||||||
|
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
xSemaphoreGive(xGuiSemaphore);
|
||||||
|
|
||||||
xTaskCreate(music_task, "music", 4096, NULL, 5, NULL);
|
play_clip_wav(MUSIC_FILE, true, true, 4, 0);
|
||||||
|
music_playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deinit_screen(void) {
|
static void deinit_screen() {
|
||||||
while (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdFALSE) vTaskDelay(pdMS_TO_TICKS(10));
|
while (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdFALSE) vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
lv_scr_load(old_scr);
|
||||||
lv_obj_clean(lv_scr_act());
|
lv_obj_del(scr);
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
xSemaphoreGive(xGuiSemaphore);
|
||||||
|
|
||||||
playing_music = false;
|
if (!stop_clip(MUSIC_FILE, pdMS_TO_TICKS(1000))) {
|
||||||
uint8_t value = 0;
|
ESP_LOGW(TAG, "Can't stop, addicted to the shindig.");
|
||||||
if (!xQueueSend(stop_music, &value, pdMS_TO_TICKS(1000))) {
|
}
|
||||||
ESP_LOGE(TAG, "Faild to send stop queue");
|
music_playing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reveal_board() {
|
||||||
|
for (int h = 0; h < height; h++) {
|
||||||
|
for (int w = 0; w < width; w++) {
|
||||||
|
if (PIECE_IMG_SRC[board[h][w]]) {
|
||||||
|
lv_img_set_src(visual_board[h][w], PIECE_IMG_SRC[board[h][w]]);
|
||||||
|
lv_obj_clear_flag(visual_board[h][w], LV_OBJ_FLAG_HIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void hide_board() {
|
||||||
|
for (int h = 0; h < height; h++) {
|
||||||
|
for (int w = 0; w < width; w++) {
|
||||||
|
lv_obj_add_flag(visual_board[h][w], LV_OBJ_FLAG_HIDDEN);
|
||||||
|
lv_img_set_src(visual_board[h][w], NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,8 +234,11 @@ bool play_game(int time, int required_score) {
|
|||||||
target_score = required_score;
|
target_score = required_score;
|
||||||
score = 0;
|
score = 0;
|
||||||
update_score();
|
update_score();
|
||||||
set_module_time(time);
|
|
||||||
start_module_timer();
|
if (!play_modified) {
|
||||||
|
set_module_time(time);
|
||||||
|
start_module_timer();
|
||||||
|
}
|
||||||
|
|
||||||
clear_board();
|
clear_board();
|
||||||
|
|
||||||
@@ -236,7 +276,8 @@ bool play_game(int time, int required_score) {
|
|||||||
show_board();
|
show_board();
|
||||||
|
|
||||||
if (score >= required_score) {
|
if (score >= required_score) {
|
||||||
stop_module_timer();
|
if (!play_modified)
|
||||||
|
stop_module_timer();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,6 +287,20 @@ bool play_game(int time, int required_score) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Toggle music with switch4
|
||||||
|
SwitchKey switch_;
|
||||||
|
while (get_switch_flipped(&switch_)) {
|
||||||
|
if (switch_ == SwitchKey::s4) {
|
||||||
|
if (music_playing) {
|
||||||
|
stop_clip(MUSIC_FILE, 0);
|
||||||
|
music_playing = false;
|
||||||
|
} else {
|
||||||
|
play_clip_wav(MUSIC_FILE, true, true, 4, 0);
|
||||||
|
music_playing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (down_held != 0) {
|
if (down_held != 0) {
|
||||||
// check repeat
|
// check repeat
|
||||||
TickType_t now = xTaskGetTickCount();
|
TickType_t now = xTaskGetTickCount();
|
||||||
@@ -257,18 +312,20 @@ bool play_game(int time, int required_score) {
|
|||||||
show_board();
|
show_board();
|
||||||
|
|
||||||
if (score >= required_score) {
|
if (score >= required_score) {
|
||||||
stop_module_timer();
|
if (!play_modified)
|
||||||
|
stop_module_timer();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_module_time() <= 0) {
|
if ((!play_modified) && get_module_time() <= 0) {
|
||||||
stop_module_timer();
|
stop_module_timer();
|
||||||
strike("Out of time");
|
strike("Out of time");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (get_switch_flipped(&switch_)) {
|
// if (get_switch_flipped(&switch_)) {
|
||||||
// printf("%d\n", piece);
|
// printf("%d\n", piece);
|
||||||
// for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
// for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||||
@@ -283,13 +340,15 @@ bool play_game(int time, int required_score) {
|
|||||||
|
|
||||||
// game over
|
// game over
|
||||||
ESP_LOGI(TAG, "Game Over. Score: %d", score);
|
ESP_LOGI(TAG, "Game Over. Score: %d", score);
|
||||||
stop_module_timer();
|
if (!play_modified)
|
||||||
|
stop_module_timer();
|
||||||
strike("Out of room");
|
strike("Out of room");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete(void) {
|
static void complete() {
|
||||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||||
|
reveal_board();
|
||||||
lv_label_set_text(game_over_label, "Winner!\nPress any button to continue");
|
lv_label_set_text(game_over_label, "Winner!\nPress any button to continue");
|
||||||
lv_obj_clear_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_clear_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
xSemaphoreGive(xGuiSemaphore);
|
||||||
@@ -302,17 +361,20 @@ static void complete(void) {
|
|||||||
}
|
}
|
||||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||||
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
hide_board();
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
xSemaphoreGive(xGuiSemaphore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fail(void) {
|
static void fail() {
|
||||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||||
lv_label_set_text(game_over_label, "Game Over\nPress any button to continue");
|
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);
|
lv_obj_clear_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
|
||||||
|
reveal_board();
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
xSemaphoreGive(xGuiSemaphore);
|
||||||
}
|
}
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
while (get_button_pressed(nullptr));
|
while (get_button_pressed(nullptr));
|
||||||
while (1) {
|
while (1) {
|
||||||
if (get_button_pressed(nullptr)) break;
|
if (get_button_pressed(nullptr)) break;
|
||||||
@@ -320,11 +382,12 @@ static void fail(void) {
|
|||||||
}
|
}
|
||||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||||
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
hide_board();
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
xSemaphoreGive(xGuiSemaphore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void step4(void) {
|
void p001_step4() {
|
||||||
StarCodeHandler star_code = {
|
StarCodeHandler star_code = {
|
||||||
.code = "*3850",
|
.code = "*3850",
|
||||||
.display_text = "Starting...",
|
.display_text = "Starting...",
|
||||||
@@ -334,18 +397,23 @@ void step4(void) {
|
|||||||
do_star_codes(&star_code, 1);
|
do_star_codes(&star_code, 1);
|
||||||
init_screen();
|
init_screen();
|
||||||
|
|
||||||
while (!play_game(4*60*1000, 2)) fail();
|
int lines_1 = play_modified ? 2 : 2;
|
||||||
|
int lines_2 = play_modified ? 5 : 4;
|
||||||
|
int lines_3 = play_modified ? 12 : 8;
|
||||||
|
while (!play_game(4*60*1000, lines_1)) fail();
|
||||||
|
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
|
||||||
complete();
|
complete();
|
||||||
while (!play_game(4*60*1000, 4)) fail();
|
while (!play_game(4*60*1000, lines_2)) fail();
|
||||||
|
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
|
||||||
complete();
|
complete();
|
||||||
while (!play_game(7*60*1000, 8)) fail();
|
while (!play_game(6*60*1000, lines_3)) fail();
|
||||||
|
play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0);
|
||||||
complete();
|
complete();
|
||||||
// vTaskDelay(pdMS_TO_TICKS(3000));
|
|
||||||
|
|
||||||
deinit_screen();
|
deinit_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_board(void) {
|
static void show_board() {
|
||||||
for (int h = 0; h < height; h++) {
|
for (int h = 0; h < height; h++) {
|
||||||
for (int w = 0; w < width; w++) {
|
for (int w = 0; w < width; w++) {
|
||||||
if (board[h][w] == 9) {
|
if (board[h][w] == 9) {
|
||||||
@@ -359,16 +427,6 @@ static void show_board(void) {
|
|||||||
board[p[0]][p[1]] = 9;
|
board[p[0]][p[1]] = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text_output) {
|
|
||||||
for (int h = height-1; h >= 0; h--) {
|
|
||||||
for (int w = 0; w < width; w++) {
|
|
||||||
printf("|%c", board[h][w] == 9 ? 'X' : (invisible_blocks ? '0' : ('0' + board[h][w])));
|
|
||||||
}
|
|
||||||
printf("|\n");
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||||
int* p = piece_nodes[i];
|
int* p = piece_nodes[i];
|
||||||
@@ -379,7 +437,7 @@ static void show_board(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generate_block(void) {
|
static void generate_block() {
|
||||||
int new_piece = piece_dist(gen);
|
int new_piece = piece_dist(gen);
|
||||||
if (new_piece == piece) {
|
if (new_piece == piece) {
|
||||||
new_piece = 1;
|
new_piece = 1;
|
||||||
@@ -414,7 +472,7 @@ static void generate_block(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rotate_block(void) {
|
static void rotate_block() {
|
||||||
piece_rotation++;
|
piece_rotation++;
|
||||||
if (piece_rotation > 3) {
|
if (piece_rotation > 3) {
|
||||||
piece_rotation = 0;
|
piece_rotation = 0;
|
||||||
@@ -492,7 +550,7 @@ static void rotate_block(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if nodes are outside of map or interposed onto placed nodes
|
// Check if nodes are outside of map or interposed onto placed nodes
|
||||||
static bool check_overlap(void) {
|
static bool check_overlap() {
|
||||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||||
int* p = piece_nodes[i];
|
int* p = piece_nodes[i];
|
||||||
if (p[0] < 0 || p[1] < 0 || p[1] >= width) {
|
if (p[0] < 0 || p[1] < 0 || p[1] >= width) {
|
||||||
@@ -504,7 +562,7 @@ static bool check_overlap(void) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void move_left(void) {
|
static void move_left() {
|
||||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||||
int* p = piece_nodes[i];
|
int* p = piece_nodes[i];
|
||||||
if (p[1] == 0) {
|
if (p[1] == 0) {
|
||||||
@@ -518,7 +576,7 @@ static void move_left(void) {
|
|||||||
get_node_locations();
|
get_node_locations();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void move_right(void) {
|
static void move_right() {
|
||||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||||
int* p = piece_nodes[i];
|
int* p = piece_nodes[i];
|
||||||
if (p[1] == width-1) {
|
if (p[1] == width-1) {
|
||||||
@@ -531,7 +589,7 @@ static void move_right(void) {
|
|||||||
get_node_locations();
|
get_node_locations();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drop(void) {
|
static void drop() {
|
||||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||||
int* p = piece_nodes[i];
|
int* p = piece_nodes[i];
|
||||||
if (p[0] == 0) {
|
if (p[0] == 0) {
|
||||||
@@ -551,7 +609,7 @@ static void drop(void) {
|
|||||||
get_node_locations();
|
get_node_locations();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void place_piece(void) {
|
static void place_piece() {
|
||||||
for (int h = 0; h < height; h++) {
|
for (int h = 0; h < height; h++) {
|
||||||
for (int w = 0; w < width; w++) {
|
for (int w = 0; w < width; w++) {
|
||||||
if (board[h][w] == 9) {
|
if (board[h][w] == 9) {
|
||||||
@@ -640,7 +698,7 @@ static void get_node_locations() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_line_clears(void) {
|
static void check_line_clears() {
|
||||||
for (int h = height-2; h >= 0; h--) {
|
for (int h = height-2; h >= 0; h--) {
|
||||||
for (int w = 0; w < width; w++) {
|
for (int w = 0; w < width; w++) {
|
||||||
if (board[h][w] != 0 && board[h][w] != 9) {
|
if (board[h][w] != 0 && board[h][w] != 9) {
|
||||||
@@ -654,7 +712,7 @@ static void check_line_clears(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_score(void) {
|
static void update_score() {
|
||||||
char buff[16] = {};
|
char buff[16] = {};
|
||||||
sprintf(buff, "%d/%d", score, target_score);
|
sprintf(buff, "%d/%d", score, target_score);
|
||||||
lcd_clear();
|
lcd_clear();
|
||||||
@@ -691,7 +749,7 @@ static void line_clear(int hi) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_board(void) {
|
void clear_board() {
|
||||||
for (int h = 0; h < height; h++) {
|
for (int h = 0; h < height; h++) {
|
||||||
for (int w = 0; w < width; w++) {
|
for (int w = 0; w < width; w++) {
|
||||||
board[h][w] = 0;
|
board[h][w] = 0;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef STEP_4_H
|
#ifndef P001_STEP_4_H
|
||||||
#define STEP_4_H
|
#define P001_STEP_4_H
|
||||||
|
|
||||||
#include <random>
|
#include <random>
|
||||||
#include "../drivers/tft.h"
|
#include "../drivers/tft.h"
|
||||||
@@ -10,14 +10,9 @@
|
|||||||
#include "../drivers/char_lcd.h"
|
#include "../drivers/char_lcd.h"
|
||||||
#include "../helper.h"
|
#include "../helper.h"
|
||||||
|
|
||||||
// TODO:
|
#define TETRIS_USE_FLASH_IMG
|
||||||
// - [ ] set up real game loop
|
#define TETRIS_USE_FLASH_BG_IMG
|
||||||
// - [ ] stop music
|
|
||||||
// - [ ] set up strike on falure
|
|
||||||
// - [ ] set up module timer
|
|
||||||
|
|
||||||
|
void p001_step4(void);
|
||||||
|
|
||||||
|
#endif /* P001_STEP_4_H */
|
||||||
void step4(void);
|
|
||||||
|
|
||||||
#endif /* STEP_4_H */
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "step5.h"
|
#include "p001_step5.h"
|
||||||
|
|
||||||
#define TIME_CLEAR 30'000
|
#define TIME_CLEAR 30'000
|
||||||
#define TIME_PLANK 40'000
|
#define TIME_PLANK 40'000
|
||||||
@@ -21,23 +21,23 @@ static std::uniform_int_distribution<> puzzle_dist(0, 7);
|
|||||||
static std::uniform_int_distribution<> led_picker_dist(0, 20);
|
static std::uniform_int_distribution<> led_picker_dist(0, 20);
|
||||||
static std::uniform_int_distribution<> led_color_dist(0, 5);
|
static std::uniform_int_distribution<> led_color_dist(0, 5);
|
||||||
|
|
||||||
void set_unique_leds(std::vector<int>& input_options, const int num, const int r, const int g, const int b) {
|
void set_unique_leds(std::vector<int>& input_options, const int num, const uint32_t color) {
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
std::uniform_int_distribution<> led_option_dist(0, input_options.size() - 1);
|
std::uniform_int_distribution<> led_option_dist(0, input_options.size() - 1);
|
||||||
int led = led_option_dist(gen);
|
int led = led_option_dist(gen);
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, input_options[led], r, g, b));
|
led_set(input_options[led], color);
|
||||||
input_options.erase(input_options.begin() + led);
|
input_options.erase(input_options.begin() + led);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_unique_leds_random_color(std::vector<int>& input_options, const int num, const int* r, const int* g, const int* b) {
|
void set_unique_leds_random_color(std::vector<int>& input_options, const int num, const uint32_t* COLORS, size_t COLORS_len) {
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
std::uniform_int_distribution<> led_option_dist(0, input_options.size() - 1);
|
std::uniform_int_distribution<> led_option_dist(0, input_options.size() - 1);
|
||||||
int led = led_option_dist(gen);
|
int led = led_option_dist(gen);
|
||||||
|
|
||||||
std::uniform_int_distribution<> led_color_dist(0, sizeof(r) - 1);
|
std::uniform_int_distribution<> led_color_dist(0, COLORS_len - 1);
|
||||||
int color = led_color_dist(gen);
|
int color = led_color_dist(gen);
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, input_options[led], r[color], g[color], b[color]));
|
led_set(input_options[led], COLORS[color]);
|
||||||
input_options.erase(input_options.begin() + led);
|
input_options.erase(input_options.begin() + led);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ bool submit_6(bool* buttons_cycling, bool button_turned_on, int led_off) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void step5(void) {
|
void p001_step5(void) {
|
||||||
StarCodeHandler star_codes[] = {
|
StarCodeHandler star_codes[] = {
|
||||||
{
|
{
|
||||||
.code = "*2648",
|
.code = "*2648",
|
||||||
@@ -196,9 +196,14 @@ void step5(void) {
|
|||||||
all_leds.push_back(i);
|
all_leds.push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int INDICATOR_RED[6] = {20, 0, 0, 10, 10, 5};
|
const uint32_t COLORS[] = {
|
||||||
const int INDICATOR_GREEN[6] = {0, 0, 10, 5, 0, 7};
|
LEDColor::LED_COLOR_RED,
|
||||||
const int INDICATOR_BLUE[6] = {0, 10, 0, 0, 5, 5};
|
LEDColor::LED_COLOR_BLUE,
|
||||||
|
LEDColor::LED_COLOR_GREEN,
|
||||||
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
|
LEDColor::LED_COLOR_PINK,
|
||||||
|
LEDColor::LED_COLOR_WHITE,
|
||||||
|
};
|
||||||
static std::uniform_int_distribution<> led_number_dist(0, 21);
|
static std::uniform_int_distribution<> led_number_dist(0, 21);
|
||||||
|
|
||||||
int last_cycle_tick = xTaskGetTickCount();
|
int last_cycle_tick = xTaskGetTickCount();
|
||||||
@@ -207,8 +212,8 @@ void step5(void) {
|
|||||||
if ((xTaskGetTickCount() - last_cycle_tick) > pdMS_TO_TICKS(100)) {
|
if ((xTaskGetTickCount() - last_cycle_tick) > pdMS_TO_TICKS(100)) {
|
||||||
clean_bomb();
|
clean_bomb();
|
||||||
std::vector<int> led_options = all_leds;
|
std::vector<int> led_options = all_leds;
|
||||||
set_unique_leds_random_color(led_options, led_number_dist(gen), INDICATOR_RED, INDICATOR_GREEN, INDICATOR_BLUE);
|
set_unique_leds_random_color(led_options, led_number_dist(gen), COLORS, sizeof(COLORS)/sizeof(COLORS[0]));
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
last_cycle_tick = xTaskGetTickCount();
|
last_cycle_tick = xTaskGetTickCount();
|
||||||
scrambled_times++;
|
scrambled_times++;
|
||||||
}
|
}
|
||||||
@@ -234,16 +239,18 @@ void step5(void) {
|
|||||||
// set green
|
// set green
|
||||||
std::uniform_int_distribution<> green_indicators_dist(1, 15);
|
std::uniform_int_distribution<> green_indicators_dist(1, 15);
|
||||||
uint8_t green_indicators = green_indicators_dist(gen);
|
uint8_t green_indicators = green_indicators_dist(gen);
|
||||||
set_unique_leds(indicator_options, green_indicators, 0, 10, 0);
|
set_unique_leds(indicator_options, green_indicators, LEDColor::LED_COLOR_GREEN);
|
||||||
|
|
||||||
// set non-green
|
// set non-green
|
||||||
const int NON_GREEN_INDICATOR_RED[3] = {20, 0, 10};
|
const uint32_t NON_GREEN_COLORS[] = {
|
||||||
const int NON_GREEN_INDICATOR_GREEN[3] = {0, 0, 0};
|
LEDColor::LED_COLOR_RED,
|
||||||
const int NON_GREEN_INDICATOR_BLUE[3] = {0, 10, 5};
|
LEDColor::LED_COLOR_BLUE,
|
||||||
|
LEDColor::LED_COLOR_PINK,
|
||||||
|
};
|
||||||
std::uniform_int_distribution<> non_green_indicators_dist(0, (20 - green_indicators));
|
std::uniform_int_distribution<> non_green_indicators_dist(0, (20 - green_indicators));
|
||||||
set_unique_leds_random_color(indicator_options, non_green_indicators_dist(gen), NON_GREEN_INDICATOR_RED, NON_GREEN_INDICATOR_GREEN, NON_GREEN_INDICATOR_BLUE);
|
set_unique_leds_random_color(indicator_options, non_green_indicators_dist(gen), NON_GREEN_COLORS, sizeof(NON_GREEN_COLORS)/sizeof(NON_GREEN_COLORS[0]));
|
||||||
|
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
|
|
||||||
// wait for submit
|
// wait for submit
|
||||||
KeypadKey key;
|
KeypadKey key;
|
||||||
@@ -266,12 +273,9 @@ void step5(void) {
|
|||||||
uint8_t indicators_num = on_indicators_dist(gen);
|
uint8_t indicators_num = on_indicators_dist(gen);
|
||||||
|
|
||||||
std::vector<int> indicator_options = all_leds;
|
std::vector<int> indicator_options = all_leds;
|
||||||
const int INDICATOR_RED[6] = {20, 0, 0, 10, 10, 5};
|
|
||||||
const int INDICATOR_GREEN[6] = {0, 0, 10, 5, 0, 7};
|
|
||||||
const int INDICATOR_BLUE[6] = {0, 10, 0, 0, 5, 5};
|
|
||||||
|
|
||||||
set_unique_leds_random_color(indicator_options, indicators_num, INDICATOR_RED, INDICATOR_BLUE, INDICATOR_GREEN);
|
set_unique_leds_random_color(indicator_options, indicators_num, COLORS, sizeof(COLORS)/sizeof(COLORS[0]));
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
|
|
||||||
uint8_t starting_switch_state = get_switch_state();
|
uint8_t starting_switch_state = get_switch_state();
|
||||||
std::string pressed_keys;
|
std::string pressed_keys;
|
||||||
@@ -315,10 +319,10 @@ void step5(void) {
|
|||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
if (lit_leds[i]) {
|
if (lit_leds[i]) {
|
||||||
int color = led_color_dist(gen);
|
int color = led_color_dist(gen);
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, idx_to_led_map[i], INDICATOR_RED[color], INDICATOR_GREEN[color], INDICATOR_BLUE[color]));
|
led_set(idx_to_led_map[i], COLORS[color]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
|
|
||||||
int green_button_pressed = 0;
|
int green_button_pressed = 0;
|
||||||
int blue_button_pressed = 0;
|
int blue_button_pressed = 0;
|
||||||
@@ -379,9 +383,12 @@ void step5(void) {
|
|||||||
set_module_time(TIME_NOTHING);
|
set_module_time(TIME_NOTHING);
|
||||||
start_module_timer();
|
start_module_timer();
|
||||||
|
|
||||||
const int COLOR_RED[5] = {0, 20, 10, 0};
|
const uint32_t COLORS[] = {
|
||||||
const int COLOR_GREEN[5] = {20, 0, 10, 0};
|
LEDColor::LED_COLOR_GREEN,
|
||||||
const int COLOR_BLUE[5] = {0, 0, 0, 20};
|
LEDColor::LED_COLOR_RED,
|
||||||
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
|
LEDColor::LED_COLOR_BLUE,
|
||||||
|
};
|
||||||
|
|
||||||
static std::uniform_int_distribution<> color_dist(0, 3);
|
static std::uniform_int_distribution<> color_dist(0, 3);
|
||||||
|
|
||||||
@@ -389,10 +396,10 @@ void step5(void) {
|
|||||||
int speaker_color = color_dist(gen);
|
int speaker_color = color_dist(gen);
|
||||||
int s3_color = color_dist(gen);
|
int s3_color = color_dist(gen);
|
||||||
|
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, 6, COLOR_RED[tft_color], COLOR_GREEN[tft_color], COLOR_BLUE[tft_color]));
|
led_set(IndicatorLED::LED_TFT, COLORS[tft_color]);
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, 9, COLOR_RED[speaker_color], COLOR_GREEN[speaker_color], COLOR_BLUE[speaker_color]));
|
led_set(IndicatorLED::LED_SPEAKER, COLORS[speaker_color]);
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, 14, COLOR_RED[s3_color], COLOR_GREEN[s3_color], COLOR_BLUE[s3_color]));
|
led_set(IndicatorLED::LED_S3, COLORS[s3_color]);
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
|
|
||||||
int buttons_pressed = 0;
|
int buttons_pressed = 0;
|
||||||
|
|
||||||
@@ -436,30 +443,36 @@ void step5(void) {
|
|||||||
start_module_timer();
|
start_module_timer();
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
const int BUTTON_COLOR_RED[4] = {0, 20, 10, 0};
|
const uint32_t BUTTON_COLORS[] = {
|
||||||
const int BUTTON_COLOR_GREEN[4] = {10, 0, 5, 0};
|
LEDColor::LED_COLOR_GREEN,
|
||||||
const int BUTTON_COLOR_BLUE[4] = {0, 0, 0, 10};
|
LEDColor::LED_COLOR_RED,
|
||||||
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
|
LEDColor::LED_COLOR_BLUE,
|
||||||
|
};
|
||||||
|
|
||||||
static std::uniform_int_distribution<> button_color_dist(0, 3);
|
static std::uniform_int_distribution<> button_color_dist(0, 3);
|
||||||
int button_colors[4] = {button_color_dist(gen), button_color_dist(gen), button_color_dist(gen), button_color_dist(gen)};
|
int button_colors[4] = {button_color_dist(gen), button_color_dist(gen), button_color_dist(gen), button_color_dist(gen)};
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, (20 - i), BUTTON_COLOR_RED[button_colors[i]], BUTTON_COLOR_GREEN[button_colors[i]], BUTTON_COLOR_BLUE[button_colors[i]]));
|
led_set(IndicatorLED::LED_B1 - i, BUTTON_COLORS[button_colors[i]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// switches
|
// switches
|
||||||
const int SWITCH_COLOR_RED[3] = {20, 0, 10};
|
const uint32_t SWITCH_COLOR[] = {
|
||||||
const int SWITCH_COLOR_GREEN[3] = {0, 10, 5};
|
LEDColor::LED_COLOR_RED,
|
||||||
|
LEDColor::LED_COLOR_GREEN,
|
||||||
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
|
};
|
||||||
|
|
||||||
static std::uniform_int_distribution<> switch_color_dist(0, 2);
|
static std::uniform_int_distribution<> switch_color_dist(0, 2);
|
||||||
|
|
||||||
int switch_colors[4] = {switch_color_dist(gen), switch_color_dist(gen), switch_color_dist(gen), switch_color_dist(gen)};
|
int switch_colors[4] = {switch_color_dist(gen), switch_color_dist(gen), switch_color_dist(gen), switch_color_dist(gen)};
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, (16 - i), SWITCH_COLOR_RED[switch_colors[i]], SWITCH_COLOR_GREEN[switch_colors[i]], 0));
|
led_set(IndicatorLED::LED_S1 - i, SWITCH_COLOR[switch_colors[i]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
|
|
||||||
ButtonKey button;
|
ButtonKey button;
|
||||||
KeypadKey key;
|
KeypadKey key;
|
||||||
@@ -475,11 +488,10 @@ void step5(void) {
|
|||||||
if (button_colors[i] > 3) {
|
if (button_colors[i] > 3) {
|
||||||
button_colors[i] = 0;
|
button_colors[i] = 0;
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, (20 - i), BUTTON_COLOR_RED[button_colors[i]], BUTTON_COLOR_GREEN[button_colors[i]], BUTTON_COLOR_BLUE[button_colors[i]]));
|
led_set(IndicatorLED::LED_B1 - i, BUTTON_COLORS[button_colors[i]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
}
|
}
|
||||||
if (get_module_time() <= 0 || (get_keypad_pressed(&key) && (char_of_keypad_key(key) == '#'))) {
|
if (get_module_time() <= 0 || (get_keypad_pressed(&key) && (char_of_keypad_key(key) == '#'))) {
|
||||||
solved_correctly = submit_4(button_colors, switch_colors, starting_switch_state);
|
solved_correctly = submit_4(button_colors, switch_colors, starting_switch_state);
|
||||||
@@ -496,18 +508,21 @@ void step5(void) {
|
|||||||
|
|
||||||
std::uniform_int_distribution<> indicator_number_dist(0, 5);
|
std::uniform_int_distribution<> indicator_number_dist(0, 5);
|
||||||
|
|
||||||
const int INDICATOR_RED[4] = {0, 20, 10, 0};
|
const uint32_t COLORS[] = {
|
||||||
const int INDICATOR_GREEN[4] = {10, 0, 5, 0};
|
LEDColor::LED_COLOR_GREEN,
|
||||||
const int INDICATOR_BLUE[4] = {0, 0, 0, 10};
|
LEDColor::LED_COLOR_RED,
|
||||||
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
|
LEDColor::LED_COLOR_BLUE,
|
||||||
|
};
|
||||||
|
|
||||||
// green, red, yellow, blue
|
// green, red, yellow, blue
|
||||||
std::array<int, 4> indicator_numbers = {indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen)};
|
std::array<int, 4> indicator_numbers = {indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen)};
|
||||||
std::vector<int> indicator_options = all_leds;
|
std::vector<int> indicator_options = all_leds;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
set_unique_leds(indicator_options, indicator_numbers[i], INDICATOR_RED[i], INDICATOR_GREEN[i], INDICATOR_BLUE[i]);
|
set_unique_leds(indicator_options, indicator_numbers[i], COLORS[i]);
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
|
|
||||||
std::array<int, 4> buttons_pressed = {0, 0, 0, 0};
|
std::array<int, 4> buttons_pressed = {0, 0, 0, 0};
|
||||||
ButtonKey button;
|
ButtonKey button;
|
||||||
@@ -550,10 +565,14 @@ void step5(void) {
|
|||||||
std::uniform_int_distribution<> led_color_dist(0, 5);
|
std::uniform_int_distribution<> led_color_dist(0, 5);
|
||||||
std::uniform_int_distribution<> led_off_dist(-1, 3);
|
std::uniform_int_distribution<> led_off_dist(-1, 3);
|
||||||
|
|
||||||
// red, purple, blue, white, green, yellow
|
const uint32_t COLORS[] = {
|
||||||
const uint8_t COLORS_RED[6] = {20, 10, 0, 5, 0, 10};
|
LEDColor::LED_COLOR_RED,
|
||||||
const uint8_t COLORS_GREEN[6] = {0, 0, 0, 7, 10, 5};
|
LEDColor::LED_COLOR_PINK,
|
||||||
const uint8_t COLORS_BLUE[6] = {0, 10, 10, 5, 0, 0};
|
LEDColor::LED_COLOR_BLUE,
|
||||||
|
LEDColor::LED_COLOR_WHITE,
|
||||||
|
LEDColor::LED_COLOR_GREEN,
|
||||||
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
|
};
|
||||||
|
|
||||||
int button_colors[4];
|
int button_colors[4];
|
||||||
bool buttons_cycling[4];
|
bool buttons_cycling[4];
|
||||||
@@ -562,14 +581,14 @@ void step5(void) {
|
|||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (led_off != i) {
|
if (led_off != i) {
|
||||||
button_colors[i] = led_color_dist(gen);
|
button_colors[i] = led_color_dist(gen);
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, (20 - i), COLORS_RED[button_colors[i]], COLORS_GREEN[button_colors[i]], COLORS_BLUE[button_colors[i]]));
|
led_set(IndicatorLED::LED_B1 - i, COLORS[button_colors[i]]);
|
||||||
buttons_cycling[i] = true;
|
buttons_cycling[i] = true;
|
||||||
} else {
|
} else {
|
||||||
button_colors[i] = -1;
|
button_colors[i] = -1;
|
||||||
buttons_cycling[i] = false;
|
buttons_cycling[i] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
|
|
||||||
const uint8_t CORRECT_COLORS[4] = {4, 0, 5, 2};
|
const uint8_t CORRECT_COLORS[4] = {4, 0, 5, 2};
|
||||||
TickType_t lastCycleTime = xTaskGetTickCount();
|
TickType_t lastCycleTime = xTaskGetTickCount();
|
||||||
@@ -593,8 +612,8 @@ void step5(void) {
|
|||||||
break;
|
break;
|
||||||
} else if (led_turn_on_dist(gen) == 0) {
|
} else if (led_turn_on_dist(gen) == 0) {
|
||||||
button_turned_on = true;
|
button_turned_on = true;
|
||||||
led_strip_set_pixel(leds, (20 - i), COLORS_RED[CORRECT_COLORS[i]], COLORS_GREEN[CORRECT_COLORS[i]], COLORS_BLUE[CORRECT_COLORS[i]]);
|
led_set(IndicatorLED::LED_B1 - i, COLORS[CORRECT_COLORS[i]]);
|
||||||
led_strip_refresh(leds);
|
leds_flush();
|
||||||
}
|
}
|
||||||
} else if (button_colors[i] != CORRECT_COLORS[i]) {
|
} else if (button_colors[i] != CORRECT_COLORS[i]) {
|
||||||
strike("Wrong time!");
|
strike("Wrong time!");
|
||||||
@@ -610,16 +629,16 @@ void step5(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((xTaskGetTickCount() - lastCycleTime) >= pdMS_TO_TICKS(500)) {
|
if ((xTaskGetTickCount() - lastCycleTime) >= pdMS_TO_TICKS(500)) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (uint32_t i = 0; i < 4; i++) {
|
||||||
if (buttons_cycling[i]) {
|
if (buttons_cycling[i]) {
|
||||||
button_colors[i]++;
|
button_colors[i]++;
|
||||||
if (button_colors[i] > 5) {
|
if (button_colors[i] > 5) {
|
||||||
button_colors[i] = 0;
|
button_colors[i] = 0;
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, (20 - i), COLORS_RED[button_colors[i]], COLORS_GREEN[button_colors[i]], COLORS_BLUE[button_colors[i]]));
|
led_set(IndicatorLED::LED_B1 - i, COLORS[button_colors[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
leds_flush();
|
||||||
|
|
||||||
lastCycleTime = xTaskGetTickCount();
|
lastCycleTime = xTaskGetTickCount();
|
||||||
}
|
}
|
||||||
@@ -632,253 +651,260 @@ void step5(void) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 7: {
|
case 7: {
|
||||||
lcd_print("What");
|
if (play_modified) {
|
||||||
set_module_time(TIME_WHAT);
|
// do PLINK
|
||||||
start_module_timer();
|
lcd_print("Plink");
|
||||||
|
set_module_time(TIME_PLINK);
|
||||||
|
start_module_timer();
|
||||||
|
|
||||||
std::uniform_int_distribution<> math_number_dist(1, 9);
|
std::uniform_int_distribution<> indicator_number_dist(0, 4);
|
||||||
|
|
||||||
std::vector<float> math_numbers;
|
// ESP_LOGI(TAG, "Green: %i, Red: %i, Yellow: %i, Blue: %i", green_indicators, red_indicators, yellow_indicators, blue_indicators);
|
||||||
std::vector<int> math_operations;
|
|
||||||
|
|
||||||
std::map<int, char> operation_map = {
|
const uint32_t COLORS[] = {
|
||||||
{0, '+'},
|
LEDColor::LED_COLOR_GREEN,
|
||||||
{1, '-'},
|
LEDColor::LED_COLOR_RED,
|
||||||
{2, '*'},
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
{3, '/'},
|
LEDColor::LED_COLOR_BLUE,
|
||||||
};
|
LEDColor::LED_COLOR_PINK,
|
||||||
|
|
||||||
int expression_answer = -1;
|
|
||||||
std::string display_expression;
|
|
||||||
|
|
||||||
while (expression_answer < 0) {
|
|
||||||
math_numbers = {static_cast<float>(math_number_dist(gen)), static_cast<float>(math_number_dist(gen)), static_cast<float>(math_number_dist(gen)), static_cast<float>(math_number_dist(gen))};
|
|
||||||
std::vector<int> possible_math_operations = {0, 1, 2, 3};
|
|
||||||
math_operations = unique_values(possible_math_operations, 3);
|
|
||||||
|
|
||||||
display_expression = std::to_string(static_cast<int>(math_numbers[0]));
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
display_expression += operation_map[math_operations[i]];
|
|
||||||
display_expression += std::to_string(static_cast<int>(math_numbers[i + 1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Solve
|
|
||||||
for (int j = 0; j < 3; j++) {
|
|
||||||
bool found = false;
|
|
||||||
for (int i = 0; i < math_operations.size(); i++) {
|
|
||||||
if (math_operations[i] == 2) {
|
|
||||||
// ESP_LOGI(TAG, "i = %i, condensing %f * %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] * math_numbers[i+1]));
|
|
||||||
math_numbers[i] = math_numbers[i] * math_numbers[i + 1];
|
|
||||||
math_numbers.erase(math_numbers.begin() + i + 1);
|
|
||||||
math_operations.erase(math_operations.begin() + i);
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
} else if (math_operations[i] == 3) {
|
|
||||||
// ESP_LOGI(TAG, "i = %i, condensing %f / %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] / math_numbers[i+1]));
|
|
||||||
math_numbers[i] = math_numbers[i] / math_numbers[i + 1];
|
|
||||||
math_numbers.erase(math_numbers.begin() + i + 1);
|
|
||||||
math_operations.erase(math_operations.begin() + i);
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found) continue;
|
|
||||||
for (int i = 0; i < math_operations.size(); i++) {
|
|
||||||
if (math_operations[i] == 0) {
|
|
||||||
// ESP_LOGI(TAG, "i = %i, condensing %f + %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] + math_numbers[i+1]));
|
|
||||||
math_numbers[i] = math_numbers[i] + math_numbers[i + 1];
|
|
||||||
math_numbers.erase(math_numbers.begin() + i + 1);
|
|
||||||
math_operations.erase(math_operations.begin() + i);
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
} else if (math_operations[i] == 1) {
|
|
||||||
// ESP_LOGI(TAG, "i = %i, condensing %f - %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] - math_numbers[i+1]));
|
|
||||||
math_numbers[i] = math_numbers[i] - math_numbers[i + 1];
|
|
||||||
math_numbers.erase(math_numbers.begin() + i + 1);
|
|
||||||
math_operations.erase(math_operations.begin() + i);
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expression_answer = static_cast<int>(std::floor(math_numbers[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// display expression
|
|
||||||
lcd_print(1, 2, display_expression.c_str());
|
|
||||||
|
|
||||||
// set LEDs
|
|
||||||
|
|
||||||
// blue, red, green, yellow
|
|
||||||
const int INDICATOR_RED[4] = {0, 20, 0, 10};
|
|
||||||
const int INDICATOR_GREEN[4] = {0, 0, 10, 5};
|
|
||||||
const int INDICATOR_BLUE[4] = {10, 0, 0, 0};
|
|
||||||
|
|
||||||
std::uniform_int_distribution<> add_sub_indicator_dist(1, 6);
|
|
||||||
std::uniform_int_distribution<> mult_div_indicator_dist(1, 3);
|
|
||||||
|
|
||||||
int modifier_indicators[4] = {add_sub_indicator_dist(gen), add_sub_indicator_dist(gen), mult_div_indicator_dist(gen), mult_div_indicator_dist(gen)};
|
|
||||||
|
|
||||||
|
|
||||||
while ((((expression_answer + (modifier_indicators[0] * 3) - modifier_indicators[1]) * std::pow(3, modifier_indicators[2])) / std::pow(2, modifier_indicators[3])) < 0) {
|
|
||||||
modifier_indicators[0] = add_sub_indicator_dist(gen);
|
|
||||||
modifier_indicators[1] = add_sub_indicator_dist(gen);
|
|
||||||
modifier_indicators[2] = mult_div_indicator_dist(gen);
|
|
||||||
modifier_indicators[3] = mult_div_indicator_dist(gen);
|
|
||||||
}
|
|
||||||
|
|
||||||
expression_answer += modifier_indicators[0] * 3;
|
|
||||||
expression_answer -= modifier_indicators[1];
|
|
||||||
expression_answer *= std::pow(3, modifier_indicators[2]);
|
|
||||||
expression_answer /= std::pow(2, modifier_indicators[3]);
|
|
||||||
|
|
||||||
std::vector<int> led_options = all_leds;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
set_unique_leds(led_options, modifier_indicators[i], INDICATOR_RED[i], INDICATOR_GREEN[i], INDICATOR_BLUE[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
|
||||||
|
|
||||||
std::string answer_string = std::to_string(expression_answer);
|
|
||||||
std::string entered_string = "";
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Solved full answer: %s", answer_string.c_str());
|
|
||||||
|
|
||||||
KeypadKey key;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (get_keypad_pressed(&key)) {
|
|
||||||
if (key == KeypadKey::star) {
|
|
||||||
// clear
|
|
||||||
entered_string = "";
|
|
||||||
} else if (key == KeypadKey::pound) {
|
|
||||||
// submit
|
|
||||||
if (entered_string != answer_string) {
|
|
||||||
strike("Incorrect answer!");
|
|
||||||
} else {
|
|
||||||
solved_correctly = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
entered_string += char_of_keypad_key(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
lcd_clear();
|
|
||||||
lcd_print(1, 1, "What");
|
|
||||||
lcd_print(1, 2, display_expression.c_str());
|
|
||||||
lcd_print(1, 3, entered_string.c_str());
|
|
||||||
}
|
|
||||||
if (get_module_time() <= 0) {
|
|
||||||
strike("Ran out of time!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 8: {
|
|
||||||
lcd_print("Plink");
|
|
||||||
set_module_time(TIME_PLINK);
|
|
||||||
start_module_timer();
|
|
||||||
|
|
||||||
std::uniform_int_distribution<> indicator_number_dist(0, 4);
|
|
||||||
|
|
||||||
// ESP_LOGI(TAG, "Green: %i, Red: %i, Yellow: %i, Blue: %i", green_indicators, red_indicators, yellow_indicators, blue_indicators);
|
|
||||||
|
|
||||||
// green, red, yellow, blue, purple
|
|
||||||
const int INDICATOR_RED[5] = {0, 20, 10, 0, 10};
|
|
||||||
const int INDICATOR_GREEN[5] = {10, 0, 5, 0, 0};
|
|
||||||
const int INDICATOR_BLUE[5] = {0, 0, 0, 10, 5};
|
|
||||||
|
|
||||||
int solved_times = 0;
|
|
||||||
bool failed = false;
|
|
||||||
while (solved_times < 3 && !failed) {
|
|
||||||
int indicator_numbers[5] = {indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen)};
|
|
||||||
|
|
||||||
std::vector<int> led_options = all_leds;
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
set_unique_leds(led_options, indicator_numbers[i], INDICATOR_RED[i], INDICATOR_GREEN[i], INDICATOR_BLUE[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
|
||||||
|
|
||||||
std::uniform_int_distribution<> answer_color_dist(0, 4);
|
|
||||||
|
|
||||||
std::map<int, std::string> color_name_map = {
|
|
||||||
{0, "Green"},
|
|
||||||
{1, "Red"},
|
|
||||||
{2, "Yellow"},
|
|
||||||
{3, "Blue"},
|
|
||||||
{4, "Purple"},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int answer_color = answer_color_dist(gen);
|
int solved_times = 0;
|
||||||
|
bool failed = false;
|
||||||
|
while (solved_times < 3 && !failed) {
|
||||||
|
int indicator_numbers[5] = {indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen)};
|
||||||
|
|
||||||
std::string color_string = color_name_map[answer_color];
|
std::vector<int> led_options = all_leds;
|
||||||
std::string answer_num = std::to_string(indicator_numbers[answer_color]);
|
for (int i = 0; i < 5; i++) {
|
||||||
|
set_unique_leds(led_options, indicator_numbers[i], COLORS[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// ESP_LOGI(TAG, "color string: %s", color_string.c_str());
|
leds_flush();
|
||||||
|
|
||||||
lcd_print(1, 2, color_string.c_str());
|
std::uniform_int_distribution<> answer_color_dist(0, 4);
|
||||||
|
|
||||||
std::string entered_string;
|
std::map<int, std::string> color_name_map = {
|
||||||
|
{0, "Green"},
|
||||||
|
{1, "Red"},
|
||||||
|
{2, "Yellow"},
|
||||||
|
{3, "Blue"},
|
||||||
|
{4, "Pink"},
|
||||||
|
};
|
||||||
|
|
||||||
|
int answer_color = answer_color_dist(gen);
|
||||||
|
|
||||||
|
std::string color_string = color_name_map[answer_color];
|
||||||
|
std::string answer_num = std::to_string(indicator_numbers[answer_color]);
|
||||||
|
|
||||||
|
// ESP_LOGI(TAG, "color string: %s", color_string.c_str());
|
||||||
|
|
||||||
|
lcd_print(1, 2, color_string.c_str());
|
||||||
|
|
||||||
|
std::string entered_string;
|
||||||
|
|
||||||
|
KeypadKey key;
|
||||||
|
while (1) {
|
||||||
|
if (get_keypad_pressed(&key)) {
|
||||||
|
bool failed = false;
|
||||||
|
|
||||||
|
if (key == KeypadKey::star) {
|
||||||
|
// clear
|
||||||
|
entered_string = "";
|
||||||
|
} else if (key == KeypadKey::pound) {
|
||||||
|
// submit
|
||||||
|
if (entered_string != answer_num) {
|
||||||
|
strike("Incorrect answer!");
|
||||||
|
failed = true;
|
||||||
|
} else {
|
||||||
|
solved_correctly = true;;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
entered_string += char_of_keypad_key(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd_clear();
|
||||||
|
lcd_print(1, 1, "Plink");
|
||||||
|
lcd_print(1, 2, color_string.c_str());
|
||||||
|
lcd_print(1, 3, entered_string.c_str());
|
||||||
|
}
|
||||||
|
if (get_module_time() <= 0) {
|
||||||
|
strike("Ran out of time!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!failed) {
|
||||||
|
solved_correctly = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// do WHAT
|
||||||
|
lcd_print(1, 1, "What");
|
||||||
|
set_module_time(TIME_WHAT);
|
||||||
|
start_module_timer();
|
||||||
|
|
||||||
|
std::uniform_int_distribution<> math_number_dist(1, 9);
|
||||||
|
|
||||||
|
std::vector<float> math_numbers;
|
||||||
|
std::vector<int> math_operations;
|
||||||
|
|
||||||
|
std::map<int, char> operation_map = {
|
||||||
|
{0, '+'},
|
||||||
|
{1, '-'},
|
||||||
|
{2, '*'},
|
||||||
|
{3, '/'},
|
||||||
|
};
|
||||||
|
|
||||||
|
int expression_answer = -1;
|
||||||
|
std::string display_expression;
|
||||||
|
|
||||||
|
while (expression_answer < 0) {
|
||||||
|
math_numbers = {static_cast<float>(math_number_dist(gen)), static_cast<float>(math_number_dist(gen)), static_cast<float>(math_number_dist(gen)), static_cast<float>(math_number_dist(gen))};
|
||||||
|
std::vector<int> possible_math_operations = {0, 1, 2, 3};
|
||||||
|
math_operations = unique_values(possible_math_operations, 3);
|
||||||
|
|
||||||
|
display_expression = std::to_string(static_cast<int>(math_numbers[0]));
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
display_expression += operation_map[math_operations[i]];
|
||||||
|
display_expression += std::to_string(static_cast<int>(math_numbers[i + 1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solve
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
bool found = false;
|
||||||
|
for (int i = 0; i < math_operations.size(); i++) {
|
||||||
|
if (math_operations[i] == 2) {
|
||||||
|
// ESP_LOGI(TAG, "i = %i, condensing %f * %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] * math_numbers[i+1]));
|
||||||
|
math_numbers[i] = math_numbers[i] * math_numbers[i + 1];
|
||||||
|
math_numbers.erase(math_numbers.begin() + i + 1);
|
||||||
|
math_operations.erase(math_operations.begin() + i);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
} else if (math_operations[i] == 3) {
|
||||||
|
// ESP_LOGI(TAG, "i = %i, condensing %f / %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] / math_numbers[i+1]));
|
||||||
|
math_numbers[i] = math_numbers[i] / math_numbers[i + 1];
|
||||||
|
math_numbers.erase(math_numbers.begin() + i + 1);
|
||||||
|
math_operations.erase(math_operations.begin() + i);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) continue;
|
||||||
|
for (int i = 0; i < math_operations.size(); i++) {
|
||||||
|
if (math_operations[i] == 0) {
|
||||||
|
// ESP_LOGI(TAG, "i = %i, condensing %f + %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] + math_numbers[i+1]));
|
||||||
|
math_numbers[i] = math_numbers[i] + math_numbers[i + 1];
|
||||||
|
math_numbers.erase(math_numbers.begin() + i + 1);
|
||||||
|
math_operations.erase(math_operations.begin() + i);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
} else if (math_operations[i] == 1) {
|
||||||
|
// ESP_LOGI(TAG, "i = %i, condensing %f - %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] - math_numbers[i+1]));
|
||||||
|
math_numbers[i] = math_numbers[i] - math_numbers[i + 1];
|
||||||
|
math_numbers.erase(math_numbers.begin() + i + 1);
|
||||||
|
math_operations.erase(math_operations.begin() + i);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expression_answer = static_cast<int>(std::floor(math_numbers[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// display expression
|
||||||
|
lcd_print(2, 1, display_expression.c_str());
|
||||||
|
|
||||||
|
// set LEDs
|
||||||
|
const uint32_t COLORS[] = {
|
||||||
|
LEDColor::LED_COLOR_BLUE,
|
||||||
|
LEDColor::LED_COLOR_RED,
|
||||||
|
LEDColor::LED_COLOR_GREEN,
|
||||||
|
LEDColor::LED_COLOR_YELLOW,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::uniform_int_distribution<> add_sub_indicator_dist(1, 6);
|
||||||
|
std::uniform_int_distribution<> mult_div_indicator_dist(1, 3);
|
||||||
|
|
||||||
|
int modifier_indicators[4] = {add_sub_indicator_dist(gen), add_sub_indicator_dist(gen), mult_div_indicator_dist(gen), mult_div_indicator_dist(gen)};
|
||||||
|
|
||||||
|
|
||||||
|
while ((((expression_answer + (modifier_indicators[0] * 3) - modifier_indicators[1]) * std::pow(3, modifier_indicators[2])) / std::pow(2, modifier_indicators[3])) < 0) {
|
||||||
|
modifier_indicators[0] = add_sub_indicator_dist(gen);
|
||||||
|
modifier_indicators[1] = add_sub_indicator_dist(gen);
|
||||||
|
modifier_indicators[2] = mult_div_indicator_dist(gen);
|
||||||
|
modifier_indicators[3] = mult_div_indicator_dist(gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
expression_answer += modifier_indicators[0] * 3;
|
||||||
|
expression_answer -= modifier_indicators[1];
|
||||||
|
expression_answer *= std::pow(3, modifier_indicators[2]);
|
||||||
|
expression_answer /= std::pow(2, modifier_indicators[3]);
|
||||||
|
|
||||||
|
std::vector<int> led_options = all_leds;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
set_unique_leds(led_options, modifier_indicators[i], COLORS[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
leds_flush();
|
||||||
|
|
||||||
|
std::string answer_string = std::to_string(expression_answer);
|
||||||
|
std::string entered_string = "";
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Solved full answer: %s", answer_string.c_str());
|
||||||
|
|
||||||
KeypadKey key;
|
KeypadKey key;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (get_keypad_pressed(&key)) {
|
if (get_keypad_pressed(&key)) {
|
||||||
bool failed = false;
|
|
||||||
|
|
||||||
if (key == KeypadKey::star) {
|
if (key == KeypadKey::star) {
|
||||||
// clear
|
// clear
|
||||||
entered_string = "";
|
entered_string = "";
|
||||||
} else if (key == KeypadKey::pound) {
|
} else if (key == KeypadKey::pound) {
|
||||||
// submit
|
// submit
|
||||||
if (entered_string != answer_num) {
|
if (entered_string != answer_string) {
|
||||||
strike("Incorrect answer!");
|
strike("Incorrect answer!");
|
||||||
failed = true;
|
|
||||||
} else {
|
} else {
|
||||||
solved_correctly = true;;
|
solved_correctly = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
entered_string += char_of_keypad_key(key);
|
entered_string += char_of_keypad_key(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failed) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
lcd_clear();
|
lcd_clear();
|
||||||
lcd_print(1, 1, "Plink");
|
lcd_print(1, 1, "What");
|
||||||
lcd_print(1, 2, color_string.c_str());
|
lcd_print(2, 1, display_expression.c_str());
|
||||||
lcd_print(1, 3, entered_string.c_str());
|
lcd_print(3, 1, entered_string.c_str());
|
||||||
}
|
}
|
||||||
if (get_module_time() <= 0) {
|
if (get_module_time() <= 0) {
|
||||||
strike("Ran out of time!");
|
strike("Ran out of time!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
if (!failed) {
|
|
||||||
solved_correctly = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
ESP_LOGE(TAG, "Invalid puzzle number %d", puzzle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
stop_module_timer();
|
stop_module_timer();
|
||||||
if (solved_correctly) {
|
if (solved_correctly) {
|
||||||
solved_puzzles++;
|
solved_puzzles++;
|
||||||
play_raw(MOUNT_POINT "/correct.pcm");
|
play_clip_wav(MOUNT_POINT "/correct.wav", true, false, 3, 0);
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
vTaskDelay(pdMS_TO_TICKS(500));
|
||||||
solved_correctly = false;
|
solved_correctly = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef STEP_5_H
|
#ifndef P001_STEP_5_H
|
||||||
#define STEP_5_H
|
#define P001_STEP_5_H
|
||||||
|
|
||||||
#include "../drivers/bottom_half.h"
|
#include "../drivers/bottom_half.h"
|
||||||
#include "../drivers/game_timer.h"
|
#include "../drivers/game_timer.h"
|
||||||
@@ -15,6 +15,6 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
void step5(void);
|
void p001_step5(void);
|
||||||
|
|
||||||
#endif /* STEP_5_H */
|
#endif /* P001_STEP_5_H */
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#include "step6.h"
|
#include "p001_step6.h"
|
||||||
|
|
||||||
__attribute__((unused))
|
__attribute__((unused))
|
||||||
static const char *TAG = "step6";
|
static const char *TAG = "step6";
|
||||||
|
|
||||||
static uint8_t cut_wires = 0;
|
static uint8_t cut_wires = 0;
|
||||||
|
|
||||||
void step6(void) {
|
void p001_step6(void) {
|
||||||
get_cut_wires();
|
get_cut_wires();
|
||||||
clear_all_pressed_released();
|
clear_all_pressed_released();
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ void step6(void) {
|
|||||||
for (int i = 0; i < NUM_WIRES; i++) {
|
for (int i = 0; i < NUM_WIRES; i++) {
|
||||||
if (just_cut_wires & (1<<i)) {
|
if (just_cut_wires & (1<<i)) {
|
||||||
if (solution[i]) {
|
if (solution[i]) {
|
||||||
play_raw(MOUNT_POINT "/correct.pcm");
|
play_clip_wav(MOUNT_POINT "/correct.wav", true, false, 3, 0);
|
||||||
} else {
|
} else {
|
||||||
strike("Cut wrong wire");
|
strike("Cut wrong wire");
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef P001_STEP_6_H
|
||||||
|
#define P001_STEP_6_H
|
||||||
|
|
||||||
|
#include "wires_puzzle.h"
|
||||||
|
#include "../drivers/all.h"
|
||||||
|
#include "../helper.h"
|
||||||
|
|
||||||
|
void p001_step6(void);
|
||||||
|
|
||||||
|
#endif /* P001_STEP_6_H */
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include "p002_step1.h"
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static const char *TAG = "step1";
|
||||||
|
|
||||||
|
void p002_step1(void) {
|
||||||
|
// TODO: implement step 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef P002_STEP_1_H
|
||||||
|
#define P002_STEP_1_H
|
||||||
|
|
||||||
|
#include "../drivers/all.h"
|
||||||
|
|
||||||
|
void p002_step1(void);
|
||||||
|
|
||||||
|
#endif /* P002_STEP_1_H */
|
||||||
@@ -0,0 +1,272 @@
|
|||||||
|
#include "p002_step2.h"
|
||||||
|
#include "helper.h"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static const char *TAG = "step2";
|
||||||
|
|
||||||
|
static const uint8_t BOARD_COUNT = 9;
|
||||||
|
static const uint8_t BOARD_SIZE = 6;
|
||||||
|
static const uint8_t PART_SHOTS[3] = {20, 15, 12};
|
||||||
|
static const char *PART_LABELS[3] = {"Alpha", "Bravo", "Charlie"};
|
||||||
|
static const char ROW_LABELS[BOARD_SIZE] = {'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
|
||||||
|
static std::random_device random_device;
|
||||||
|
static std::mt19937 random_engine(random_device());
|
||||||
|
static std::uniform_int_distribution<int> random_board(0, BOARD_COUNT - 1);
|
||||||
|
|
||||||
|
static const uint8_t ALL_BOARDS[BOARD_COUNT][BOARD_SIZE][BOARD_SIZE] = {
|
||||||
|
{
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{0,0,1,1,1,1},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,1,0,1,1,0},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,0,0,1,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,1,0,1,1,0},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,0,0,1,0,0},
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{1,1,1,1,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,0,1,1,1,1},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,0,1,0,0,0},
|
||||||
|
{1,0,1,0,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{1,0,0,0,0,0},
|
||||||
|
{1,0,0,0,0,0},
|
||||||
|
{1,0,0,0,0,1},
|
||||||
|
{1,0,0,0,0,1},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
{0,1,1,1,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{1,1,0,1,0,0},
|
||||||
|
{0,0,0,1,0,0},
|
||||||
|
{0,1,0,1,0,0},
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{0,1,1,1,1,0},
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,0,1,0,1,0},
|
||||||
|
{1,0,1,0,1,0},
|
||||||
|
{0,0,1,0,1,0},
|
||||||
|
{0,0,1,0,0,0},
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{1,1,0,0,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,0,0,0,0,1},
|
||||||
|
{1,1,0,0,0,0},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
{1,1,1,0,1,0},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,1,1,0,0,0},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
{0,0,1,0,1,0},
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{1,1,1,1,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{1,0,0,0,0,0},
|
||||||
|
{0,1,0,0,1,1},
|
||||||
|
{0,1,0,1,0,0},
|
||||||
|
{0,1,0,1,0,0},
|
||||||
|
{0,1,0,1,0,0},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool row_from_button_state(uint8_t state, uint8_t *row) {
|
||||||
|
switch (state) {
|
||||||
|
case 0b1100: *row = 0; return true; // B1 + B2 -> A
|
||||||
|
case 0b1010: *row = 1; return true; // B1 + B3 -> B
|
||||||
|
case 0b1001: *row = 2; return true; // B1 + B4 -> C
|
||||||
|
case 0b0110: *row = 3; return true; // B2 + B3 -> D
|
||||||
|
case 0b0101: *row = 4; return true; // B2 + B4 -> E
|
||||||
|
case 0b0011: *row = 5; return true; // B3 + B4 -> F
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool column_from_switch_state(uint8_t state, uint8_t *col) {
|
||||||
|
uint8_t value = state & 0xF;
|
||||||
|
if (value >= 1 && value <= 6) {
|
||||||
|
*col = value - 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count_ship_segments(const uint8_t board[BOARD_SIZE][BOARD_SIZE]) {
|
||||||
|
int count = 0;
|
||||||
|
for (uint8_t row = 0; row < BOARD_SIZE; ++row) {
|
||||||
|
for (uint8_t col = 0; col < BOARD_SIZE; ++col) {
|
||||||
|
if (board[row][col] == 1) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_board(uint8_t dest[BOARD_SIZE][BOARD_SIZE], const uint8_t src[BOARD_SIZE][BOARD_SIZE]) {
|
||||||
|
memcpy(dest, src, BOARD_SIZE * BOARD_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void render_status(const char *part_name,
|
||||||
|
int shots_left,
|
||||||
|
int hits,
|
||||||
|
int misses,
|
||||||
|
int row,
|
||||||
|
int col,
|
||||||
|
const char *info) {
|
||||||
|
char line0[21] = {0};
|
||||||
|
char line1[21] = {0};
|
||||||
|
char line2[21] = {0};
|
||||||
|
char line3[21] = {0};
|
||||||
|
|
||||||
|
snprintf(line0, sizeof(line0), "%s Shots:%2d", part_name, shots_left);
|
||||||
|
if (row >= 0 && col >= 0) {
|
||||||
|
snprintf(line1, sizeof(line1), "Row %c Col %d", ROW_LABELS[row], col + 1);
|
||||||
|
} else {
|
||||||
|
snprintf(line1, sizeof(line1), "Row - Col -");
|
||||||
|
}
|
||||||
|
snprintf(line2, sizeof(line2), "Hits:%2d Misses:%2d", hits, misses);
|
||||||
|
snprintf(line3, sizeof(line3), "%s", info);
|
||||||
|
|
||||||
|
lcd_clear();
|
||||||
|
lcd_print(0, 0, line0);
|
||||||
|
lcd_print(0, 1, line1);
|
||||||
|
lcd_print(0, 2, line2);
|
||||||
|
lcd_print(0, 3, line3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void p002_step2(void) {
|
||||||
|
clean_bomb();
|
||||||
|
|
||||||
|
for (int part = 0; part < 3; ++part) {
|
||||||
|
const char *part_name = PART_LABELS[part];
|
||||||
|
const int max_shots = PART_SHOTS[part];
|
||||||
|
bool completed = false;
|
||||||
|
|
||||||
|
while (!completed) {
|
||||||
|
uint8_t board[BOARD_SIZE][BOARD_SIZE];
|
||||||
|
copy_board(board, ALL_BOARDS[random_board(random_engine)]);
|
||||||
|
|
||||||
|
int shots_taken = 0;
|
||||||
|
int hits = 0;
|
||||||
|
int misses = 0;
|
||||||
|
int current_row = -1;
|
||||||
|
int current_col = -1;
|
||||||
|
const char *status = "Hold 2 buttons + set switches";
|
||||||
|
|
||||||
|
render_status(part_name, max_shots - shots_taken, hits, misses, -1, -1, status);
|
||||||
|
clean_bomb();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
uint8_t button_state = get_button_state();
|
||||||
|
uint8_t switch_state = get_switch_state();
|
||||||
|
uint8_t row = 0;
|
||||||
|
uint8_t col = 0;
|
||||||
|
bool row_valid = row_from_button_state(button_state, &row);
|
||||||
|
bool col_valid = column_from_switch_state(switch_state, &col);
|
||||||
|
|
||||||
|
if (row_valid) {
|
||||||
|
current_row = row;
|
||||||
|
} else {
|
||||||
|
current_row = -1;
|
||||||
|
}
|
||||||
|
if (col_valid) {
|
||||||
|
current_col = col;
|
||||||
|
} else {
|
||||||
|
current_col = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeypadKey key;
|
||||||
|
if (get_keypad_pressed(&key)) {
|
||||||
|
if (key == KeypadKey::k5) {
|
||||||
|
if (!row_valid) {
|
||||||
|
status = "Invalid row selection";
|
||||||
|
} else if (!col_valid) {
|
||||||
|
status = "Invalid column value";
|
||||||
|
} else {
|
||||||
|
uint8_t cell = board[row][col];
|
||||||
|
if (cell == 2 || cell == 3) {
|
||||||
|
status = "Already fired there";
|
||||||
|
} else {
|
||||||
|
shots_taken += 1;
|
||||||
|
if (cell == 1) {
|
||||||
|
board[row][col] = 3;
|
||||||
|
hits += 1;
|
||||||
|
status = "Hit!";
|
||||||
|
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_RED);
|
||||||
|
} else {
|
||||||
|
board[row][col] = 2;
|
||||||
|
misses += 1;
|
||||||
|
status = "Miss!";
|
||||||
|
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_WHITE);
|
||||||
|
}
|
||||||
|
leds_flush();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(250));
|
||||||
|
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_OFF);
|
||||||
|
leds_flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render_status(part_name,
|
||||||
|
max_shots - shots_taken,
|
||||||
|
hits,
|
||||||
|
misses,
|
||||||
|
current_row,
|
||||||
|
current_col,
|
||||||
|
status);
|
||||||
|
|
||||||
|
if (count_ship_segments(board) == 0) {
|
||||||
|
completed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shots_taken >= max_shots) {
|
||||||
|
strike("Out of shots!");
|
||||||
|
status = "Out of shots! Retry";
|
||||||
|
render_status(part_name,
|
||||||
|
0,
|
||||||
|
hits,
|
||||||
|
misses,
|
||||||
|
current_row,
|
||||||
|
current_col,
|
||||||
|
status);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (part < 2)
|
||||||
|
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
|
||||||
|
clean_bomb();
|
||||||
|
}
|
||||||
|
|
||||||
|
play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0);
|
||||||
|
lcd_clear();
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef P002_STEP_2_H
|
||||||
|
#define P002_STEP_2_H
|
||||||
|
|
||||||
|
#include "../drivers/all.h"
|
||||||
|
|
||||||
|
void p002_step2(void);
|
||||||
|
|
||||||
|
#endif /* P002_STEP_2_H */
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include "p002_step3.h"
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static const char *TAG = "step3";
|
||||||
|
|
||||||
|
void p002_step3(void) {
|
||||||
|
// TODO: implement step 3
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef P002_STEP_3_H
|
||||||
|
#define P002_STEP_3_H
|
||||||
|
|
||||||
|
#include "../drivers/all.h"
|
||||||
|
|
||||||
|
void p002_step3(void);
|
||||||
|
|
||||||
|
#endif /* P002_STEP_3_H */
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include "p002_step4.h"
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static const char *TAG = "step4";
|
||||||
|
|
||||||
|
void p002_step4(void) {
|
||||||
|
// TODO: implement step 4
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef P002_STEP_4_H
|
||||||
|
#define P002_STEP_4_H
|
||||||
|
|
||||||
|
#include "../drivers/all.h"
|
||||||
|
|
||||||
|
void p002_step4(void);
|
||||||
|
|
||||||
|
#endif /* P002_STEP_4_H */
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include "p002_step5.h"
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static const char *TAG = "step5";
|
||||||
|
|
||||||
|
void p002_step5(void) {
|
||||||
|
// TODO: implement step 5
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef P002_STEP_5_H
|
||||||
|
#define P002_STEP_5_H
|
||||||
|
|
||||||
|
#include "../drivers/all.h"
|
||||||
|
|
||||||
|
void p002_step5(void);
|
||||||
|
|
||||||
|
#endif /* P002_STEP_5_H */
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include "p002_step6.h"
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static const char *TAG = "step6";
|
||||||
|
|
||||||
|
void p002_step6(void) {
|
||||||
|
// TODO: implement step 6
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef P002_STEP_6_H
|
||||||
|
#define P002_STEP_6_H
|
||||||
|
|
||||||
|
#include "../drivers/all.h"
|
||||||
|
|
||||||
|
void p002_step6(void);
|
||||||
|
|
||||||
|
#endif /* P002_STEP_6_H */
|
||||||
@@ -30,7 +30,7 @@ void setup_wires(void) {
|
|||||||
clear_all_pressed_released();
|
clear_all_pressed_released();
|
||||||
get_cut_wires();
|
get_cut_wires();
|
||||||
lcd_clear();
|
lcd_clear();
|
||||||
lcd_set_cursor_vis(false);
|
lcd_set_cursor_vis(true);
|
||||||
|
|
||||||
WireColor wires[NUM_WIRES];
|
WireColor wires[NUM_WIRES];
|
||||||
load_wires_from_sd_card(wires);
|
load_wires_from_sd_card(wires);
|
||||||
|
|||||||
+93
-26
@@ -1,26 +1,29 @@
|
|||||||
#include "step0.h"
|
#include "step0.h"
|
||||||
|
#include "drivers/state_tracking.h"
|
||||||
|
|
||||||
static const char* TAG = "step0";
|
static const char* TAG = "step0";
|
||||||
|
|
||||||
extern uint32_t initial_game_time;
|
extern uint32_t initial_game_time;
|
||||||
extern uint32_t skip_to_step;
|
extern uint32_t skip_to_step;
|
||||||
|
extern uint32_t puzzle;
|
||||||
|
|
||||||
static void set_game_time(void);
|
static void set_game_time();
|
||||||
static void skip_to_step1(void) { skip_to_step = 1; }
|
static void skip_to_step1() { skip_to_step = 1; }
|
||||||
static void skip_to_step2(void) { skip_to_step = 2; }
|
static void skip_to_step2() { skip_to_step = 2; }
|
||||||
static void skip_to_step3(void) { skip_to_step = 3; }
|
static void skip_to_step3() { skip_to_step = 3; }
|
||||||
static void skip_to_step4(void) { skip_to_step = 4; }
|
static void skip_to_step4() { skip_to_step = 4; }
|
||||||
static void skip_to_step5(void) { skip_to_step = 5; }
|
static void skip_to_step5() { skip_to_step = 5; }
|
||||||
static void skip_to_step6(void) { skip_to_step = 6; }
|
static void skip_to_step6() { skip_to_step = 6; }
|
||||||
static void try_step1(void) { clean_bomb(); step1(); }
|
static void try_step1() { clean_bomb(); p001_step1(); }
|
||||||
static void try_step2(void) { clean_bomb(); step2(); }
|
static void try_step2() { clean_bomb(); p001_step2(); }
|
||||||
static void try_step3(void) { clean_bomb(); step3(); }
|
static void try_step3() { clean_bomb(); p001_step3(); }
|
||||||
static void try_step4(void) { clean_bomb(); step4(); }
|
static void try_step4() { clean_bomb(); p001_step4(); }
|
||||||
static void try_step5(void) { clean_bomb(); step5(); }
|
static void try_step5() { clean_bomb(); p001_step5(); }
|
||||||
static void try_step6(void) { clean_bomb(); step6(); }
|
static void try_step6() { clean_bomb(); p001_step6(); }
|
||||||
static void issue_strike(void) { strike("Strike Issued"); }
|
static void issue_strike() { strike("Strike Issued"); }
|
||||||
static void debug_switches(void);
|
static void flashbang();
|
||||||
static void battery_stats(void) {
|
static void debug_switches();
|
||||||
|
static void battery_stats() {
|
||||||
BaseType_t xReturned;
|
BaseType_t xReturned;
|
||||||
TaskHandle_t xHandle = NULL;
|
TaskHandle_t xHandle = NULL;
|
||||||
xReturned = xTaskCreate(bat_monitor_task, "bat_monitor", 4096, NULL, 5, &xHandle);
|
xReturned = xTaskCreate(bat_monitor_task, "bat_monitor", 4096, NULL, 5, &xHandle);
|
||||||
@@ -33,20 +36,57 @@ static void battery_stats(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_p001() {
|
||||||
|
play_modified = false;
|
||||||
|
puzzle = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_p001_modified() {
|
||||||
|
play_modified = true;
|
||||||
|
puzzle = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_p002() {
|
||||||
|
puzzle = 2;
|
||||||
|
}
|
||||||
|
|
||||||
/// Wait for "*9819"
|
/// Wait for "*9819"
|
||||||
void step0(void) {
|
void step0() {
|
||||||
led_strip_set_pixel(leds, Led::speaker, 0, 0, 20);
|
led_set(IndicatorLED::LED_SPEAKER, LEDColor::LED_COLOR_BLUE);
|
||||||
led_strip_refresh(leds);
|
leds_flush();
|
||||||
|
|
||||||
StarCodeHandler star_codes[] = {
|
StarCodeHandler star_codes[] = {
|
||||||
{
|
{
|
||||||
.code = "*9819",
|
.code = "*9819",
|
||||||
.display_text = "Diffusal Initiated",
|
.display_text = "Start P001DH",
|
||||||
.should_exit = true,
|
.should_exit = true,
|
||||||
.callback = nullptr,
|
.callback = do_p001,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.code = "*9818",
|
||||||
|
.display_text = "Start P001DM",
|
||||||
|
.should_exit = true,
|
||||||
|
.callback = do_p001_modified,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.code = "*3141",
|
||||||
|
.display_text = "Start P002",
|
||||||
|
.should_exit = true,
|
||||||
|
.callback = do_p002,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.code = "*59861",
|
.code = "*59861",
|
||||||
.display_text = "Set Up Wires",
|
.display_text = "Setup Wires",
|
||||||
.should_exit = false,
|
.should_exit = false,
|
||||||
.callback = setup_wires,
|
.callback = setup_wires,
|
||||||
},
|
},
|
||||||
@@ -146,6 +186,18 @@ void step0(void) {
|
|||||||
.should_exit = false,
|
.should_exit = false,
|
||||||
.callback = issue_strike,
|
.callback = issue_strike,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.code = "*1112",
|
||||||
|
.display_text = "????",
|
||||||
|
.should_exit = false,
|
||||||
|
.callback = flashbang,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.code = "*1113",
|
||||||
|
.display_text = "replay_last",
|
||||||
|
.should_exit = false,
|
||||||
|
.callback = replay_last,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
int len = sizeof(star_codes)/sizeof(StarCodeHandler);
|
int len = sizeof(star_codes)/sizeof(StarCodeHandler);
|
||||||
do_star_codes(star_codes, len);
|
do_star_codes(star_codes, len);
|
||||||
@@ -163,7 +215,7 @@ static void _update_display(uint8_t* digits, uint8_t cursor_pos) {
|
|||||||
lcd_set_cursor_pos(mapped_cursor_pos, 1);
|
lcd_set_cursor_pos(mapped_cursor_pos, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_game_time(void) {
|
static void set_game_time() {
|
||||||
uint8_t hours = (initial_game_time / (1000*60*60)) % 10;
|
uint8_t hours = (initial_game_time / (1000*60*60)) % 10;
|
||||||
uint8_t minutes = (initial_game_time / (1000*60)) % 60;
|
uint8_t minutes = (initial_game_time / (1000*60)) % 60;
|
||||||
uint8_t seconds = (initial_game_time / (1000)) % 60;
|
uint8_t seconds = (initial_game_time / (1000)) % 60;
|
||||||
@@ -195,8 +247,8 @@ static void set_game_time(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clean_bomb();
|
clean_bomb();
|
||||||
led_strip_set_pixel(leds, Led::speaker, 0, 0, 20);
|
led_set(IndicatorLED::LED_SPEAKER, LEDColor::LED_COLOR_BLUE);
|
||||||
led_strip_refresh(leds);
|
leds_flush();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
int just_pressed = -1;
|
int just_pressed = -1;
|
||||||
@@ -266,7 +318,7 @@ static void print_4bin_rev(char* out_str, uint8_t n) {
|
|||||||
out_str[4] = '\0';
|
out_str[4] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void debug_switches(void) {
|
static void debug_switches() {
|
||||||
clean_bomb();
|
clean_bomb();
|
||||||
uint8_t switch_state = 0xFF;
|
uint8_t switch_state = 0xFF;
|
||||||
uint8_t switch_touch_state = 0xFF;
|
uint8_t switch_touch_state = 0xFF;
|
||||||
@@ -346,3 +398,18 @@ static void debug_switches(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -8,12 +8,12 @@
|
|||||||
#include "setup_wires.h"
|
#include "setup_wires.h"
|
||||||
#include "../helper.h"
|
#include "../helper.h"
|
||||||
|
|
||||||
#include "step1.h"
|
#include "p001_step1.h"
|
||||||
#include "step2.h"
|
#include "p001_step2.h"
|
||||||
#include "step3.h"
|
#include "p001_step3.h"
|
||||||
#include "step4.h"
|
#include "p001_step4.h"
|
||||||
#include "step5.h"
|
#include "p001_step5.h"
|
||||||
#include "step6.h"
|
#include "p001_step6.h"
|
||||||
|
|
||||||
/// Wait for "*9819"
|
/// Wait for "*9819"
|
||||||
void step0(void);
|
void step0(void);
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#ifndef STEP_1_H
|
|
||||||
#define STEP_1_H
|
|
||||||
|
|
||||||
#include <random>
|
|
||||||
#include "../drivers/bottom_half.h"
|
|
||||||
#include "../drivers/tft.h"
|
|
||||||
#include "../drivers/leds.h"
|
|
||||||
#include "../drivers/wires.h"
|
|
||||||
#include "../drivers/speaker.h"
|
|
||||||
#include "../drivers/game_timer.h"
|
|
||||||
#include "../drivers/char_lcd.h"
|
|
||||||
|
|
||||||
void step1(void);
|
|
||||||
|
|
||||||
#endif /* STEP_1_H */
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#ifndef STEP_3_H
|
|
||||||
#define STEP_3_H
|
|
||||||
|
|
||||||
#include <random>
|
|
||||||
#include "../drivers/bottom_half.h"
|
|
||||||
#include "../drivers/wires.h"
|
|
||||||
#include "../drivers/speaker.h"
|
|
||||||
#include "../drivers/leds.h"
|
|
||||||
#include "../drivers/char_lcd.h"
|
|
||||||
#include "../drivers/game_timer.h"
|
|
||||||
#include "../helper.h"
|
|
||||||
|
|
||||||
void step3(void);
|
|
||||||
|
|
||||||
#endif /* STEP_3_H */
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#ifndef STEP_6_H
|
|
||||||
#define STEP_6_H
|
|
||||||
|
|
||||||
#include "wires_puzzle.h"
|
|
||||||
#include "drivers/wires.h"
|
|
||||||
#include "drivers/bottom_half.h"
|
|
||||||
#include "drivers/sd.h"
|
|
||||||
#include "drivers/speaker.h"
|
|
||||||
|
|
||||||
void step6(void);
|
|
||||||
|
|
||||||
#endif /* STEP_6_H */
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
set(SOURCES
|
||||||
|
"bg.c"
|
||||||
|
"clear.c"
|
||||||
|
"db.c"
|
||||||
|
"green.c"
|
||||||
|
"lb.c"
|
||||||
|
"orange.c"
|
||||||
|
"purple.c"
|
||||||
|
"red.c"
|
||||||
|
"yellow.c"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_sources(${COMPONENT_LIB} PRIVATE ${SOURCES})
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,69 @@
|
|||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include("lvgl.h")
|
||||||
|
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_IMG_CLEAR
|
||||||
|
#define LV_ATTRIBUTE_IMG_CLEAR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_CLEAR uint8_t clear_map[] = {
|
||||||
|
0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0xdb, 0xde, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0x5d, 0xef, 0x7d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7e, 0xf7, 0x7e, 0xf7, 0x5d, 0xef, 0xba, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0x5d, 0xef, 0x7d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7e, 0xf7, 0x7e, 0xf7, 0x5d, 0xef, 0xba, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0x5d, 0xef, 0x7d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7e, 0xf7, 0x7e, 0xf7, 0x5d, 0xef, 0xba, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0x5d, 0xef, 0x7d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7e, 0xf7, 0x7e, 0xf7, 0x5d, 0xef, 0xba, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0x5d, 0xef, 0x7d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7e, 0xf7, 0x7e, 0xf7, 0x5d, 0xef, 0xba, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0x5d, 0xef, 0x7d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7e, 0xf7, 0x7e, 0xf7, 0x5d, 0xef, 0xba, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0x5d, 0xef, 0x7d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7e, 0xf7, 0x7e, 0xf7, 0x5d, 0xef, 0xba, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0x5d, 0xef, 0x7d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7e, 0xf7, 0x7e, 0xf7, 0x5d, 0xef, 0xba, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0x5d, 0xef, 0x7d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7e, 0xf7, 0x7e, 0xf7, 0x5d, 0xef, 0xba, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xbb, 0xde, 0x5d, 0xef, 0x7d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7e, 0xf7, 0x7e, 0xf7, 0x5d, 0xef, 0xba, 0xd6, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0xb7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0xb7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0xb7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0xb7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0xb7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0xb7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0xb7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0xb7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0xb7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0xb7, 0xbd, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0xf8, 0xc5, 0x38, 0xc6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x18, 0xc6, 0xd7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0xf8, 0xc5, 0x38, 0xc6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x18, 0xc6, 0xd7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0xf8, 0xc5, 0x38, 0xc6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x18, 0xc6, 0xd7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0xf8, 0xc5, 0x38, 0xc6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x18, 0xc6, 0xd7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0xf8, 0xc5, 0x38, 0xc6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x18, 0xc6, 0xd7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0xf8, 0xc5, 0x38, 0xc6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x18, 0xc6, 0xd7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0xf8, 0xc5, 0x38, 0xc6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x18, 0xc6, 0xd7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0xf8, 0xc5, 0x38, 0xc6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x18, 0xc6, 0xd7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0xf8, 0xc5, 0x38, 0xc6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x18, 0xc6, 0xd7, 0xbd, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xb7, 0xbd, 0xf8, 0xc5, 0x38, 0xc6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x18, 0xc6, 0xd7, 0xbd, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0xf7, 0xbd, 0x38, 0xc6, 0x79, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0x9a, 0xd6, 0x9a, 0xd6, 0x7a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf7, 0xbd, 0x38, 0xc6, 0x79, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0x9a, 0xd6, 0x9a, 0xd6, 0x7a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf7, 0xbd, 0x38, 0xc6, 0x79, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0x9a, 0xd6, 0x9a, 0xd6, 0x7a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf7, 0xbd, 0x38, 0xc6, 0x79, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0x9a, 0xd6, 0x9a, 0xd6, 0x7a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf7, 0xbd, 0x38, 0xc6, 0x79, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0x9a, 0xd6, 0x9a, 0xd6, 0x7a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf7, 0xbd, 0x38, 0xc6, 0x79, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0x9a, 0xd6, 0x9a, 0xd6, 0x7a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf7, 0xbd, 0x38, 0xc6, 0x79, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0x9a, 0xd6, 0x9a, 0xd6, 0x7a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf7, 0xbd, 0x38, 0xc6, 0x79, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0x9a, 0xd6, 0x9a, 0xd6, 0x7a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf7, 0xbd, 0x38, 0xc6, 0x79, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0x9a, 0xd6, 0x9a, 0xd6, 0x7a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf7, 0xbd, 0x38, 0xc6, 0x79, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0x9a, 0xd6, 0x9a, 0xd6, 0x7a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0xf8, 0xc5, 0x59, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x9a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf8, 0xc5, 0x59, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x9a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf8, 0xc5, 0x59, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x9a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf8, 0xc5, 0x59, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x9a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf8, 0xc5, 0x59, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x9a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf8, 0xc5, 0x59, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x9a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf8, 0xc5, 0x59, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x9a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf8, 0xc5, 0x59, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x9a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf8, 0xc5, 0x59, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x9a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0xf8, 0xc5, 0x59, 0xce, 0x7a, 0xd6, 0x9a, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0x9a, 0xd6, 0x59, 0xce, 0x18, 0xc6, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0x18, 0xc6, 0x79, 0xce, 0x9a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xdb, 0xde, 0xbb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x18, 0xc6, 0x79, 0xce, 0x9a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xdb, 0xde, 0xbb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x18, 0xc6, 0x79, 0xce, 0x9a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xdb, 0xde, 0xbb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x18, 0xc6, 0x79, 0xce, 0x9a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xdb, 0xde, 0xbb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x18, 0xc6, 0x79, 0xce, 0x9a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xdb, 0xde, 0xbb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x18, 0xc6, 0x79, 0xce, 0x9a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xdb, 0xde, 0xbb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x18, 0xc6, 0x79, 0xce, 0x9a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xdb, 0xde, 0xbb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x18, 0xc6, 0x79, 0xce, 0x9a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xdb, 0xde, 0xbb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x18, 0xc6, 0x79, 0xce, 0x9a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xdb, 0xde, 0xbb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x18, 0xc6, 0x79, 0xce, 0x9a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xfb, 0xde, 0xdb, 0xde, 0xbb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x7a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0xfc, 0xe6, 0xdb, 0xde, 0xdb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x7a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0xfc, 0xe6, 0xdb, 0xde, 0xdb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x7a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0xfc, 0xe6, 0xdb, 0xde, 0xdb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x7a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0xfc, 0xe6, 0xdb, 0xde, 0xdb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x7a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0xfc, 0xe6, 0xdb, 0xde, 0xdb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x7a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0xfc, 0xe6, 0xdb, 0xde, 0xdb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x7a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0xfc, 0xe6, 0xdb, 0xde, 0xdb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x7a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0xfc, 0xe6, 0xdb, 0xde, 0xdb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x7a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0xfc, 0xe6, 0xdb, 0xde, 0xdb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x7a, 0xd6, 0xbb, 0xde, 0xdb, 0xde, 0xfb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0xfc, 0xe6, 0xdb, 0xde, 0xdb, 0xde, 0x9a, 0xd6, 0x59, 0xce, 0x75, 0xad, 0xba, 0xd6,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x9a, 0xd6, 0xdb, 0xde, 0xfb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x3c, 0xe7, 0x1c, 0xe7, 0xfc, 0xe6, 0xfb, 0xde, 0xba, 0xd6, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x9a, 0xd6, 0xdb, 0xde, 0xfb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x3c, 0xe7, 0x1c, 0xe7, 0xfc, 0xe6, 0xfb, 0xde, 0xba, 0xd6, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x9a, 0xd6, 0xdb, 0xde, 0xfb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x3c, 0xe7, 0x1c, 0xe7, 0xfc, 0xe6, 0xfb, 0xde, 0xba, 0xd6, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x9a, 0xd6, 0xdb, 0xde, 0xfb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x3c, 0xe7, 0x1c, 0xe7, 0xfc, 0xe6, 0xfb, 0xde, 0xba, 0xd6, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x9a, 0xd6, 0xdb, 0xde, 0xfb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x3c, 0xe7, 0x1c, 0xe7, 0xfc, 0xe6, 0xfb, 0xde, 0xba, 0xd6, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x9a, 0xd6, 0xdb, 0xde, 0xfb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x3c, 0xe7, 0x1c, 0xe7, 0xfc, 0xe6, 0xfb, 0xde, 0xba, 0xd6, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x9a, 0xd6, 0xdb, 0xde, 0xfb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x3c, 0xe7, 0x1c, 0xe7, 0xfc, 0xe6, 0xfb, 0xde, 0xba, 0xd6, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x9a, 0xd6, 0xdb, 0xde, 0xfb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x3c, 0xe7, 0x1c, 0xe7, 0xfc, 0xe6, 0xfb, 0xde, 0xba, 0xd6, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x9a, 0xd6, 0xdb, 0xde, 0xfb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x3c, 0xe7, 0x1c, 0xe7, 0xfc, 0xe6, 0xfb, 0xde, 0xba, 0xd6, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x39, 0xce, 0x9a, 0xd6, 0xdb, 0xde, 0xfb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x3c, 0xe7, 0x1c, 0xe7, 0xfc, 0xe6, 0xfb, 0xde, 0xba, 0xd6, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0x59, 0xce, 0x9a, 0xd6, 0xfb, 0xde, 0xfc, 0xe6, 0x3c, 0xe7, 0x3d, 0xef, 0x3d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xfc, 0xe6, 0xbb, 0xde, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x59, 0xce, 0x9a, 0xd6, 0xfb, 0xde, 0xfc, 0xe6, 0x3c, 0xe7, 0x3d, 0xef, 0x3d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xfc, 0xe6, 0xbb, 0xde, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x59, 0xce, 0x9a, 0xd6, 0xfb, 0xde, 0xfc, 0xe6, 0x3c, 0xe7, 0x3d, 0xef, 0x3d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xfc, 0xe6, 0xbb, 0xde, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x59, 0xce, 0x9a, 0xd6, 0xfb, 0xde, 0xfc, 0xe6, 0x3c, 0xe7, 0x3d, 0xef, 0x3d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xfc, 0xe6, 0xbb, 0xde, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x59, 0xce, 0x9a, 0xd6, 0xfb, 0xde, 0xfc, 0xe6, 0x3c, 0xe7, 0x3d, 0xef, 0x3d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xfc, 0xe6, 0xbb, 0xde, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x59, 0xce, 0x9a, 0xd6, 0xfb, 0xde, 0xfc, 0xe6, 0x3c, 0xe7, 0x3d, 0xef, 0x3d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xfc, 0xe6, 0xbb, 0xde, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x59, 0xce, 0x9a, 0xd6, 0xfb, 0xde, 0xfc, 0xe6, 0x3c, 0xe7, 0x3d, 0xef, 0x3d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xfc, 0xe6, 0xbb, 0xde, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x59, 0xce, 0x9a, 0xd6, 0xfb, 0xde, 0xfc, 0xe6, 0x3c, 0xe7, 0x3d, 0xef, 0x3d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xfc, 0xe6, 0xbb, 0xde, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x59, 0xce, 0x9a, 0xd6, 0xfb, 0xde, 0xfc, 0xe6, 0x3c, 0xe7, 0x3d, 0xef, 0x3d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xfc, 0xe6, 0xbb, 0xde, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6, 0xbb, 0xde, 0x75, 0xad, 0x59, 0xce, 0x9a, 0xd6, 0xfb, 0xde, 0xfc, 0xe6, 0x3c, 0xe7, 0x3d, 0xef, 0x3d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xfc, 0xe6, 0xbb, 0xde, 0x7a, 0xd6, 0x75, 0xad, 0xba, 0xd6,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0x5d, 0xef, 0x5d, 0xef, 0x7d, 0xef, 0x5d, 0xef, 0x3c, 0xe7, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0x5d, 0xef, 0x5d, 0xef, 0x7d, 0xef, 0x5d, 0xef, 0x3c, 0xe7, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0x5d, 0xef, 0x5d, 0xef, 0x7d, 0xef, 0x5d, 0xef, 0x3c, 0xe7, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0x5d, 0xef, 0x5d, 0xef, 0x7d, 0xef, 0x5d, 0xef, 0x3c, 0xe7, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0x5d, 0xef, 0x5d, 0xef, 0x7d, 0xef, 0x5d, 0xef, 0x3c, 0xe7, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0x5d, 0xef, 0x5d, 0xef, 0x7d, 0xef, 0x5d, 0xef, 0x3c, 0xe7, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0x5d, 0xef, 0x5d, 0xef, 0x7d, 0xef, 0x5d, 0xef, 0x3c, 0xe7, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0x5d, 0xef, 0x5d, 0xef, 0x7d, 0xef, 0x5d, 0xef, 0x3c, 0xe7, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0x5d, 0xef, 0x5d, 0xef, 0x7d, 0xef, 0x5d, 0xef, 0x3c, 0xe7, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0xfc, 0xe6, 0x1c, 0xe7, 0x5d, 0xef, 0x5d, 0xef, 0x7d, 0xef, 0x5d, 0xef, 0x3c, 0xe7, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x5d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x7d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x5d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x7d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x5d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x7d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x5d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x7d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x5d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x7d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x5d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x7d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x5d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x7d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x5d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x7d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x5d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x7d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde, 0xbb, 0xde, 0x75, 0xad, 0x79, 0xce, 0xbb, 0xde, 0x1c, 0xe7, 0x1c, 0xe7, 0x5d, 0xef, 0x7e, 0xf7, 0x9e, 0xf7, 0x7d, 0xef, 0x3d, 0xef, 0x1c, 0xe7, 0xdb, 0xde, 0x9a, 0xd6, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0xba, 0xd6, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xba, 0xd6, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xba, 0xd6, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xba, 0xd6, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xba, 0xd6, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xba, 0xd6, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xba, 0xd6, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xba, 0xd6, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xba, 0xd6, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde, 0xba, 0xd6, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0xbb, 0xde,
|
||||||
|
0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xbb, 0xde, 0xba, 0xd6, 0xbb, 0xde, 0xba, 0xd6, 0x00, 0x00,
|
||||||
|
/*alpha channel*/
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const lv_img_dsc_t clear = {
|
||||||
|
.header.cf = LV_IMG_CF_RGB565A8,
|
||||||
|
.header.always_zero = 0,
|
||||||
|
.header.reserved = 0,
|
||||||
|
.header.w = 160,
|
||||||
|
.header.h = 16,
|
||||||
|
.data_size = 7680,
|
||||||
|
.data = clear_map,
|
||||||
|
};
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include("lvgl.h")
|
||||||
|
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_IMG_DB
|
||||||
|
#define LV_ATTRIBUTE_IMG_DB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_DB uint8_t db_map[] = {
|
||||||
|
0x00, 0x00, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x00, 0x00,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x33, 0x54, 0x33, 0x54, 0x33, 0x54, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0x13, 0x33, 0xb5, 0x4b, 0xd5, 0x4b, 0xf6, 0x4b, 0xf7, 0x4b, 0x17, 0x4c, 0x17, 0x4c, 0x17, 0x4c, 0xf6, 0x4b, 0xf6, 0x4b, 0xb5, 0x4b, 0x13, 0x33, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0xf1, 0x01, 0xd5, 0x4b, 0xdd, 0xce, 0xbb, 0x9d, 0xb9, 0x64, 0xb9, 0x64, 0xb9, 0x64, 0xb9, 0x64, 0xb9, 0x64, 0x98, 0x64, 0xf6, 0x4b, 0xf1, 0x01, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0xf1, 0x01, 0x53, 0x02, 0x95, 0x02, 0x58, 0x54, 0x7b, 0x85, 0x1a, 0x6d, 0x1a, 0x6d, 0x1a, 0x6d, 0x79, 0x54, 0xb5, 0x02, 0x74, 0x02, 0x32, 0x02, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0x32, 0x02, 0x95, 0x02, 0xd6, 0x02, 0xf7, 0x02, 0x38, 0x03, 0x38, 0x03, 0x59, 0x03, 0x38, 0x03, 0x18, 0x03, 0xf7, 0x02, 0xb5, 0x02, 0x53, 0x02, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0x53, 0x02, 0xb5, 0x02, 0xf7, 0x02, 0x18, 0x03, 0x59, 0x03, 0x59, 0x03, 0x59, 0x03, 0x59, 0x03, 0x38, 0x03, 0x18, 0x03, 0xd6, 0x02, 0x74, 0x02, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0x74, 0x02, 0xd6, 0x02, 0x38, 0x03, 0x59, 0x03, 0x7a, 0x03, 0x9a, 0x03, 0xbb, 0x03, 0x9a, 0x03, 0x7a, 0x03, 0x59, 0x03, 0x17, 0x03, 0xb5, 0x02, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0x95, 0x02, 0xf7, 0x02, 0x59, 0x03, 0x5a, 0x03, 0xbb, 0x03, 0xbb, 0x03, 0xbb, 0x03, 0xbb, 0x03, 0x9a, 0x03, 0x59, 0x03, 0x38, 0x03, 0xb6, 0x02, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0xb5, 0x02, 0x18, 0x03, 0x7a, 0x03, 0xbb, 0x03, 0xfc, 0x03, 0xfc, 0x03, 0x1d, 0x04, 0xfc, 0x03, 0xbb, 0x03, 0x9b, 0x03, 0x59, 0x03, 0xd7, 0x02, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0xb6, 0x02, 0x38, 0x03, 0x9a, 0x03, 0xbb, 0x03, 0xfc, 0x03, 0x1d, 0x04, 0x1d, 0x04, 0x1d, 0x04, 0xfc, 0x03, 0xbb, 0x03, 0x59, 0x03, 0xf7, 0x02, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0xd6, 0x02, 0x59, 0x03, 0xbb, 0x03, 0xfc, 0x03, 0x3d, 0x04, 0x5e, 0x04, 0x7e, 0x04, 0x5e, 0x04, 0x1d, 0x04, 0xfc, 0x03, 0x7a, 0x03, 0x18, 0x03, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0xd7, 0x02, 0x59, 0x03, 0xbb, 0x03, 0xfc, 0x03, 0x5e, 0x04, 0x9f, 0x04, 0xbf, 0x04, 0x7f, 0x04, 0x1d, 0x04, 0xfc, 0x03, 0x9a, 0x03, 0x18, 0x03, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x13, 0x33, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0x13, 0x33,
|
||||||
|
0x00, 0x00, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x13, 0x33, 0x00, 0x00,
|
||||||
|
/*alpha channel*/
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const lv_img_dsc_t db = {
|
||||||
|
.header.cf = LV_IMG_CF_RGB565A8,
|
||||||
|
.header.always_zero = 0,
|
||||||
|
.header.reserved = 0,
|
||||||
|
.header.w = 16,
|
||||||
|
.header.h = 16,
|
||||||
|
.data_size = 768,
|
||||||
|
.data = db_map,
|
||||||
|
};
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include("lvgl.h")
|
||||||
|
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_IMG_GREEN
|
||||||
|
#define LV_ATTRIBUTE_IMG_GREEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_GREEN uint8_t green_map[] = {
|
||||||
|
0x00, 0x00, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0x00, 0x00,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0xe9, 0x34, 0xe9, 0x34, 0xe9, 0x34, 0xe9, 0x34, 0x09, 0x35, 0x09, 0x35, 0x09, 0x35, 0x09, 0x35, 0xe9, 0x34, 0xe9, 0x34, 0xe9, 0x34, 0xe9, 0x34, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0xe9, 0x34, 0x2c, 0x4d, 0x6c, 0x4d, 0x8c, 0x4d, 0xac, 0x4d, 0xcc, 0x4d, 0xcc, 0x4d, 0xcc, 0x4d, 0x8c, 0x4d, 0x8c, 0x4d, 0x2c, 0x4d, 0xc9, 0x34, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0x44, 0x04, 0x6c, 0x4d, 0x7a, 0xcf, 0xb5, 0x9e, 0x4f, 0x66, 0x4f, 0x66, 0x4f, 0x66, 0x4f, 0x66, 0x2f, 0x66, 0x0f, 0x66, 0x8c, 0x4d, 0x44, 0x04, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0x44, 0x04, 0xc4, 0x04, 0x25, 0x05, 0x0e, 0x56, 0xd3, 0x86, 0x91, 0x6e, 0x91, 0x6e, 0x91, 0x6e, 0x2e, 0x56, 0x65, 0x05, 0x05, 0x05, 0x84, 0x04, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0xa4, 0x04, 0x25, 0x05, 0xa5, 0x05, 0xc6, 0x05, 0x06, 0x06, 0x26, 0x06, 0x26, 0x06, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x05, 0x65, 0x05, 0xe5, 0x04, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0xc4, 0x04, 0x65, 0x05, 0xc6, 0x05, 0xe6, 0x05, 0x46, 0x06, 0x47, 0x06, 0x47, 0x06, 0x47, 0x06, 0x26, 0x06, 0x06, 0x06, 0x85, 0x05, 0x05, 0x05, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0x05, 0x05, 0xa5, 0x05, 0x06, 0x06, 0x47, 0x06, 0x87, 0x06, 0xa7, 0x06, 0xa7, 0x06, 0xa7, 0x06, 0x67, 0x06, 0x46, 0x06, 0xe6, 0x05, 0x65, 0x05, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0x45, 0x05, 0xc6, 0x05, 0x46, 0x06, 0x67, 0x06, 0xa7, 0x06, 0xc8, 0x06, 0xe8, 0x06, 0xc8, 0x06, 0x87, 0x06, 0x67, 0x06, 0x06, 0x06, 0x85, 0x05, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0x65, 0x05, 0x06, 0x06, 0x87, 0x06, 0xa7, 0x06, 0x08, 0x07, 0x08, 0x07, 0x28, 0x07, 0x28, 0x07, 0xe8, 0x06, 0xa7, 0x06, 0x46, 0x06, 0xc6, 0x05, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0x65, 0x05, 0x06, 0x06, 0xa7, 0x06, 0xc7, 0x06, 0x28, 0x07, 0x48, 0x07, 0x48, 0x07, 0x48, 0x07, 0x08, 0x07, 0xc7, 0x06, 0x47, 0x06, 0xc6, 0x05, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0xa5, 0x05, 0x46, 0x06, 0xc7, 0x06, 0x08, 0x07, 0x69, 0x07, 0x89, 0x07, 0xa9, 0x07, 0x89, 0x07, 0x28, 0x07, 0x08, 0x07, 0x87, 0x06, 0xe6, 0x05, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0xa5, 0x05, 0x47, 0x06, 0xe8, 0x06, 0x08, 0x07, 0x89, 0x07, 0xc9, 0x07, 0xea, 0x07, 0xa9, 0x07, 0x48, 0x07, 0x08, 0x07, 0x87, 0x06, 0x06, 0x06, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0xa9, 0x34, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa3, 0x03, 0xa9, 0x34,
|
||||||
|
0x00, 0x00, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0xa9, 0x34, 0x00, 0x00,
|
||||||
|
/*alpha channel*/
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const lv_img_dsc_t green = {
|
||||||
|
.header.cf = LV_IMG_CF_RGB565A8,
|
||||||
|
.header.always_zero = 0,
|
||||||
|
.header.reserved = 0,
|
||||||
|
.header.w = 16,
|
||||||
|
.header.h = 16,
|
||||||
|
.data_size = 768,
|
||||||
|
.data = green_map,
|
||||||
|
};
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include("lvgl.h")
|
||||||
|
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_IMG_LB
|
||||||
|
#define LV_ATTRIBUTE_IMG_LB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_LB uint8_t lb_map[] = {
|
||||||
|
0x00, 0x00, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x00, 0x00,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0x73, 0x34, 0x73, 0x34, 0x73, 0x34, 0x73, 0x34, 0x94, 0x34, 0x94, 0x34, 0x94, 0x34, 0x94, 0x34, 0x73, 0x34, 0x73, 0x34, 0x73, 0x34, 0x73, 0x34, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0x73, 0x34, 0xd5, 0x4c, 0x15, 0x4d, 0x36, 0x4d, 0x37, 0x4d, 0x57, 0x4d, 0x57, 0x4d, 0x57, 0x4d, 0x36, 0x4d, 0x16, 0x4d, 0xf5, 0x4c, 0x53, 0x34, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0xb1, 0x03, 0x15, 0x4d, 0x3d, 0xcf, 0x7b, 0x9e, 0xd9, 0x65, 0xd9, 0x65, 0xf9, 0x65, 0xf9, 0x65, 0xd9, 0x65, 0xd8, 0x65, 0x36, 0x4d, 0xb1, 0x03, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0xb1, 0x03, 0x33, 0x04, 0x95, 0x04, 0xb8, 0x55, 0x7b, 0x86, 0x3a, 0x6e, 0x3a, 0x6e, 0x3a, 0x6e, 0xd9, 0x55, 0xd5, 0x04, 0x54, 0x04, 0xf2, 0x03, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0x12, 0x04, 0x95, 0x04, 0x16, 0x05, 0x37, 0x05, 0x78, 0x05, 0x78, 0x05, 0x99, 0x05, 0x78, 0x05, 0x58, 0x05, 0x37, 0x05, 0xd5, 0x04, 0x53, 0x04, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0x33, 0x04, 0xb5, 0x04, 0x37, 0x05, 0x58, 0x05, 0x99, 0x05, 0xb9, 0x05, 0xb9, 0x05, 0xb9, 0x05, 0x78, 0x05, 0x58, 0x05, 0xf6, 0x04, 0x74, 0x04, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0x74, 0x04, 0x16, 0x05, 0x78, 0x05, 0xb9, 0x05, 0xda, 0x05, 0xfa, 0x05, 0x1b, 0x06, 0xfa, 0x05, 0xda, 0x05, 0x99, 0x05, 0x37, 0x05, 0xb5, 0x04, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0xb5, 0x04, 0x37, 0x05, 0x99, 0x05, 0xda, 0x05, 0x1b, 0x06, 0x3b, 0x06, 0x3b, 0x06, 0x3b, 0x06, 0xfa, 0x05, 0xd9, 0x05, 0x78, 0x05, 0xd6, 0x04, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0xb5, 0x04, 0x58, 0x05, 0xda, 0x05, 0x1b, 0x06, 0x5c, 0x06, 0x7c, 0x06, 0x7d, 0x06, 0x7c, 0x06, 0x3b, 0x06, 0xfb, 0x05, 0x99, 0x05, 0x17, 0x05, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0xd6, 0x04, 0x78, 0x05, 0xfa, 0x05, 0x1b, 0x06, 0x7c, 0x06, 0x9d, 0x06, 0x9d, 0x06, 0x9d, 0x06, 0x5c, 0x06, 0x1b, 0x06, 0xb9, 0x05, 0x37, 0x05, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0x16, 0x05, 0x99, 0x05, 0x1b, 0x06, 0x5c, 0x06, 0xbd, 0x06, 0xde, 0x06, 0xfe, 0x06, 0xde, 0x06, 0x9d, 0x06, 0x5c, 0x06, 0xda, 0x05, 0x58, 0x05, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0x17, 0x05, 0xb9, 0x05, 0x3b, 0x06, 0x7c, 0x06, 0xde, 0x06, 0x1f, 0x07, 0x3f, 0x07, 0x1f, 0x07, 0x9d, 0x06, 0x7c, 0x06, 0xfa, 0x05, 0x58, 0x05, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x53, 0x34, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x2f, 0x03, 0x53, 0x34,
|
||||||
|
0x00, 0x00, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x53, 0x34, 0x00, 0x00,
|
||||||
|
/*alpha channel*/
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const lv_img_dsc_t lb = {
|
||||||
|
.header.cf = LV_IMG_CF_RGB565A8,
|
||||||
|
.header.always_zero = 0,
|
||||||
|
.header.reserved = 0,
|
||||||
|
.header.w = 16,
|
||||||
|
.header.h = 16,
|
||||||
|
.data_size = 768,
|
||||||
|
.data = lb_map,
|
||||||
|
};
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include("lvgl.h")
|
||||||
|
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_IMG_ORANGE
|
||||||
|
#define LV_ATTRIBUTE_IMG_ORANGE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_ORANGE uint8_t orange_map[] = {
|
||||||
|
0x00, 0x00, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x00, 0x00,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x86, 0x9b, 0x86, 0x9b, 0x86, 0x9b, 0x86, 0x9b, 0xa6, 0xa3, 0xa6, 0xa3, 0xa6, 0xa3, 0xa6, 0xa3, 0x86, 0x9b, 0x86, 0x9b, 0x86, 0x9b, 0x86, 0x9b, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x86, 0x9b, 0x09, 0xac, 0x49, 0xac, 0x49, 0xb4, 0x69, 0xbc, 0x69, 0xbc, 0x89, 0xbc, 0x69, 0xbc, 0x49, 0xb4, 0x49, 0xb4, 0x09, 0xac, 0x86, 0x9b, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x80, 0x8a, 0x29, 0xac, 0xf9, 0xee, 0xf3, 0xdd, 0x0c, 0xcd, 0x0c, 0xcd, 0x2c, 0xcd, 0x0c, 0xcd, 0x0c, 0xcd, 0xec, 0xc4, 0x49, 0xb4, 0x80, 0x8a, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x80, 0x8a, 0xe0, 0x9a, 0x40, 0xab, 0xca, 0xc4, 0xd0, 0xdd, 0x6d, 0xd5, 0x6d, 0xd5, 0x6d, 0xd5, 0xea, 0xcc, 0x60, 0xab, 0x00, 0xa3, 0xc0, 0x92, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0xc0, 0x92, 0x40, 0xab, 0x80, 0xb3, 0xa0, 0xbb, 0xe0, 0xc3, 0xe0, 0xc3, 0x00, 0xcc, 0xe0, 0xc3, 0xe0, 0xc3, 0xa0, 0xbb, 0x60, 0xab, 0xe0, 0x9a, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0xe0, 0x9a, 0x40, 0xab, 0xa0, 0xbb, 0xe0, 0xc3, 0x00, 0xcc, 0x20, 0xcc, 0x20, 0xcc, 0x20, 0xcc, 0xe0, 0xc3, 0xe0, 0xc3, 0x80, 0xb3, 0x20, 0xa3, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x20, 0xa3, 0x80, 0xb3, 0xe0, 0xc3, 0x20, 0xcc, 0x40, 0xd4, 0x60, 0xd4, 0x80, 0xdc, 0x60, 0xd4, 0x40, 0xd4, 0x20, 0xcc, 0xc0, 0xbb, 0x40, 0xab, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x40, 0xab, 0xa0, 0xbb, 0x00, 0xcc, 0x40, 0xd4, 0x80, 0xdc, 0xa0, 0xdc, 0xa0, 0xdc, 0xa0, 0xdc, 0x60, 0xd4, 0x40, 0xcc, 0xe0, 0xc3, 0x60, 0xb3, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x40, 0xab, 0xe0, 0xc3, 0x40, 0xd4, 0x80, 0xdc, 0xc0, 0xe4, 0xe0, 0xe4, 0xe0, 0xec, 0xe0, 0xe4, 0xa0, 0xdc, 0x80, 0xdc, 0x00, 0xcc, 0xa0, 0xbb, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x60, 0xb3, 0xe0, 0xc3, 0x60, 0xd4, 0x80, 0xdc, 0xe0, 0xe4, 0x00, 0xed, 0x00, 0xed, 0x00, 0xed, 0xc0, 0xe4, 0x80, 0xdc, 0x20, 0xcc, 0xa0, 0xbb, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x80, 0xb3, 0x20, 0xcc, 0x80, 0xdc, 0xc0, 0xe4, 0x20, 0xed, 0x40, 0xf5, 0x40, 0xf5, 0x40, 0xf5, 0x00, 0xed, 0xc0, 0xe4, 0x40, 0xd4, 0xc0, 0xc3, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0xa0, 0xbb, 0x20, 0xcc, 0xa0, 0xdc, 0xe0, 0xe4, 0x40, 0xf5, 0x60, 0xfd, 0x80, 0xfd, 0x60, 0xfd, 0x00, 0xed, 0xe0, 0xe4, 0x60, 0xd4, 0xe0, 0xc3, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x66, 0x9b, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x20, 0x7a, 0x66, 0x9b,
|
||||||
|
0x00, 0x00, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x66, 0x9b, 0x00, 0x00,
|
||||||
|
/*alpha channel*/
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const lv_img_dsc_t orange = {
|
||||||
|
.header.cf = LV_IMG_CF_RGB565A8,
|
||||||
|
.header.always_zero = 0,
|
||||||
|
.header.reserved = 0,
|
||||||
|
.header.w = 16,
|
||||||
|
.header.h = 16,
|
||||||
|
.data_size = 768,
|
||||||
|
.data = orange_map,
|
||||||
|
};
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include("lvgl.h")
|
||||||
|
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_IMG_PURPLE
|
||||||
|
#define LV_ATTRIBUTE_IMG_PURPLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_PURPLE uint8_t purple_map[] = {
|
||||||
|
0x00, 0x00, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0x00, 0x00,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x93, 0x89, 0x93, 0x89, 0x93, 0x89, 0x93, 0x89, 0x94, 0x89, 0x94, 0x89, 0x94, 0x89, 0x94, 0x89, 0x93, 0x89, 0x93, 0x89, 0x93, 0x89, 0x93, 0x89, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x73, 0x81, 0x55, 0x92, 0x55, 0x9a, 0x56, 0x9a, 0x57, 0xa2, 0x57, 0xa2, 0x57, 0xa2, 0x57, 0xa2, 0x56, 0x9a, 0x56, 0x9a, 0x55, 0x92, 0x73, 0x81, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x11, 0x68, 0x35, 0x9a, 0x5d, 0xe6, 0xdb, 0xcc, 0x19, 0xb3, 0x19, 0xb3, 0x19, 0xb3, 0x19, 0xb3, 0x19, 0xb3, 0x18, 0xb3, 0x56, 0x9a, 0x11, 0x68, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x11, 0x68, 0x13, 0x78, 0x15, 0x80, 0x98, 0xaa, 0x1b, 0xcc, 0x5a, 0xbb, 0x5a, 0xc3, 0x5a, 0xbb, 0x99, 0xb2, 0x15, 0x88, 0x14, 0x80, 0x12, 0x70, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x12, 0x78, 0x15, 0x80, 0x16, 0x90, 0x17, 0x98, 0x18, 0xa0, 0x18, 0xa0, 0x19, 0xa0, 0x18, 0xa0, 0x18, 0x98, 0x17, 0x98, 0x15, 0x88, 0x13, 0x78, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x13, 0x78, 0x15, 0x88, 0x17, 0x98, 0x18, 0x98, 0x19, 0xa0, 0x19, 0xa8, 0x19, 0xa8, 0x19, 0xa8, 0x18, 0xa0, 0x18, 0x98, 0x16, 0x90, 0x14, 0x80, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x14, 0x80, 0x16, 0x90, 0x18, 0xa0, 0x19, 0xa8, 0x1a, 0xa8, 0x1a, 0xb0, 0x1b, 0xb0, 0x1a, 0xb0, 0x1a, 0xa8, 0x19, 0xa0, 0x17, 0x98, 0x15, 0x88, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x15, 0x88, 0x17, 0x98, 0x19, 0xa0, 0x1a, 0xa8, 0x1b, 0xb0, 0x1b, 0xb8, 0x1b, 0xb8, 0x1b, 0xb8, 0x1a, 0xb0, 0x19, 0xa8, 0x18, 0xa0, 0x16, 0x88, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x15, 0x88, 0x18, 0x98, 0x1a, 0xa8, 0x1b, 0xb0, 0x1c, 0xb8, 0x1c, 0xc0, 0x1d, 0xc0, 0x1c, 0xc0, 0x1b, 0xb8, 0x1b, 0xb0, 0x19, 0xa0, 0x17, 0x90, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x16, 0x88, 0x18, 0xa0, 0x1a, 0xb0, 0x1b, 0xb0, 0x1c, 0xc0, 0x1d, 0xc0, 0x1d, 0xc0, 0x1d, 0xc0, 0x1c, 0xb8, 0x1b, 0xb0, 0x19, 0xa8, 0x17, 0x98, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x16, 0x90, 0x19, 0xa0, 0x1b, 0xb0, 0x1c, 0xb8, 0x1d, 0xc8, 0x1e, 0xc8, 0x1e, 0xd0, 0x1e, 0xc8, 0x1d, 0xc0, 0x1c, 0xb8, 0x1a, 0xa8, 0x18, 0x98, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x17, 0x90, 0x19, 0xa8, 0x1b, 0xb8, 0x1c, 0xc0, 0x1e, 0xc8, 0x1f, 0xd0, 0x1f, 0xd8, 0x1f, 0xd0, 0x1d, 0xc0, 0x1c, 0xc0, 0x1a, 0xb0, 0x18, 0x98, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0xb3, 0x81, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0x0f, 0x58, 0xb3, 0x81,
|
||||||
|
0x00, 0x00, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0xb3, 0x81, 0x00, 0x00,
|
||||||
|
/*alpha channel*/
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const lv_img_dsc_t purple = {
|
||||||
|
.header.cf = LV_IMG_CF_RGB565A8,
|
||||||
|
.header.always_zero = 0,
|
||||||
|
.header.reserved = 0,
|
||||||
|
.header.w = 16,
|
||||||
|
.header.h = 16,
|
||||||
|
.data_size = 768,
|
||||||
|
.data = purple_map,
|
||||||
|
};
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include("lvgl.h")
|
||||||
|
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_IMG_RED
|
||||||
|
#define LV_ATTRIBUTE_IMG_RED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_RED uint8_t red_map[] = {
|
||||||
|
0x00, 0x00, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0x00, 0x00,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x86, 0x99, 0x86, 0x99, 0x86, 0x99, 0x86, 0x99, 0x86, 0xa1, 0x86, 0xa1, 0x86, 0xa1, 0x86, 0xa1, 0x86, 0x99, 0x86, 0x99, 0x86, 0x99, 0x86, 0x99, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x66, 0x99, 0x49, 0xaa, 0x49, 0xaa, 0x49, 0xb2, 0x49, 0xba, 0x49, 0xba, 0x49, 0xba, 0x49, 0xba, 0x49, 0xb2, 0x49, 0xb2, 0x49, 0xaa, 0x66, 0x99, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0x88, 0x29, 0xaa, 0x59, 0xee, 0xd3, 0xdc, 0x0c, 0xcb, 0x0c, 0xcb, 0x0c, 0xcb, 0x0c, 0xcb, 0x0c, 0xcb, 0x0c, 0xc3, 0x49, 0xb2, 0x00, 0x88, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0x88, 0x00, 0x98, 0x00, 0xa8, 0x8a, 0xc2, 0x10, 0xdc, 0x4d, 0xd3, 0x4d, 0xd3, 0x4d, 0xd3, 0x8a, 0xca, 0x00, 0xa8, 0x00, 0xa0, 0x00, 0x90, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0x90, 0x00, 0xa8, 0x00, 0xb0, 0x00, 0xb8, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc8, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xb8, 0x00, 0xa8, 0x00, 0x98, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0x98, 0x00, 0xa8, 0x00, 0xb8, 0x00, 0xc0, 0x00, 0xc8, 0x00, 0xc8, 0x00, 0xc8, 0x00, 0xc8, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xb0, 0x00, 0xa0, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0xa0, 0x00, 0xb0, 0x00, 0xc0, 0x00, 0xc8, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd8, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xc8, 0x00, 0xb8, 0x00, 0xa8, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0xa8, 0x00, 0xb8, 0x00, 0xc8, 0x00, 0xd0, 0x00, 0xd8, 0x00, 0xd8, 0x00, 0xd8, 0x00, 0xd8, 0x00, 0xd0, 0x00, 0xc8, 0x00, 0xc0, 0x00, 0xb0, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0xa8, 0x00, 0xc0, 0x00, 0xd0, 0x00, 0xd8, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe8, 0x00, 0xe0, 0x00, 0xd8, 0x00, 0xd8, 0x00, 0xc8, 0x00, 0xb8, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0xb0, 0x00, 0xc0, 0x00, 0xd0, 0x00, 0xd8, 0x00, 0xe0, 0x00, 0xe8, 0x00, 0xe8, 0x00, 0xe8, 0x00, 0xe0, 0x00, 0xd8, 0x00, 0xc8, 0x00, 0xb8, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0xb0, 0x00, 0xc8, 0x00, 0xd8, 0x00, 0xe0, 0x00, 0xe8, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xe8, 0x00, 0xe0, 0x00, 0xd0, 0x00, 0xc0, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0xb8, 0x00, 0xc8, 0x00, 0xd8, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0xe8, 0x00, 0xe0, 0x00, 0xd0, 0x00, 0xc0, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0xa6, 0x99, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0xa6, 0x99,
|
||||||
|
0x00, 0x00, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0x00, 0x00,
|
||||||
|
/*alpha channel*/
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const lv_img_dsc_t red = {
|
||||||
|
.header.cf = LV_IMG_CF_RGB565A8,
|
||||||
|
.header.always_zero = 0,
|
||||||
|
.header.reserved = 0,
|
||||||
|
.header.w = 16,
|
||||||
|
.header.h = 16,
|
||||||
|
.data_size = 768,
|
||||||
|
.data = red_map,
|
||||||
|
};
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include("lvgl.h")
|
||||||
|
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LV_ATTRIBUTE_IMG_YELLOW
|
||||||
|
#define LV_ATTRIBUTE_IMG_YELLOW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_YELLOW uint8_t yellow_map[] = {
|
||||||
|
0x00, 0x00, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x00, 0x00,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0xa8, 0x9c, 0xa8, 0xa4, 0xa8, 0xa4, 0xa8, 0xa4, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0x88, 0x9c, 0xcb, 0xa4, 0xeb, 0xac, 0x0b, 0xad, 0x2b, 0xb5, 0x2b, 0xb5, 0x2b, 0xb5, 0x2b, 0xb5, 0x0b, 0xad, 0x0b, 0xad, 0xcb, 0xa4, 0x88, 0x9c, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0x20, 0x94, 0xeb, 0xac, 0x18, 0xef, 0x33, 0xce, 0xae, 0xc5, 0xae, 0xc5, 0xae, 0xc5, 0xae, 0xc5, 0x8e, 0xbd, 0x8e, 0xbd, 0x0b, 0xad, 0x20, 0x94, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0x20, 0x94, 0x60, 0x9c, 0xa0, 0xa4, 0x8c, 0xbd, 0x31, 0xd6, 0xef, 0xcd, 0xef, 0xcd, 0xef, 0xcd, 0x8c, 0xbd, 0xc0, 0xac, 0x80, 0xa4, 0x40, 0x94, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0x40, 0x9c, 0xa0, 0xa4, 0x00, 0xad, 0x20, 0xb5, 0x40, 0xbd, 0x40, 0xbd, 0x60, 0xbd, 0x40, 0xbd, 0x40, 0xbd, 0x20, 0xb5, 0xc0, 0xac, 0x80, 0x9c, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0x60, 0x9c, 0xc0, 0xac, 0x20, 0xb5, 0x20, 0xb5, 0x60, 0xbd, 0x80, 0xc5, 0x80, 0xc5, 0x80, 0xc5, 0x40, 0xbd, 0x40, 0xbd, 0xe0, 0xac, 0x80, 0xa4, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0x80, 0xa4, 0x00, 0xad, 0x40, 0xbd, 0x80, 0xc5, 0xa0, 0xcd, 0xc0, 0xcd, 0xc0, 0xcd, 0xc0, 0xcd, 0xa0, 0xc5, 0x60, 0xc5, 0x20, 0xb5, 0xc0, 0xac, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0xc0, 0xa4, 0x20, 0xb5, 0x60, 0xbd, 0x80, 0xc5, 0xc0, 0xcd, 0xe0, 0xd5, 0x00, 0xd6, 0xe0, 0xd5, 0xc0, 0xcd, 0x80, 0xc5, 0x40, 0xbd, 0xe0, 0xac, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0xc0, 0xac, 0x40, 0xbd, 0xa0, 0xcd, 0xc0, 0xcd, 0x20, 0xde, 0x20, 0xde, 0x40, 0xe6, 0x40, 0xde, 0x00, 0xd6, 0xc0, 0xcd, 0x60, 0xbd, 0x00, 0xb5, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0xe0, 0xac, 0x40, 0xbd, 0xc0, 0xcd, 0xe0, 0xd5, 0x40, 0xde, 0x60, 0xe6, 0x60, 0xe6, 0x60, 0xe6, 0x20, 0xde, 0xe0, 0xd5, 0x80, 0xc5, 0x20, 0xb5, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0x00, 0xad, 0x60, 0xc5, 0xe0, 0xd5, 0x20, 0xde, 0x80, 0xee, 0xa0, 0xee, 0xc0, 0xf6, 0xa0, 0xee, 0x40, 0xe6, 0x20, 0xde, 0xa0, 0xcd, 0x20, 0xb5, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0x00, 0xb5, 0x80, 0xc5, 0x00, 0xd6, 0x20, 0xde, 0xa0, 0xee, 0xe0, 0xf6, 0x00, 0xff, 0xe0, 0xf6, 0x60, 0xe6, 0x20, 0xde, 0xc0, 0xcd, 0x40, 0xbd, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x88, 0x9c, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0xa0, 0x83, 0x88, 0x9c,
|
||||||
|
0x00, 0x00, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x88, 0x9c, 0x00, 0x00,
|
||||||
|
/*alpha channel*/
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const lv_img_dsc_t yellow = {
|
||||||
|
.header.cf = LV_IMG_CF_RGB565A8,
|
||||||
|
.header.always_zero = 0,
|
||||||
|
.header.reserved = 0,
|
||||||
|
.header.w = 16,
|
||||||
|
.header.h = 16,
|
||||||
|
.data_size = 768,
|
||||||
|
.data = yellow_map,
|
||||||
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "wires_puzzle.h"
|
#include "wires_puzzle.h"
|
||||||
|
|
||||||
const static char* WIRES_FILE_PATH = "/sdcard/wires.txt";
|
const static char* WIRES_FILE_PATH = MOUNT_POINT "/wires.txt";
|
||||||
const static char* TAG = "wires_puzzle";
|
const static char* TAG = "wires_puzzle";
|
||||||
|
|
||||||
static int color_name_len[NUM_COLORS] = {
|
static int color_name_len[NUM_COLORS] = {
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <esp_random.h>
|
#include <esp_random.h>
|
||||||
#include <string.h>
|
#include "drivers/sd.h"
|
||||||
#include "esp_vfs_fat.h"
|
|
||||||
|
|
||||||
#define NUM_COLORS 6
|
#define NUM_COLORS 6
|
||||||
#define NUM_WIRES 8
|
#define NUM_WIRES 8
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user