tetris impl

This commit is contained in:
Mitchell Marino 2024-08-09 11:20:42 -05:00
parent b6eac70c2c
commit 074faf8879
6 changed files with 78 additions and 1735 deletions

View File

@ -10,15 +10,11 @@ static lv_disp_drv_t lv_disp_drv;
static lv_disp_t *lv_display = NULL; static lv_disp_t *lv_display = NULL;
static lv_color_t *lv_buf_1 = NULL; static lv_color_t *lv_buf_1 = NULL;
static lv_color_t *lv_buf_2 = NULL; static lv_color_t *lv_buf_2 = NULL;
static lv_obj_t *meter = NULL;
static lv_style_t style_screen;
lv_obj_t* screen; lv_obj_t* screen;
static lv_style_t style_screen;
static void update_meter_value(void *indic, int32_t v) SemaphoreHandle_t xGuiSemaphore;
{
lv_meter_set_indicator_end_value(meter, (lv_meter_indicator_t*)indic, v);
}
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,
@ -40,7 +36,7 @@ static void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t
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);
} }
static void IRAM_ATTR lvgl_tick_cb(void *param) { static void IRAM_ATTR lv_tick_task(void *param) {
lv_tick_inc(LVGL_UPDATE_PERIOD_MS); lv_tick_inc(LVGL_UPDATE_PERIOD_MS);
} }
@ -121,7 +117,8 @@ static void initialize_display() {
#endif #endif
} }
static void initialize_lvgl() { static void guiTask(void *pvParameter) {
xGuiSemaphore = xSemaphoreCreateMutex();
ESP_LOGI(TAG, "Initializing LVGL"); ESP_LOGI(TAG, "Initializing LVGL");
lv_init(); lv_init();
ESP_LOGI(TAG, "Allocating %zu bytes for LVGL buffer", LV_BUFFER_SIZE * sizeof(lv_color_t)); ESP_LOGI(TAG, "Allocating %zu bytes for LVGL buffer", LV_BUFFER_SIZE * sizeof(lv_color_t));
@ -145,86 +142,48 @@ static void initialize_lvgl() {
ESP_LOGI(TAG, "Creating LVGL tick timer"); ESP_LOGI(TAG, "Creating LVGL tick timer");
const esp_timer_create_args_t lvgl_tick_timer_args = { const esp_timer_create_args_t lvgl_tick_timer_args = {
.callback = &lvgl_tick_cb, .callback = &lv_tick_task,
.arg = NULL, // .dispatch_method = ESP_TIMER_TASK,
.dispatch_method = ESP_TIMER_TASK, .name = "periodic_gui",
.name = "lvgl_tick", // .skip_unhandled_events = false
.skip_unhandled_events = false
}; };
esp_timer_handle_t lvgl_tick_timer = NULL; esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer)); ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &periodic_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_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_disp_get_scr_act(NULL);
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(lv_scr_act(), &style_screen, LV_STATE_DEFAULT);
}
void create_demo_ui() { while (1) {
// Create a meter which can be animated. /* Delay 1 tick (assumes FreeRTOS tick is 10ms */
meter = lv_meter_create(screen); vTaskDelay(pdMS_TO_TICKS(10));
lv_obj_center(meter);
lv_obj_set_size(meter, 200, 200);
// Add a scale first /* Try to take the semaphore, call lvgl related function on success */
lv_meter_scale_t *scale = lv_meter_add_scale(meter); if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) {
lv_meter_set_scale_ticks(meter, scale, 41, 2, 10, lv_palette_main(LV_PALETTE_GREY)); lv_task_handler();
lv_meter_set_scale_major_ticks(meter, scale, 8, 4, 15, lv_color_black(), 10); xSemaphoreGive(xGuiSemaphore);
}
}
lv_meter_indicator_t *indic; vTaskDelete(NULL);
// Add a blue arc to the start
indic = lv_meter_add_arc(meter, scale, 3, lv_palette_main(LV_PALETTE_BLUE), 0);
lv_meter_set_indicator_start_value(meter, indic, 0);
lv_meter_set_indicator_end_value(meter, indic, 20);
// Make the tick lines blue at the start of the scale
indic = lv_meter_add_scale_lines(meter, scale, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_BLUE), false, 0);
lv_meter_set_indicator_start_value(meter, indic, 0);
lv_meter_set_indicator_end_value(meter, indic, 20);
// Add a red arc to the end
indic = lv_meter_add_arc(meter, scale, 3, lv_palette_main(LV_PALETTE_RED), 0);
lv_meter_set_indicator_start_value(meter, indic, 80);
lv_meter_set_indicator_end_value(meter, indic, 100);
// Make the tick lines red at the end of the scale
indic = lv_meter_add_scale_lines(meter, scale, lv_palette_main(LV_PALETTE_RED), lv_palette_main(LV_PALETTE_RED), false, 0);
lv_meter_set_indicator_start_value(meter, indic, 80);
lv_meter_set_indicator_end_value(meter, indic, 100);
// Add a needle line indicator
indic = lv_meter_add_needle_line(meter, scale, 4, lv_palette_main(LV_PALETTE_GREY), -10);
// Create an animation to set the value
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_exec_cb(&a, update_meter_value);
lv_anim_set_var(&a, indic);
lv_anim_set_values(&a, 0, 100);
lv_anim_set_time(&a, 2000);
lv_anim_set_repeat_delay(&a, 100);
lv_anim_set_playback_time(&a, 500);
lv_anim_set_playback_delay(&a, 100);
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
lv_anim_start(&a);
} }
static void tick_timer_task(void* arg) { static void tick_timer_task(void* arg) {
while (1) while (1)
{ {
lv_task_handler();
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
lv_timer_handler();
} }
} }
void init_tft() { void init_tft() {
initialize_spi(); initialize_spi();
initialize_display(); initialize_display();
initialize_lvgl(); xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 5, NULL, 1);
xTaskCreate(tick_timer_task, "tick_lvgl", 4096, NULL, 5, NULL); // xTaskCreatePinnedToCore(tick_timer_task, "tick_lvgl", 4096, NULL, 5, NULL, 1);
ESP_LOGI(TAG, "TFT initialization Successful"); ESP_LOGI(TAG, "TFT initialization Successful");
} }

