diff --git a/CODE/UTSM/include/utsm/deshab_ui.h b/CODE/UTSM/include/utsm/deshab_ui.h index 7cfd256..c452ab8 100644 --- a/CODE/UTSM/include/utsm/deshab_ui.h +++ b/CODE/UTSM/include/utsm/deshab_ui.h @@ -738,27 +738,28 @@ static inline du_u32 du_theme_accent(du_theme t) { #define DP_KATE_DANGER 0xFFFF4D6Du /* --danger: #ff4d6d */ /* =================================================================== - * L1 — Winux-Kate 语义色值 + * L1 — 桌面语义色值(白色调主题,去 winux-Kate 深色风) + * 底色白/浅灰,组件白卡片 + 浅灰描边,文字深灰,强调色深板岩。 * =================================================================== */ -#define KS_BG_PRIMARY DP_KATE_BG -#define KS_BG_SECONDARY DP_KATE_PANEL_SOLID -#define KS_BG_TERTIARY DP_KATE_BG2 +#define KS_BG_PRIMARY 0xFFF3F4F6u /* 页面底:浅灰 */ +#define KS_BG_SECONDARY 0xFFFFFFFFu /* 面板:白 */ +#define KS_BG_TERTIARY 0xFFE9ECF0u /* 三级底:稍深浅灰 */ -#define KS_TEXT_PRIMARY DP_KATE_TEXT -#define KS_TEXT_DIM DP_KATE_TEXT_DIM -#define KS_TEXT_INVERT DP_KATE_BG +#define KS_TEXT_PRIMARY 0xFF1A1A1Au /* 主文字:近黑 */ +#define KS_TEXT_DIM 0xFF6B7280u /* 次文字:中灰 */ +#define KS_TEXT_INVERT 0xFFFFFFFFu /* accent 上的文字:白 */ -#define KS_ACCENT DP_KATE_ACCENT -#define KS_ACCENT2 DP_KATE_ACCENT2 -#define KS_ACCENT_DIM DP_KATE_ACCENT_DIM_SOLID +#define KS_ACCENT 0xFF111827u /* 强调:深板岩(白底上高对比) */ +#define KS_ACCENT2 0xFF4B5563u /* 次强调:中板岩 */ +#define KS_ACCENT_DIM 0xFFE5E7EBu /* 强调淡底:浅灰 */ -#define KS_BORDER DP_KATE_PANEL_BORDER_SOLID -#define KS_BORDER_FOCUS DP_KATE_ACCENT -#define KS_BORDER_DIM 0xFF1A2840u /* 暗边框 */ +#define KS_BORDER 0xFFD1D5DBu /* 边框:浅灰 */ +#define KS_BORDER_FOCUS 0xFF111827u /* 聚焦边框:深板岩 */ +#define KS_BORDER_DIM 0xFFE5E7EBu /* 暗边框:极浅灰 */ -#define KS_DANGER DP_KATE_DANGER -#define KS_WARN DP_KATE_WARN +#define KS_DANGER 0xFFDC2626u /* 红 */ +#define KS_WARN 0xFFD97706u /* 琥珀 */ /* =================================================================== * Winux-Kate 布局常量(源自 theme.css / pages.css) diff --git a/CODE/desktop/MAKEFILE b/CODE/desktop/MAKEFILE index 7e71306..5806e7b 100644 --- a/CODE/desktop/MAKEFILE +++ b/CODE/desktop/MAKEFILE @@ -20,7 +20,7 @@ $(OUT): $(OBJECTS) linker.ld @mkdir -p $(dir $@) $(LD) $(LDFLAGS) -o $@ $(OBJECTS) -%.o: %.c +%.o: %.c ../tools/fat32_io.h $(CC) $(CFLAGS) -c $< -o $@ clean: diff --git a/CODE/desktop/compositor.c b/CODE/desktop/compositor.c index a178d86..f55ee19 100644 --- a/CODE/desktop/compositor.c +++ b/CODE/desktop/compositor.c @@ -188,7 +188,7 @@ static void redraw_all_fluent(void) { for (u64 x = 0; x < g_fb_w; x++) line[x] = srcline[x]; } } else { - du_fill_bg_gradient(&g_fb, 0xFF0A0E1Cu, 0xFF16264Au); + du_fill_bg_gradient(&g_fb, 0xFFE9ECF0u, 0xFFF3F4F6u); } } diff --git a/CODE/desktop/launcher.c b/CODE/desktop/launcher.c index 352759a..a100125 100644 --- a/CODE/desktop/launcher.c +++ b/CODE/desktop/launcher.c @@ -342,7 +342,7 @@ void launch_pe_app(int app_id) { { u32 *p = (u32 *)g_pe_surf; u64 n = (u64)cw * (u64)ch; - for (u64 i = 0; i < n; i++) p[i] = 0xFF101418u; + for (u64 i = 0; i < n; i++) p[i] = 0xFFF3F4F6u; } win->app_state = &g_pe_state_dummy; /* draw_desktop_page 要求非空才调 on_draw */ diff --git a/CODE/desktop/lxc.c b/CODE/desktop/lxc.c index bafa07c..46068d3 100644 --- a/CODE/desktop/lxc.c +++ b/CODE/desktop/lxc.c @@ -385,7 +385,7 @@ void blit_scanout_to_ide(int hx, int hy, int hw, int hh) { const struct linux_compat_scanout_info *si = ide_scanout_state(); if (!si || !si->enabled || !si->host_vaddr) { /* scanout 未就绪:X server 尚未 SET_SCANOUT,显示等待提示 */ - du_fill_rect(&g_fb, hx, hy, hw, hh, 0xFF051828u); + du_fill_rect(&g_fb, hx, hy, hw, hh, KS_BG_SECONDARY); draw_centered("WAITING FOR GUEST X SERVER . . .", hx + hw / 2, hy + hh / 2 - 8, KS_TEXT_DIM, 0); return; @@ -433,9 +433,9 @@ void blit_scanout_to_ide(int hx, int hy, int hw, int hh) { int cov_w = (hw < sw) ? hw : sw; int cov_h = (hh < sh) ? hh : sh; if (cov_w < hw) - du_fill_rect(&g_fb, hx + cov_w, hy, hw - cov_w, cov_h, 0xFF051828u); + du_fill_rect(&g_fb, hx + cov_w, hy, hw - cov_w, cov_h, KS_BG_SECONDARY); if (cov_h < hh) - du_fill_rect(&g_fb, hx, hy + cov_h, hw, hh - cov_h, 0xFF051828u); + du_fill_rect(&g_fb, hx, hy + cov_h, hw, hh - cov_h, KS_BG_SECONDARY); } /* P7.6: 叠加 guest 硬件光标(ARGB alpha-blend 到 framebuffer)。 diff --git a/CODE/desktop/main.c b/CODE/desktop/main.c index 0ec9fe9..cedb116 100644 --- a/CODE/desktop/main.c +++ b/CODE/desktop/main.c @@ -7,6 +7,7 @@ * 原 "Winux-Kate 结构完整复刻" 布局说明见 pages.c 头注释; * M2-M4 将按 Win11 Fluent 桌面重构计划逐页替换。 */ +#include "ascii_font.h" /* 顺序敏感:先于 desktop.h(g_ascii 导出) */ #include "desktop.h" #include "zhfont.h" /* M1: 中文位图字库(dbf 加载 + 中英混排渲染) */ #include "wallpaper.h" /* M2: 壁纸背景层缓存 */ @@ -78,84 +79,89 @@ static void load_fuck_config(void) { } /* ============================================================ - * Boot 屏(打字机) + * 登录 → 桌面 crossfade(渐隐渐显) + * 登录最后一帧已在真实 fb 上;桌面首帧已由 redraw_all() 绘入 + * sprite buffer。复用 WALLPAPER_STAGING(wallpaper_init 后已空闲) + * 保存登录帧,按 alpha 混合 16 步直写真实 fb。 * ============================================================ */ -static const char *BOOT_LINES[] = { - "DESHAB DESKTOP v0.1.0", - "DEAICUP STUDIO && LINEHU STUDIO", - "https://deaicup.com", - "https://github.com/Linehu-Studio", -}; -#define BOOT_LINE_COUNT 4 +#define XFADE_ADDR WALLPAPER_STAGING_ADDR /* 8MB 区,init 后空闲 */ +#define XFADE_STEPS 16 static void busy_delay(u32 cycles) { for (volatile u32 i = 0; i < cycles; i++) __asm__("pause"); } -static void boot_screen(void) { +static void crossfade_login_to_desktop(void) { int W = (int)g_fb_w, H = (int)g_fb_h; + u32 *src = (u32 *)XFADE_ADDR; /* 登录帧 */ + const u32 *dst = (const u32 *)g_fb.fb; /* 桌面帧(sprite buffer) */ + u32 *out = (u32 *)g_real_fb; + u64 n = (u64)W * (u64)H; - /* M2 修复:保留 DSK 已绘制的启动画面(渐变背景 + 居中开机 Logo + - * dcp/xj 角标),boot 屏叠加在其上下空白区——logo 不跳位、不重复、 - * 不被覆盖。DSK logo 居中 157px:占据 H/2-78 .. H/2+78。 */ + /* 1. 保存登录最后一帧 */ { u64 pitch_u32 = g_fb_pitch / 4; for (u64 y = 0; y < g_fb_h; y++) { - const u32 *src = (const u32 *)((const u8 *)g_real_fb + y * g_fb_pitch); - u32 *dst = (u32 *)SPRITE_BUF_ADDR + y * pitch_u32; - for (u64 x = 0; x < g_fb_w; x++) dst[x] = src[x]; + const u32 *s = (const u32 *)((const u8 *)g_real_fb + y * g_fb_pitch); + u32 *d = (u32 *)((u8 *)src + y * (u64)W * 4); + for (u64 x = 0; x < g_fb_w; x++) d[x] = s[x]; } + (void)pitch_u32; } - int lw = 46 * (int)DU_ASCII_STEP; - int lx = (W - lw) / 2; - int ty = H / 2 - 220; + /* 2. 桌面首帧绘入 sprite buffer(由调用方 redraw_all() 完成后进入本函数) */ - /* boot-title(logo 上方空白区)——一次性整行绘制(打字机效果已删) */ - const char *title = "DESHAB"; - int tl = kstrlen(title); - du_draw_string(&g_fb, title, W / 2 - tl * (int)DU_ASCII_STEP, ty, - KS_ACCENT, 0, DU_ASCII_STEP * 2); - du_divider_h(&g_fb, W / 2 - 120, ty + 30, 240, KS_ACCENT); - - /* boot-subtitle(对应 Kate "由 Deaicup 工作室制作") */ - draw_centered("DEAICUP STUDIO", W / 2, ty + 44, KS_ACCENT2, 0); - - /* boot-lines(logo 下方空白区,H/2+110 起)——整屏一次绘制 */ - int ly = H / 2 + 110; - int bar_y = ly + BOOT_LINE_COUNT * ((int)DU_ASCII_LINE_H + 2) + 12; - int bw = 260; - for (int li = 0; li < BOOT_LINE_COUNT; li++) { - const char *s = BOOT_LINES[li]; - u32 fg = (li == 1 || li == BOOT_LINE_COUNT - 1) ? KS_TEXT_DIM : KS_ACCENT2; - du_draw_string(&g_fb, ">", lx, ly, KS_ACCENT, 0, DU_ASCII_STEP); - du_draw_string(&g_fb, s, lx + (int)DU_ASCII_STEP, ly, fg, 0, DU_ASCII_STEP); - ly += (int)DU_ASCII_LINE_H + 2; - /* boot-bar: 渐变填充(accent → accent2) */ - int fill = bw * (li + 1) / BOOT_LINE_COUNT; - du_rect_outline(&g_fb, W / 2 - bw / 2, bar_y, bw, 6, KS_BORDER, 1); - if (fill > 2) du_fill_rect_gradient(&g_fb, W / 2 - bw / 2 + 1, bar_y + 1, - fill - 2, 4, KS_ACCENT, KS_ACCENT2); + /* 3. alpha 混合直写真实 fb:out = src*(1-a) + dst*a */ + for (int step = 1; step <= XFADE_STEPS; step++) { + u32 a = (u32)(step * 256 / XFADE_STEPS); + u32 ia = 256 - a; + for (u64 i = 0; i < n; i++) { + u32 s = src[i], d = dst[i]; + u32 sr = (s >> 16) & 0xFF, sg = (s >> 8) & 0xFF, sb = s & 0xFF; + u32 dr = (d >> 16) & 0xFF, dg = (d >> 8) & 0xFF, db = d & 0xFF; + out[i] = 0xFF000000u | + (((sr * ia + dr * a) >> 8) << 16) | + (((sg * ia + dg * a) >> 8) << 8) | + ((sb * ia + db * a) >> 8); + } + busy_delay(40000); } - flip_buffer(); - - /* boot-hint + credit(对应 Kate "SYSTEM ONLINE" + "© 2026 Deaicup Studio") */ - draw_centered("SYSTEM ONLINE", W / 2, H - 64, KS_ACCENT2, 0); - draw_centered("(C) 2026 DEAICUP STUDIO", W / 2, H - 40, KS_TEXT_DIM, 0); - flip_buffer(); - busy_delay(10000000); } /* ============================================================ * 严格错误策略插桩(D 系列):错误不再降级,整屏 fatal + 错误码。 - * 每个插桩点唯一 symbol(DSK-E)。 + * 每个插桩点唯一 symbol(DESK-E)。 * ============================================================ */ static void desktop_fatal(const char *sym) { - /* 严格错误策略:任何错误不再降级,串口留档 + 停机。 - * (UI 层 fatal 屏由各 UI 组件就绪后的路径使用;此处不依赖任何子系统) */ + /* 严格错误策略:串口留档 + 深红 fatal 屏(ASCII 18px 直写真实 fb)+ 停机 */ slog(sym); + if (g_real_fb && g_fb_w && g_fb_h) { + u32 *fb = (u32 *)g_real_fb; + u64 pitch_u32 = g_fb_pitch / 4; + for (u64 y = 0; y < g_fb_h; y++) + for (u64 x = 0; x < g_fb_w; x++) + fb[y * pitch_u32 + x] = 0xFF3A0A0Au; /* 深红 */ + /* 居中绘制 symbol(ASCII 字符走 11x18 位图,其余跳过) */ + int len = 0; + while (sym[len]) len++; + int cw = 11, ch = 18; + int x0 = (int)(g_fb_w - (u64)len * cw) / 2; + int y0 = (int)g_fb_h / 2 - ch / 2; + for (int i = 0; i < len; i++) { + unsigned char c = (unsigned char)sym[i]; + if (c < 32 || c > 126) continue; + const unsigned char *g = g_ascii[c - 32]; + for (int py = 0; py < ch; py++) { + u32 *row = fb + (u64)(y0 + py) * pitch_u32; + for (int px = 0; px < cw; px++) { + if (g[py * cw + px]) + row[x0 + i * cw + px] = 0xFFF2F2F2u; /* 白 */ + } + } + } + } for (;;) __asm__("cli; hlt"); } @@ -220,8 +226,7 @@ void dsk_entry(const dsk_boot_context *ctx) { slog("[zhfont] dbf loaded (16px ok)"); } else { slog_num("[zhfont] dbf load failed rc=", zrc); - slog("[zhfont] CJK disabled (ASCII fallback)"); - for (;;) __asm__("hlt"); + desktop_fatal("DESK-E04 FONT PACK MISSING"); } } @@ -233,13 +238,16 @@ void dsk_entry(const dsk_boot_context *ctx) { slog("[wallpaper] loaded + scaled"); } else { slog_num("[wallpaper] load failed rc=", wrc); - slog("[wallpaper] gradient fallback"); + /* 严格错误策略:材质包(壁纸)缺失不降级,fatal 屏 + 错误码 */ + desktop_fatal("DESK-E02 TEXTURE PACK MISSING"); } /* M2: 开始菜单 logo(textures/startMenuLogo.rgba → 0x8700000) */ if (taskbar_init(f32_read_path_lfn_to_w) == 0) slog("[taskbar] startMenu logo loaded"); - else - slog("[taskbar] startMenu logo missing (glyph fallback)"); + else { + /* 严格错误策略:材质包(开始菜单 logo)缺失不降级 */ + desktop_fatal("DESK-E03 STARTMENU LOGO MISSING"); + } g_page = 3; /* Fluent 默认进 DESKTOP 页 */ } @@ -278,11 +286,11 @@ void dsk_entry(const dsk_boot_context *ctx) { files_refresh(); - boot_screen(); + /* 桌面首帧绘入 sprite buffer,然后从登录帧渐隐渐显到桌面(无 boot 屏) */ + redraw_all(); + crossfade_login_to_desktop(); g_booted = 1; - redraw_all(); - flip_buffer(); /* M2 修复:boot 后立即上屏,打字机残留清屏 */ slog("desktop ready"); desktop_launch_pending_native(); diff --git a/CODE/desktop/pages.c b/CODE/desktop/pages.c index 74f4859..2a97f62 100644 --- a/CODE/desktop/pages.c +++ b/CODE/desktop/pages.c @@ -14,7 +14,7 @@ void draw_topbar(void) { int W = (int)g_fb_w; du_fill_rect_gradient(&g_fb, 0, 0, W, KATE_TOPBAR_H, - 0xFF0A2840u, KS_BG_PRIMARY); + 0xFFFFFFFFu, KS_BG_PRIMARY); du_divider_h(&g_fb, 0, KATE_TOPBAR_H, W, KS_BORDER); int x = 12; @@ -180,7 +180,7 @@ static void draw_slider(int x, int y, int w, int val, int rect_out[4]) { static void draw_statusbar_full(void) { int W = (int)g_fb_w; int y = (int)g_fb_h - KATE_STATUSBAR_H; - du_fill_rect(&g_fb, 0, y, W, KATE_STATUSBAR_H, 0xFF051828u); + du_fill_rect(&g_fb, 0, y, W, KATE_STATUSBAR_H, KS_BG_SECONDARY); du_divider_h(&g_fb, 0, y, W, KS_BORDER); int x = 12; @@ -420,7 +420,7 @@ void draw_ide(void) { int top = KATE_TOPBAR_H; /* ide-tabs(36px):dot + 实例标签 + "+ NEW IDE" + ide-hint(Kate 结构) */ - du_fill_rect(&g_fb, 0, top, W, 36, 0xFF051828u); + du_fill_rect(&g_fb, 0, top, W, 36, KS_BG_SECONDARY); du_divider_h(&g_fb, 0, top + 36, W, KS_BORDER); int x = 12; int ty = top + (36 - (int)DU_ASCII_LINE_H) / 2 + 1; @@ -507,7 +507,7 @@ void draw_ide(void) { blit_scanout_to_ide(hx + 2, hy + 2, hw - 4, hh - 4); } else { /* P8.1: 启动中--显示分阶段状态 + 详细信息 */ - du_fill_rect(&g_fb, hx + 2, hy + 2, hw - 4, hh - 4, 0xFF051828u); + du_fill_rect(&g_fb, hx + 2, hy + 2, hw - 4, hh - 4, KS_BG_SECONDARY); draw_centered(g_launch_status[0] ? g_launch_status : "STARTING VSCODE . . .", W / 2, hy + hh / 2 - 20, KS_TEXT_DIM, 0); @@ -598,7 +598,7 @@ void draw_desktop_page(void) { int W = (int)g_fb_w; int tb_y = (int)g_fb_h - KATE_TASKBAR_H; du_fill_rect_gradient(&g_fb, 0, tb_y, W, KATE_TASKBAR_H, - 0xFF0A2840u, KS_BG_PRIMARY); + 0xFFFFFFFFu, KS_BG_PRIMARY); du_divider_h(&g_fb, 0, tb_y, W, KS_BORDER); int x = 8; @@ -683,7 +683,7 @@ void draw_custom_page(int cp_idx) { cpage *cp = &g_cpages[cp_idx]; /* ide-tabs 栏(36px):dot + 页名 + "+ NEW INSTANCE" + ide-hint(Kate 结构) */ - du_fill_rect(&g_fb, 0, top, W, 36, 0xFF051828u); + du_fill_rect(&g_fb, 0, top, W, 36, KS_BG_SECONDARY); du_divider_h(&g_fb, 0, top + 36, W, KS_BORDER); int ty = top + (36 - (int)DU_ASCII_LINE_H) / 2 + 1; @@ -836,7 +836,7 @@ void draw_ctx_menu(void) { g_ctx_rect[0] = x; g_ctx_rect[1] = y; g_ctx_rect[2] = mw; g_ctx_rect[3] = mh; - du_fill_rect(&g_fb, x, y, mw, mh, 0xFF050A18u); + du_fill_rect(&g_fb, x, y, mw, mh, KS_BG_SECONDARY); du_rect_outline(&g_fb, x, y, mw, mh, KS_ACCENT, 1); du_kate_glow_border(&g_fb, x, y, mw, mh, KS_ACCENT); diff --git a/CODE/desktop/shell.c b/CODE/desktop/shell.c index cc650ca..dc82947 100644 --- a/CODE/desktop/shell.c +++ b/CODE/desktop/shell.c @@ -482,6 +482,17 @@ int handle_key(u8 sc) { if (sc == 0x01) { if (g_taskview) { g_taskview = 0; return 1; } if (g_ctx_open) { g_ctx_open = 0; return 1; } + /* IDE 页:Esc = detach + 退回桌面页(IDE 退出通道) */ + if (g_page == 2) { + if (g_ide_attached) { + g_ide_attached = 0; + g_input_forward_enabled = 0; + ide_attach_invalidate(); + slog("ide detached (esc), input forwarding off"); + } + page_switch(3); + return 1; + } return 0; } if (g_taskview || g_ctx_open) return 0; /* 模态期间吞掉按键 */ diff --git a/CODE/desktop/taskbar.c b/CODE/desktop/taskbar.c index 4fba6fd..bde0c0f 100644 --- a/CODE/desktop/taskbar.c +++ b/CODE/desktop/taskbar.c @@ -32,7 +32,7 @@ int g_tb2_clk_rect[4]; #define TB_APPBTN 44 /* 应用钮边长 */ #define TB_PAD 8 /* 条内边距 */ -static const wf_theme *tb_theme(void) { return &g_wf_dark; } +static const wf_theme *tb_theme(void) { return &g_wf_light; } /* ---- 开始菜单 logo(textures/startMenuLogo.rgba,加载失败回退字形) ---- */ static int g_smlogo_ok = 0; @@ -151,8 +151,8 @@ void taskbar_draw(void) { g_tb2_app_rect[i][0] = x; g_tb2_app_rect[i][1] = byy; g_tb2_app_rect[i][2] = TB_APPBTN; g_tb2_app_rect[i][3] = TB_APPBTN; wf_btn_state st = tb_hover_state(g_tb2_app_rect[i]); - if (w->focused) du_wf_overlay(&g_fb, x, byy, TB_APPBTN, TB_APPBTN, 0x22FFFFFFu); - else if (st == WF_BTN_HOVER) du_wf_overlay(&g_fb, x, byy, TB_APPBTN, TB_APPBTN, 0x22FFFFFFu); + if (w->focused) du_wf_overlay(&g_fb, x, byy, TB_APPBTN, TB_APPBTN, 0x22000000u); + else if (st == WF_BTN_HOVER) du_wf_overlay(&g_fb, x, byy, TB_APPBTN, TB_APPBTN, 0x22000000u); du_wf_icon(&g_fb, tb_app_icon(w->app_id), x + (TB_APPBTN - 22) / 2, byy + (TB_APPBTN - 22) / 2, 22, t->text_primary); /* 运行指示条:底部 accent,聚焦加宽 */ diff --git a/CODE/desktop/wm.c b/CODE/desktop/wm.c index 358f86b..6048c70 100644 --- a/CODE/desktop/wm.c +++ b/CODE/desktop/wm.c @@ -250,7 +250,7 @@ void draw_window_frame(desktop_window *w) { du_fill_rounded_rect(&g_fb, w->x, w->y, w->w, w->h, KS_BG_SECONDARY, 2); du_fill_rect_gradient(&g_fb, w->x + 1, w->y + 1, w->w - 2, KATE_TITLEBAR_H - 1, - 0xFF0A3050u, KS_BG_SECONDARY); + KS_BG_TERTIARY, KS_BG_SECONDARY); du_divider_h(&g_fb, w->x, w->y + KATE_TITLEBAR_H, w->w, KS_BORDER); du_fill_rect(&g_fb, w->x + 6, w->y + KATE_TITLEBAR_H / 2 - 2, 4, 4, KS_ACCENT2); @@ -258,7 +258,7 @@ void draw_window_frame(desktop_window *w) { du_draw_string(&g_fb, w->title, w->x + 14, w->y + (KATE_TITLEBAR_H - (i64)DU_ASCII_LINE_H) / 2 + 1, - KS_ACCENT, 0xFF0A3050u, DU_ASCII_STEP); + KS_ACCENT, KS_BG_SECONDARY, DU_ASCII_STEP); int bx = w->x + w->w - CLOSE_BTN_OFFSET; int by = w->y + (KATE_TITLEBAR_H - CLOSE_BTN_SIZE) / 2; diff --git a/CODE/tools/fat32_io.h b/CODE/tools/fat32_io.h index 0613b53..aa03360 100644 --- a/CODE/tools/fat32_io.h +++ b/CODE/tools/fat32_io.h @@ -789,8 +789,18 @@ static inline int f32_read_file_by_clus(u32 clus, u32 size, u8 *out_buf, u32 buf for (u32 b = 0; b < fc_bytes; b++) dst[b] = fb[b]; dst += fc_bytes; remaining -= fc_bytes; u32 fo = fat_byte_off + fc * 4; - if (fo + 4 > sizeof(f32_disk)) break; - fc = f32_r32(f32_disk + fo) & 0x0FFFFFFF; + if (fo + 4 <= sizeof(f32_disk)) { + fc = f32_r32(f32_disk + fo) & 0x0FFFFFFF; + } else { + /* BUG-031 修复:FAT 超出 128KB 预读缓冲(sidecar FAT ~2.1MB)。 + * 旧逻辑直接越界读 f32_disk 尾部得到垃圾簇号,链路走飞导致 + * 大文件(字库/壁纸)第二簇起数据损坏。按需读取单 FAT 扇区 + * (fo 为相对 LBA0 的字节偏移,直接换算扇区号)。 */ + u8 fat_sec[512]; + if (f32_read_sectors(fo / 512, 1, fat_sec) != 0) + return -7; + fc = f32_r32(fat_sec + (fo % 512)) & 0x0FFFFFFF; + } } return 0; } diff --git a/SYSTEM/system/deshab64/desktop.elf b/SYSTEM/system/deshab64/desktop.elf index 358f122..a2a8cd1 100755 Binary files a/SYSTEM/system/deshab64/desktop.elf and b/SYSTEM/system/deshab64/desktop.elf differ diff --git a/SYSTEM/system/deshab64/desktop/textures/startMenuLogo.rgba b/SYSTEM/system/deshab64/desktop/textures/startMenuLogo.rgba new file mode 100644 index 0000000..449d0d6 Binary files /dev/null and b/SYSTEM/system/deshab64/desktop/textures/startMenuLogo.rgba differ diff --git a/build.ps1 b/build.ps1 index 2f10a9a..23ea8b5 100644 --- a/build.ps1 +++ b/build.ps1 @@ -759,6 +759,40 @@ if (Test-Path $PanicLogoPng) { } else { Write-Host '[build] WARNING: ohMyLogo.png not found (panic screen keeps embedded data)' } + +# Generate desktop textures (PNG/webP -> raw RGBA for the desktop material pack) +$GenTex = Join-Path $Root 'CODE\desktop\gen_textures.py' +if (Test-Path $GenTex) { + $TexSrc = Join-Path $Root 'SYSTEM\system\deshab64\desktop\textures\startMenuLogo.png' + $TexStamp = Join-Path $Root 'SYSTEM\system\deshab64\desktop\textures\startMenuLogo.rgba' + $needTex = -not (Test-Path $TexStamp) + if ($needTex -and (Test-Path $TexSrc)) { + $needTex = (Get-Item $TexSrc).LastWriteTime -gt (Get-Item $TexStamp).LastWriteTime + } + if ($needTex) { + Write-Host '[build] Generating desktop textures (gen_textures.py)...' + $texDone = $false + $Python = $null + foreach ($p in @('C:\Users\林濬哲\AppData\Local\Programs\Python\Python312\python.exe', + 'C:\msys64\mingw64\bin\python.exe', + 'python', 'python3')) { + try { $cmd = Get-Command $p -ErrorAction Stop; $Python = $cmd.Source; break } catch {} + } + if ($Python) { + & $Python $GenTex + if ($LASTEXITCODE -eq 0) { $texDone = $true } + } + if (-not $texDone) { + # Fallback: WSL python3 (has Pillow on this machine) + $wslPath = ($GenTex -replace '^([A-Za-z]):', '/mnt/$1').ToLower() + & wsl python3 $wslPath + if ($LASTEXITCODE -eq 0) { $texDone = $true } + } + if (-not $texDone) { + Write-Host '[build] WARNING: desktop texture generation failed (material pack may be incomplete)' + } + } +} try { & $make -C "$DskDir" -f MAKEFILE "CC=$clang" "LD=$lld" if ($LASTEXITCODE -ne 0) {