Files

77 lines
3.3 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.
/* textures.c — 裸 RGBA 纹理绘制实现(M2)
*
* 数组字节序 R,G,B,A;framebuffer u32 = 0xAARRGGBB。
* 双线性插值(像素中心对齐,8.8 定点)+ src-over alpha。
*/
#include "ascii_font.h" /* 顺序敏感:必须先于 textures.h(deshab_ui.h 需 g_ascii) */
#include "textures.h"
void tex_draw_scaled(du_context *ctx, const tex_u8 *rgba, int sw, int sh,
int x, int y, int w, int h, int dim) {
if (!ctx || !rgba || sw <= 0 || sh <= 0 || w <= 0 || h <= 0) return;
if (dim < 0) dim = 0;
if (dim > 256) dim = 256;
int fw = (int)ctx->width, fh = (int)ctx->height;
tex_u32 *fb = ctx->fb;
tex_i64 pitch = (tex_i64)ctx->pitch / 4; /* u32 单位 */
for (int dy = 0; dy < h; dy++) {
int py = y + dy;
if (py < 0 || py >= fh) continue;
tex_i64 fy64 = ((tex_i64)dy * sh << 8) / h;
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;
tex_u32 *dline = fb + (tex_i64)py * pitch;
for (int dx = 0; dx < w; dx++) {
int px = x + dx;
if (px < 0 || px >= fw) continue;
tex_i64 fx64 = ((tex_i64)dx * sw << 8) / 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 tex_u8 *p00 = rgba + ((tex_i64)sy0 * sw + sx0) * 4;
const tex_u8 *p10 = rgba + ((tex_i64)sy0 * sw + sx1) * 4;
const tex_u8 *p01 = rgba + ((tex_i64)sy1 * sw + sx0) * 4;
const tex_u8 *p11 = rgba + ((tex_i64)sy1 * sw + sx1) * 4;
tex_u32 a, r, g, b;
{
tex_u32 rtop = ((tex_u32)p00[0] * (256 - fx) + (tex_u32)p10[0] * fx) >> 8;
tex_u32 rbot = ((tex_u32)p01[0] * (256 - fx) + (tex_u32)p11[0] * fx) >> 8;
tex_u32 gtop = ((tex_u32)p00[1] * (256 - fx) + (tex_u32)p10[1] * fx) >> 8;
tex_u32 gbot = ((tex_u32)p01[1] * (256 - fx) + (tex_u32)p11[1] * fx) >> 8;
tex_u32 btop = ((tex_u32)p00[2] * (256 - fx) + (tex_u32)p10[2] * fx) >> 8;
tex_u32 bbot = ((tex_u32)p01[2] * (256 - fx) + (tex_u32)p11[2] * fx) >> 8;
tex_u32 atop = ((tex_u32)p00[3] * (256 - fx) + (tex_u32)p10[3] * fx) >> 8;
tex_u32 abot = ((tex_u32)p01[3] * (256 - fx) + (tex_u32)p11[3] * fx) >> 8;
r = (rtop * (256 - fy) + rbot * fy) >> 8;
g = (gtop * (256 - fy) + gbot * fy) >> 8;
b = (btop * (256 - fy) + bbot * fy) >> 8;
a = (atop * (256 - fy) + abot * fy) >> 8;
}
if (a == 0) continue;
/* 亮度衰减(boot 背景) */
r = r * dim >> 8; g = g * dim >> 8; b = b * dim >> 8;
tex_u32 dst = dline[px];
if (a >= 255) {
dline[px] = 0xFF000000u | (r << 16) | (g << 8) | b;
} else {
tex_u32 dr = (dst >> 16) & 0xFF, dg = (dst >> 8) & 0xFF, db = dst & 0xFF;
tex_u32 na = 255 - a;
dline[px] = 0xFF000000u |
(((r * a + dr * na) >> 8) << 16) |
(((g * a + dg * na) >> 8) << 8) |
((b * a + db * na) >> 8);
}
}
}
}