Files

80 lines
3.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* wallpaper.c — 壁纸背景层缓存实现(M2:磁盘加载版)
*
* 流程:FAT32 流式读桌面材质包 textures/back.rgba(889×500 RGBA 字节流)
* → WALLPAPER_STAGING_ADDR 暂存 → 双线性缩放(对齐像素中心,8.8 定点)
* → WALLPAPER_ADDR 背景层缓存。
* 数组字节序 R,G,B,A;framebuffer u32 = 0xAARRGGBB(R 在 bit16)。 */
#include "wallpaper.h"
/* 材质包 back.rgba 尺寸(与 gen_textures.py 的 back 889×500 一致;运行时按文件大小校验) */
#define WP_SRC_W 889
#define WP_SRC_H 500
static wp_u32 *g_wp_layer = 0;
static int g_wp_w = 0, g_wp_h = 0;
static wp_u32 g_wp_src_w = WP_SRC_W, g_wp_src_h = WP_SRC_H;
int wallpaper_init(wallpaper_read_fn read_to, int fb_w, int fb_h) {
if (!read_to || fb_w <= 0 || fb_h <= 0) return -1;
if ((wp_u64)fb_w * (wp_u64)fb_h * 4u > WALLPAPER_MAX) return -2;
/* 1. 流式读原始 RGBA 到暂存区(PE surface 区,启动期独占) */
wp_u32 src_total = g_wp_src_w * g_wp_src_h * 4u;
if (src_total > WALLPAPER_STAGING_MAX) return -3;
wp_u32 got = 0;
if (read_to("system/deshab64/desktop/textures/back.rgba",
(wp_u8 *)WALLPAPER_STAGING_ADDR, src_total, &got) != 0)
return -4;
if (got < src_total) {
/* 文件比预期小:按实际行数截断(防御,正常部署不会发生) */
if (got < g_wp_src_w * 4u) return -5;
g_wp_src_h = got / (g_wp_src_w * 4u);
}
const wp_u8 *src = (const wp_u8 *)WALLPAPER_STAGING_ADDR;
/* 2. 双线性缩放到背景层缓存 */
g_wp_layer = (wp_u32 *)WALLPAPER_ADDR;
g_wp_w = fb_w;
g_wp_h = fb_h;
int sw = (int)g_wp_src_w, sh = (int)g_wp_src_h;
for (int y = 0; y < fb_h; y++) {
wp_i64 fy64 = ((wp_i64)y * sh << 8) / fb_h; /* 8.8 定点 */
int sy0 = (int)(fy64 >> 8);
int fy = (int)(fy64 & 0xFF);
int sy1 = (sy0 + 1 < sh) ? sy0 + 1 : sy0;
if (sy0 >= sh) sy0 = sy1 = sh - 1;
for (int x = 0; x < fb_w; x++) {
wp_i64 fx64 = ((wp_i64)x * sw << 8) / fb_w;
int sx0 = (int)(fx64 >> 8);
int fx = (int)(fx64 & 0xFF);
int sx1 = (sx0 + 1 < sw) ? sx0 + 1 : sx0;
if (sx0 >= sw) sx0 = sx1 = sw - 1;
const wp_u8 *p00 = src + ((wp_i64)sy0 * sw + sx0) * 4;
const wp_u8 *p10 = src + ((wp_i64)sy0 * sw + sx1) * 4;
const wp_u8 *p01 = src + ((wp_i64)sy1 * sw + sx0) * 4;
const wp_u8 *p11 = src + ((wp_i64)sy1 * sw + sx1) * 4;
wp_u32 r, g, b;
{
wp_u32 rtop = ((wp_u32)p00[0] * (256 - fx) + (wp_u32)p10[0] * fx) >> 8;
wp_u32 rbot = ((wp_u32)p01[0] * (256 - fx) + (wp_u32)p11[0] * fx) >> 8;
wp_u32 gtop = ((wp_u32)p00[1] * (256 - fx) + (wp_u32)p10[1] * fx) >> 8;
wp_u32 gbot = ((wp_u32)p01[1] * (256 - fx) + (wp_u32)p11[1] * fx) >> 8;
wp_u32 btop = ((wp_u32)p00[2] * (256 - fx) + (wp_u32)p10[2] * fx) >> 8;
wp_u32 bbot = ((wp_u32)p01[2] * (256 - fx) + (wp_u32)p11[2] * fx) >> 8;
r = (rtop * (256 - fy) + rbot * fy) >> 8;
g = (gtop * (256 - fy) + gbot * fy) >> 8;
b = (btop * (256 - fy) + bbot * fy) >> 8;
}
g_wp_layer[(wp_i64)y * fb_w + x] =
0xFF000000u | (r << 16) | (g << 8) | b;
}
}
return 0;
}
wp_u32 *wallpaper_layer(void) {
return g_wp_layer;
}