增加单击SW2抽签功能

This commit is contained in:
CSBOOK\44744
2026-06-28 18:14:21 +08:00
parent 4cc2089192
commit 984787d736
7 changed files with 301 additions and 8 deletions
@@ -123,6 +123,20 @@ static void control_plane_dispatch_key_event(const control_plane_key_event_t *ev
event->press_duration_ms,
event->click_count);
if (event->key_id == CONTROL_PLANE_KEY_ID_SW2) {
if (event->type == CONTROL_PLANE_KEY_EVENT_SHORT_PRESS) {
const domain_expression_request_t request = {
.id = DOMAIN_EXPRESSION_CHOUQIAN,
.trigger = DOMAIN_EXPRESSION_TRIGGER_SW2_SINGLE_CLICK,
};
esp_err_t expr_err = domain_runtime_request_expression(&request);
if (expr_err != ESP_OK && expr_err != ESP_ERR_INVALID_STATE) {
ESP_LOGW(TAG, "SW2 single-click chouqian expression failed: %s", esp_err_to_name(expr_err));
}
}
return;
}
if (event->key_id != CONTROL_PLANE_KEY_ID_PTT) {
return;
}
+2
View File
@@ -88,6 +88,7 @@ typedef enum {
DOMAIN_EXPRESSION_WEALTH_SPIN,
DOMAIN_EXPRESSION_WEALTH_DIRECTION,
DOMAIN_EXPRESSION_MUYU,
DOMAIN_EXPRESSION_CHOUQIAN,
} domain_expression_id_t;
typedef enum {
@@ -100,6 +101,7 @@ typedef enum {
DOMAIN_EXPRESSION_TRIGGER_MODEL_DIRECTION,
DOMAIN_EXPRESSION_TRIGGER_DAILY_FORTUNE,
DOMAIN_EXPRESSION_TRIGGER_PTT_DOUBLE_CLICK,
DOMAIN_EXPRESSION_TRIGGER_SW2_SINGLE_CLICK,
} domain_expression_trigger_t;
typedef struct {
@@ -12,6 +12,7 @@
#include "domain_internal.h"
#include "platform.h"
#include "esp_random.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
@@ -77,6 +78,13 @@ static const uint8_t s_server_error_frame_order[] = {0, 1, 2, 1, 0};
static const uint8_t s_wifi_disconnected_frame_order[] = {0, 1, 2, 3, 2, 1, 0};
static const uint8_t s_basic_face_frame_order[] = {0, 1, 2};
static const uint8_t s_muyu_frame_order[] = {0, 1, 2, 1};
static const char *const s_chouqian_result_asset_dirs[] = {
"chouqian_buyun",
"chouqian_heping",
"chouqian_shangshang",
"chouqian_xiaoji",
"chouqian_zhongshang",
};
/*
* Wealth-direction reveal asset directories, indexed parallel to the direction
@@ -95,6 +103,7 @@ static const char *const s_wealth_direction_asset_dirs[] = {
};
#define DOMAIN_WEALTH_DIRECTION_FRAME_MS 100U
#define DOMAIN_CHOUQIAN_FRAME_MS 500U
#define DOMAIN_AUTH_KEY_STORE_NAMESPACE "auth_key"
#define DOMAIN_AUTH_STATE_STORE_NAMESPACE "auth"
@@ -1244,6 +1253,55 @@ static esp_err_t domain_resolve_expression_platform_request(
return ESP_OK;
}
if (request->id == DOMAIN_EXPRESSION_CHOUQIAN) {
static platform_lcd_presentation_step_t s_chouqian_steps[6];
const size_t result_count = sizeof(s_chouqian_result_asset_dirs) /
sizeof(s_chouqian_result_asset_dirs[0]);
const char *result_asset = s_chouqian_result_asset_dirs[esp_random() % result_count];
s_chouqian_steps[0] = (platform_lcd_presentation_step_t) {
.asset_dir = "chouqian_qianzhi",
.frame_index = 0,
.delay_ms = DOMAIN_CHOUQIAN_FRAME_MS,
};
s_chouqian_steps[1] = (platform_lcd_presentation_step_t) {
.asset_dir = "chouqian_qianzhi",
.frame_index = 1,
.delay_ms = DOMAIN_CHOUQIAN_FRAME_MS,
};
s_chouqian_steps[2] = (platform_lcd_presentation_step_t) {
.asset_dir = "chouqian_qianzhi",
.frame_index = 2,
.delay_ms = DOMAIN_CHOUQIAN_FRAME_MS,
};
s_chouqian_steps[3] = (platform_lcd_presentation_step_t) {
.asset_dir = result_asset,
.frame_index = 0,
.delay_ms = DOMAIN_CHOUQIAN_FRAME_MS,
};
s_chouqian_steps[4] = (platform_lcd_presentation_step_t) {
.asset_dir = result_asset,
.frame_index = 1,
.delay_ms = DOMAIN_CHOUQIAN_FRAME_MS,
};
s_chouqian_steps[5] = (platform_lcd_presentation_step_t) {
.asset_dir = result_asset,
.frame_index = 2,
.delay_ms = DOMAIN_CHOUQIAN_FRAME_MS,
};
*out_platform_request = (platform_lcd_presentation_request_t) {
.kind = PLATFORM_LCD_PRESENTATION_STEP_SEQUENCE,
.priority = 125,
.interrupt_current = true,
.return_to_idle = true,
.steps = s_chouqian_steps,
.step_count = sizeof(s_chouqian_steps) / sizeof(s_chouqian_steps[0]),
};
ESP_LOGI(TAG, "Chouqian result asset=%s", result_asset);
return ESP_OK;
}
const domain_expression_catalog_entry_t *entry = domain_find_expression_entry(request->id);
if (entry == NULL) {
ESP_LOGW(TAG, "Unknown expression request id=%d trigger=%d",
+18
View File
@@ -73,6 +73,24 @@ set(platform_lcd_flash_assets
muyu0
muyu1
muyu2
chouqian_qianzhi0
chouqian_qianzhi1
chouqian_qianzhi2
chouqian_buyun0
chouqian_buyun1
chouqian_buyun2
chouqian_heping0
chouqian_heping1
chouqian_heping2
chouqian_shangshang0
chouqian_shangshang1
chouqian_shangshang2
chouqian_xiaoji0
chouqian_xiaoji1
chouqian_xiaoji2
chouqian_zhongshang0
chouqian_zhongshang1
chouqian_zhongshang2
)
set(platform_lcd_flash_asset_files)
foreach(lcd_rle_asset IN LISTS platform_lcd_flash_assets)
+10
View File
@@ -350,13 +350,21 @@ esp_err_t platform_stop_lcd_render_loop(int timeout_ms);
#define PLATFORM_LCD_PRESENTATION_FRAME_ORDER_MAX 16
#define PLATFORM_LCD_PRESENTATION_ASSET_DIR_MAX 32
#define PLATFORM_LCD_PRESENTATION_STEP_MAX 12
typedef enum {
PLATFORM_LCD_PRESENTATION_IDLE = 0,
PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE,
PLATFORM_LCD_PRESENTATION_SLOT_REELS,
PLATFORM_LCD_PRESENTATION_STEP_SEQUENCE,
} platform_lcd_presentation_kind_t;
typedef struct {
const char *asset_dir;
uint8_t frame_index;
uint32_t delay_ms;
} platform_lcd_presentation_step_t;
typedef struct {
platform_lcd_presentation_kind_t kind;
uint8_t priority;
@@ -368,6 +376,8 @@ typedef struct {
uint16_t repeat_count;
uint32_t frame_ms;
uint32_t duration_ms;
const platform_lcd_presentation_step_t *steps;
size_t step_count;
} platform_lcd_presentation_request_t;
/**
+57
View File
@@ -50,6 +50,8 @@ typedef struct {
uint16_t repeat_count;
uint32_t frame_ms;
uint32_t duration_ms;
platform_lcd_presentation_step_t steps[PLATFORM_LCD_PRESENTATION_STEP_MAX];
size_t step_count;
} lcd_direct_request_t;
typedef struct {
@@ -644,6 +646,43 @@ static esp_err_t lcd_direct_play_asset_sequence(const lcd_direct_request_t *requ
return ESP_OK;
}
static esp_err_t lcd_direct_play_step_sequence(const lcd_direct_request_t *request)
{
ESP_RETURN_ON_FALSE(request != NULL,
ESP_ERR_INVALID_ARG,
TAG,
"invalid step sequence");
for (size_t i = 0; i < request->step_count; ++i) {
bool stop = false;
portENTER_CRITICAL(&s_state_lock);
stop = s_stop_requested || s_pending_valid;
portEXIT_CRITICAL(&s_state_lock);
if (stop) {
return ESP_ERR_INVALID_STATE;
}
const platform_lcd_presentation_step_t *step = &request->steps[i];
const lcd_direct_image_t *frame = lcd_direct_asset_frame(step->asset_dir, step->frame_index);
ESP_RETURN_ON_FALSE(frame != NULL,
ESP_ERR_NOT_FOUND,
TAG,
"LCD step frame not found asset=%s frame=%u",
step->asset_dir != NULL ? step->asset_dir : "<null>",
(unsigned)step->frame_index);
ESP_RETURN_ON_ERROR(lcd_direct_draw_rle_image(frame, NULL, 0),
TAG,
"draw step frame failed");
uint32_t delay_ms = step->delay_ms > 0U ? step->delay_ms : 100U;
vTaskDelay(pdMS_TO_TICKS(delay_ms));
}
lcd_direct_signal_completion();
return ESP_OK;
}
static esp_err_t lcd_direct_play_basic_face_until_pending(void)
{
const lcd_direct_request_t request = {
@@ -768,6 +807,17 @@ void lcd_direct_start_render_loop(void)
s_pending_valid = true;
portEXIT_CRITICAL(&s_state_lock);
}
} else if (request.kind == PLATFORM_LCD_PRESENTATION_STEP_SEQUENCE) {
draw_err = lcd_direct_play_step_sequence(&request);
if (draw_err == ESP_OK && request.return_to_idle) {
lcd_direct_request_t idle = {
.kind = PLATFORM_LCD_PRESENTATION_IDLE,
};
portENTER_CRITICAL(&s_state_lock);
s_pending = idle;
s_pending_valid = true;
portEXIT_CRITICAL(&s_state_lock);
}
} else {
draw_err = lcd_direct_draw_test_pattern(&request);
}
@@ -872,6 +922,13 @@ esp_err_t lcd_direct_request_presentation(const platform_lcd_presentation_reques
}
memcpy(copied.frame_order, request->frame_order, copied.frame_order_count);
}
if (request->steps != NULL && request->step_count > 0U) {
copied.step_count = request->step_count;
if (copied.step_count > PLATFORM_LCD_PRESENTATION_STEP_MAX) {
copied.step_count = PLATFORM_LCD_PRESENTATION_STEP_MAX;
}
memcpy(copied.steps, request->steps, copied.step_count * sizeof(copied.steps[0]));
}
TaskHandle_t task = NULL;
portENTER_CRITICAL(&s_state_lock);
+142 -8
View File
@@ -39,6 +39,106 @@ static const lcd_direct_image_t s_muyu_frames[] = {
},
};
static const lcd_direct_image_t s_chouqian_qianzhi_frames[] = {
{
.path = LCD_ASSET_BASE_PATH "chouqian_qianzhi0.rle",
.run_count = 74056U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_qianzhi1.rle",
.run_count = 73259U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_qianzhi2.rle",
.run_count = 72906U,
},
};
static const lcd_direct_image_t s_chouqian_buyun_frames[] = {
{
.path = LCD_ASSET_BASE_PATH "chouqian_buyun0.rle",
.run_count = 72370U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_buyun1.rle",
.run_count = 72552U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_buyun2.rle",
.run_count = 72757U,
},
};
static const lcd_direct_image_t s_chouqian_heping_frames[] = {
{
.path = LCD_ASSET_BASE_PATH "chouqian_heping0.rle",
.run_count = 72370U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_heping1.rle",
.run_count = 73049U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_heping2.rle",
.run_count = 73365U,
},
};
static const lcd_direct_image_t s_chouqian_shangshang_frames[] = {
{
.path = LCD_ASSET_BASE_PATH "chouqian_shangshang0.rle",
.run_count = 72370U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_shangshang1.rle",
.run_count = 72944U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_shangshang2.rle",
.run_count = 73190U,
},
};
static const lcd_direct_image_t s_chouqian_xiaoji_frames[] = {
{
.path = LCD_ASSET_BASE_PATH "chouqian_xiaoji0.rle",
.run_count = 72370U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_xiaoji1.rle",
.run_count = 72827U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_xiaoji2.rle",
.run_count = 73006U,
},
};
static const lcd_direct_image_t s_chouqian_zhongshang_frames[] = {
{
.path = LCD_ASSET_BASE_PATH "chouqian_zhongshang0.rle",
.run_count = 72370U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_zhongshang1.rle",
.run_count = 72135U,
},
{
.path = LCD_ASSET_BASE_PATH "chouqian_zhongshang2.rle",
.run_count = 72292U,
},
};
static const lcd_direct_image_t *lcd_direct_frame_from_array(const lcd_direct_image_t *frames,
size_t frame_count,
uint8_t frame_index)
{
if (frame_index >= frame_count) {
return NULL;
}
return &frames[frame_index];
}
const lcd_direct_image_t *lcd_direct_default_image(void)
{
return &s_default_image;
@@ -51,17 +151,51 @@ const lcd_direct_image_t *lcd_direct_asset_frame(const char *asset_dir, uint8_t
}
if (strcmp(asset_dir, "jichubiaoqing") == 0) {
if (frame_index < sizeof(s_basic_face_frames) / sizeof(s_basic_face_frames[0])) {
return &s_basic_face_frames[frame_index];
}
return NULL;
return lcd_direct_frame_from_array(s_basic_face_frames,
sizeof(s_basic_face_frames) / sizeof(s_basic_face_frames[0]),
frame_index);
}
if (strcmp(asset_dir, "muyu") == 0) {
if (frame_index < sizeof(s_muyu_frames) / sizeof(s_muyu_frames[0])) {
return &s_muyu_frames[frame_index];
}
return NULL;
return lcd_direct_frame_from_array(s_muyu_frames,
sizeof(s_muyu_frames) / sizeof(s_muyu_frames[0]),
frame_index);
}
if (strcmp(asset_dir, "chouqian_qianzhi") == 0) {
return lcd_direct_frame_from_array(s_chouqian_qianzhi_frames,
sizeof(s_chouqian_qianzhi_frames) / sizeof(s_chouqian_qianzhi_frames[0]),
frame_index);
}
if (strcmp(asset_dir, "chouqian_buyun") == 0) {
return lcd_direct_frame_from_array(s_chouqian_buyun_frames,
sizeof(s_chouqian_buyun_frames) / sizeof(s_chouqian_buyun_frames[0]),
frame_index);
}
if (strcmp(asset_dir, "chouqian_heping") == 0) {
return lcd_direct_frame_from_array(s_chouqian_heping_frames,
sizeof(s_chouqian_heping_frames) / sizeof(s_chouqian_heping_frames[0]),
frame_index);
}
if (strcmp(asset_dir, "chouqian_shangshang") == 0) {
return lcd_direct_frame_from_array(s_chouqian_shangshang_frames,
sizeof(s_chouqian_shangshang_frames) / sizeof(s_chouqian_shangshang_frames[0]),
frame_index);
}
if (strcmp(asset_dir, "chouqian_xiaoji") == 0) {
return lcd_direct_frame_from_array(s_chouqian_xiaoji_frames,
sizeof(s_chouqian_xiaoji_frames) / sizeof(s_chouqian_xiaoji_frames[0]),
frame_index);
}
if (strcmp(asset_dir, "chouqian_zhongshang") == 0) {
return lcd_direct_frame_from_array(s_chouqian_zhongshang_frames,
sizeof(s_chouqian_zhongshang_frames) / sizeof(s_chouqian_zhongshang_frames[0]),
frame_index);
}
return NULL;