/** * @file main.c * @brief LVGL 模拟器入口 — 160x160 1bpp 单色菜单 UI * @note 基于 lv_port_pc_vscode 适配,用于 PC 上 UI 开发与调试 * * 键盘映射: * ↑/↓/←/→ → 方向键导航 * Enter → 确认/进入 * Escape → 返回 */ #include #include #ifdef _MSC_VER #include #else #include #endif #define SDL_MAIN_HANDLED #include #include "lvgl.h" #include "sim_port.h" #include "ui_menu.h" /* 屏幕尺寸(与 MCU 端一致) */ #define SIM_SCREEN_W 160 #define SIM_SCREEN_H 160 /** * @brief 程序入口 */ int main(int argc, char **argv) { (void)argc; (void)argv; /* 初始化 SDL2(仅 timer + events,视频由 lv_sdl_window 内部初始化) */ if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_EVENTS) != 0) { fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError()); return 1; } /* 初始化 LVGL */ lv_init(); /* 初始化模拟器端口:创建 SDL 窗口 + 键盘输入 */ if (sim_port_init(SIM_SCREEN_W, SIM_SCREEN_H) != 0) { fprintf(stderr, "sim_port_init failed\n"); SDL_Quit(); return 1; } /* 设置 SDL 窗口标题 */ lv_display_t *disp = lv_display_get_default(); if (disp != NULL) { lv_sdl_window_set_title(disp, "STM32F4-Base UI Simulator (160x160 1bpp)"); } /* 构建菜单 UI(与 MCU 端共用 ui_menu.c) */ if (ui_menu_init() != 0) { fprintf(stderr, "ui_menu_init failed\n"); SDL_Quit(); return 1; } printf("=== LVGL Simulator Started ===\n"); printf("Screen: %dx%d 1bpp\n", SIM_SCREEN_W, SIM_SCREEN_H); printf("Keyboard: ↑↓←→ navigate, Enter confirm, Escape back\n"); printf("Press Ctrl+C or close window to exit\n\n"); /* 主循环:处理 SDL 事件 + 驱动 LVGL 刷新 */ while (1) { /* 处理 SDL 事件(窗口关闭等) */ SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { printf("SDL_QUIT received, exiting...\n"); SDL_Quit(); return 0; } if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE) { /* Escape 键:如果在子页面则返回上一级 */ /* LVGL keyboard 驱动已自动处理 LV_KEY_ESC */ } } /* 驱动 LVGL 定时器与刷新 */ uint32_t sleep_ms = lv_timer_handler(); if (sleep_ms == LV_NO_TIMER_READY) { sleep_ms = LV_DEF_REFR_PERIOD; } /* 强制整屏刷新(1bpp SDL PARTIAL 模式下保证首帧输出) */ lv_refr_now(NULL); #ifdef _MSC_VER Sleep(sleep_ms); #else usleep(sleep_ms * 1000); #endif } return 0; }