diff --git a/Apps/GameBoy/main/Source/main.c b/Apps/GameBoy/main/Source/main.c index 6030718..b0c5183 100644 --- a/Apps/GameBoy/main/Source/main.c +++ b/Apps/GameBoy/main/Source/main.c @@ -14,7 +14,16 @@ #include #include + +/* Board firmware 0.8.0-dev/IDF 5.3.2 does not export esp_log for side-loaded ELFs. */ +#undef ESP_LOGI +#undef ESP_LOGW +#undef ESP_LOGE +#define ESP_LOGI(tag, fmt, ...) do { (void)(tag); } while (0) +#define ESP_LOGW(tag, fmt, ...) do { (void)(tag); } while (0) +#define ESP_LOGE(tag, fmt, ...) do { (void)(tag); } while (0) #include +#include #include #include @@ -29,8 +38,8 @@ #include "peanut_gb.h" #define TAG "GameBoy" -#define DEFAULT_ROM_PATH "/sdcard/roms/gb/default.gb" -#define ROMS_DIR "/sdcard/roms/gb" +#define DEFAULT_ROM_PATH "/data/roms/gb/default.gb" +#define ROMS_DIR "/data/roms/gb" #define MAX_ROMS 64 #define MAX_PATH 512 #define MAX_ROM_SIZE (2 * 1024 * 1024) @@ -91,6 +100,8 @@ typedef struct { bool emu_running; bool framebuffer_allocated; bool rom_loaded; + uint32_t fps_frames; + int64_t fps_last_us; } AppCtx; typedef struct { @@ -242,11 +253,23 @@ static void scan_rom_dir(AppCtx* ctx) { /* Emu timer */ static void emu_timer_cb(lv_timer_t* timer) { AppCtx* ctx=(AppCtx*)lv_timer_get_user_data(timer); - if (!ctx || !ctx->emu_running || !ctx->rom_loaded) return; - if (!ctx->canvas || !ctx->fb_native) return; - ctx->gb.direct.joypad=ctx->joypad_state; + if (!ctx || !ctx->emu_running || !ctx->rom_loaded || !ctx->canvas) return; + ctx->gb.direct.joypad = ctx->joypad_state; gb_run_frame(&ctx->gb); lv_obj_invalidate(ctx->canvas); + ctx->fps_frames++; + int64_t now = esp_timer_get_time(); + if (ctx->fps_last_us == 0) ctx->fps_last_us = now; + int64_t elapsed = now - ctx->fps_last_us; + if (elapsed >= 1000000) { + uint32_t fps = (uint32_t)((ctx->fps_frames * 1000000ULL) / (uint64_t)elapsed); + if (ctx->status_label) { + lv_label_set_text_fmt(ctx->status_label, "GB: %s FPS:%lu", ctx->rom_title[0] ? ctx->rom_title : "GameBoy", (unsigned long)fps); + } + printf("GAMEBOY_FPS %lu\n", (unsigned long)fps); + ctx->fps_frames = 0; + ctx->fps_last_us = now; + } } /* Input helpers */ @@ -310,7 +333,7 @@ static void default_rom_event(lv_event_t* e){ if (load_rom_file(ctx, DEFAULT_ROM_PATH)){ switch_to_emu(ctx); } else { - if (ctx->status_label) lv_label_set_text(ctx->status_label, "default.gb not found in /sdcard/roms/gb/"); + if (ctx->status_label) lv_label_set_text(ctx->status_label, "default.gb not found in /data/roms/gb/"); } } static void back_to_menu_event(lv_event_t* e){ @@ -343,7 +366,7 @@ static void build_browser_ui(AppCtx* ctx, lv_obj_t* parent){ if (ctx->rom_count==0){ lv_obj_t* lbl=lv_label_create(parent); - lv_label_set_text(lbl, "No ROMs found in /sdcard/roms/gb\nPut .gb files there."); + lv_label_set_text(lbl, "No ROMs found in /data/roms/gb\nPut .gb files there."); lv_obj_set_style_text_color(lbl, lv_color_white(), 0); } else { for (int i=0;irom_count;i++){ @@ -379,7 +402,8 @@ static void build_emu_ui(AppCtx* ctx, lv_obj_t* parent){ lv_obj_set_style_bg_color(info_bar, lv_color_hex(0x222222), 0); lv_obj_t* title_lbl=lv_label_create(info_bar); - lv_label_set_text_fmt(title_lbl, "GB: %s", ctx->rom_title[0]?ctx->rom_title:"GameBoy"); + ctx->status_label = title_lbl; + lv_label_set_text_fmt(title_lbl, "GB: %s FPS:--", ctx->rom_title[0]?ctx->rom_title:"GameBoy"); lv_obj_set_style_text_color(title_lbl, lv_color_white(), 0); lv_obj_t* spacer=lv_obj_create(info_bar); @@ -409,18 +433,10 @@ static void build_emu_ui(AppCtx* ctx, lv_obj_t* parent){ } if (ctx->fb_native){ - lv_coord_t disp_w=lv_display_get_horizontal_resolution(NULL); - lv_coord_t disp_h=lv_display_get_vertical_resolution(NULL); - int scale=1; - if (disp_w>=FRAME_W*2 && disp_h>=FRAME_H*3) scale=2; - if (disp_w>=FRAME_W*3 && disp_h>=FRAME_H*4) scale=3; - lv_obj_t* canvas=lv_canvas_create(canvas_cont); - ctx->canvas=canvas; - lv_canvas_set_buffer(canvas, ctx->fb_native, FRAME_W, FRAME_H, LV_COLOR_FORMAT_RGB565); - (void)scale; /* Prototype: avoid non-exported LVGL transform-scale symbols in side-loaded app. */ - lv_obj_set_style_border_width(canvas,1,0); - lv_obj_set_style_border_color(canvas, lv_color_hex(0x555555),0); - lv_obj_center(canvas); + ctx->canvas = lv_canvas_create(canvas_cont); + lv_canvas_set_buffer(ctx->canvas, ctx->fb_native, FRAME_W, FRAME_H, LV_COLOR_FORMAT_RGB565); + lv_obj_set_style_border_width(ctx->canvas, 1, 0); + lv_obj_set_style_border_color(ctx->canvas, lv_color_hex(0x444444), 0); } else { lv_obj_t* err=lv_label_create(canvas_cont); lv_label_set_text(err,"FB alloc failed"); lv_obj_set_style_text_color(err, lv_color_white(),0); } @@ -495,6 +511,8 @@ static void build_emu_ui(AppCtx* ctx, lv_obj_t* parent){ } if (ctx->emu_timer){ lv_timer_delete(ctx->emu_timer); ctx->emu_timer=NULL; } + ctx->fps_frames = 0; + ctx->fps_last_us = esp_timer_get_time(); ctx->emu_timer=lv_timer_create(emu_timer_cb, TICK_MS, ctx); ctx->emu_running=true; ctx->mode=APP_MODE_EMU;