View File

@ -64,6 +64,8 @@
extern lv_obj_t* screen; extern lv_obj_t* screen;
extern SemaphoreHandle_t xGuiSemaphore;
void create_demo_ui(); void create_demo_ui();
void init_tft(); void init_tft();

View File

@ -42,12 +42,11 @@ extern "C" void app_main(void) {
// create_demo_ui(); // create_demo_ui();
clean_bomb(); clean_bomb();
// step0();
step0(); // set_game_time(30000);
set_game_time(30000); // start_game_timer();
start_game_timer(); // clean_bomb();
clean_bomb(); // step1();
step1();
clean_bomb(); clean_bomb();
step2(); step2();
clean_bomb(); clean_bomb();
@ -64,8 +63,6 @@ extern "C" void app_main(void) {
ESP_LOGI(TAG, "Bomb has been diffused. Counter-Terrorists win."); ESP_LOGI(TAG, "Bomb has been diffused. Counter-Terrorists win.");
ESP_ERROR_CHECK_WITHOUT_ABORT(play_raw("/sdcard/diffused.pcm")); ESP_ERROR_CHECK_WITHOUT_ABORT(play_raw("/sdcard/diffused.pcm"));
// play_example(); // play_example();

View File

@ -8,7 +8,6 @@ set(SOURCES
"step5.cpp" "step5.cpp"
"step6.cpp" "step6.cpp"
"wires_puzzle.cpp" "wires_puzzle.cpp"
"tetris.c"
) )
target_sources(${COMPONENT_LIB} PRIVATE ${SOURCES}) target_sources(${COMPONENT_LIB} PRIVATE ${SOURCES})

View File

@ -3,6 +3,7 @@
static const char *TAG = "step2"; static const char *TAG = "step2";
static lv_obj_t* scr; static lv_obj_t* scr;
static lv_style_t scr_style;
static lv_obj_t* img; static lv_obj_t* img;
static bool invisible_blocks = false; static bool invisible_blocks = false;
@ -12,6 +13,20 @@ 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 const char* BACKGROUND_FILE_NAME = "A:/sdcard/bg.bin";
static const char* PIECE_IMG_SRC[] = {
"A:/sdcard/red.bin",
"A:/sdcard/lb.bin",
"A:/sdcard/db.bin",
"A:/sdcard/orange.bin",
"A:/sdcard/yellow.bin",
"A:/sdcard/green.bin",
"A:/sdcard/purple.bin",
};
static bool game = true; static bool game = true;
static int score = 0; static int score = 0;
@ -25,13 +40,11 @@ static int piece_nodes[4][2] = {
{0, 0}, {0, 0},
}; };
static lv_color_t piece_colors[] = { lv_obj_t* piece_imgs[4] = {};
(lv_color_t { .full = 0xfee0 }),
};
std::random_device rd; std::random_device rd;
std::mt19937 gen(rd()); std::mt19937 gen(rd());
std::uniform_int_distribution<> piece_dist(2, 7); std::uniform_int_distribution<> piece_dist(2, 6);
static void generate_block(void); static void generate_block(void);
static void show_board(void); static void show_board(void);
@ -100,22 +113,30 @@ static int bdca(int i) { // [0,1,2,3] -> [ 0,+2,+1,-1]
static void init_screen(void) { static void init_screen(void) {
LV_IMG_DECLARE(tetris); // create new screen
// scr = lv_obj_create(NULL);
// scr = lv_obj_create(screen); // lv_style_init(&scr_style);
// img = lv_img_create(lv_scr_act()); // lv_style_set_bg_color(&scr_style, lv_color_black());
// lv_img_set_src(img, &tetris); // lv_obj_add_style(scr, &scr_style, LV_STATE_DEFAULT);
// lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); // lv_scr_load(scr);
img = lv_img_create(lv_scr_act()); img = lv_img_create(lv_scr_act());
lv_img_set_src(img, "A:/sdcard/db.bin"); lv_img_set_src(img, BACKGROUND_FILE_NAME);
lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
for (int i = 0; i < 4; i++) {
piece_imgs[i] = lv_img_create(lv_scr_act());
lv_obj_align(piece_imgs[i], LV_ALIGN_BOTTOM_LEFT, 159, -320);
}
// play_raw(MOUNT_POINT "/tetris.pcm"); // play_raw(MOUNT_POINT "/tetris.pcm");
} }
static void deinit_screen(void) { static void deinit_screen(void) {
lv_obj_clean(scr); while (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdFALSE) vTaskDelay(pdMS_TO_TICKS(10));
lv_obj_clean(lv_scr_act());
xSemaphoreGive(xGuiSemaphore);
} }
void step2(void) { void step2(void) {
@ -185,8 +206,14 @@ static void show_board(void) {
printf("|\n"); printf("|\n");
} }
printf("\n"); printf("\n");
} else { }
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
int* p = piece_nodes[i];
lv_obj_t* piece_img = piece_imgs[i];
// lv_img_set_src(piece_img, FILE_NAME[piece]);
lv_obj_align(piece_img, LV_ALIGN_BOTTOM_LEFT, 159 + p[1]*16, -(p[0]*16));
} }
} }
@ -215,6 +242,11 @@ static void generate_block(void) {
} }
} }
} }
for (int i = 0; i < 4; i++) {
lv_obj_t* piece_img = piece_imgs[i];
lv_img_set_src(piece_img, PIECE_IMG_SRC[piece]);
}
} }
static void rotate_block(void) { static void rotate_block(void) {
@ -415,3 +447,4 @@ static void line_clear(int height) {
} }
score++; score++;
} }

File diff suppressed because one or more lines are too long