fix: sync template sysroot, add script

This commit is contained in:
2026-06-12 11:56:20 +02:00
parent 22691c5c17
commit 44f86a8b19
33 changed files with 5172 additions and 147 deletions
+99 -31
View File
@@ -19,6 +19,46 @@ class Framebuffer {
int fb_height;
int fb_pitch; // in bytes
static inline void fill_pixels(uint32_t* dst, int count, uint32_t pixel) {
if (!dst || count <= 0) return;
uint64_t pixel64 = ((uint64_t)pixel << 32) | pixel;
if (((uint64_t)dst & 4) && count > 0) {
*dst++ = pixel;
count--;
}
uint64_t* dst64 = (uint64_t*)dst;
int pairs = count / 2;
for (int i = 0; i < pairs; i++) {
dst64[i] = pixel64;
}
if (count & 1) {
((uint32_t*)(dst64 + pairs))[0] = pixel;
}
}
static inline uint32_t blend_pixel(uint32_t dst, uint32_t src, uint32_t alpha) {
uint32_t inv_a = 255 - alpha;
uint32_t sr = (src >> 16) & 0xFF;
uint32_t sg = (src >> 8) & 0xFF;
uint32_t sb = src & 0xFF;
uint32_t dr = (dst >> 16) & 0xFF;
uint32_t dg = (dst >> 8) & 0xFF;
uint32_t db = dst & 0xFF;
uint32_t rr = alpha * sr + inv_a * dr;
uint32_t gg = alpha * sg + inv_a * dg;
uint32_t bb = alpha * sb + inv_a * db;
rr = (rr + 1 + (rr >> 8)) >> 8;
gg = (gg + 1 + (gg >> 8)) >> 8;
bb = (bb + 1 + (bb >> 8)) >> 8;
return 0xFF000000 | (rr << 16) | (gg << 8) | bb;
}
public:
Framebuffer() : hw_fb(nullptr), back_buf(nullptr), fb_width(0), fb_height(0), fb_pitch(0) {
Montauk::FbInfo info;
@@ -76,6 +116,8 @@ public:
}
inline void fill_rect(int x, int y, int w, int h, Color c) {
if (!back_buf) return;
// Clip to screen bounds
int x0 = x < 0 ? 0 : x;
int y0 = y < 0 ? 0 : y;
@@ -89,9 +131,7 @@ public:
for (int row = y0; row < y1; row++) {
uint32_t* dst = (uint32_t*)((uint8_t*)back_buf + row * fb_pitch) + x0;
for (int col = 0; col < clipped_w; col++) {
dst[col] = pixel;
}
fill_pixels(dst, clipped_w, pixel);
}
}
@@ -137,56 +177,84 @@ public:
}
inline void blit(int x, int y, int w, int h, const uint32_t* pixels) {
for (int row = 0; row < h; row++) {
int dy = y + row;
if (dy < 0 || dy >= fb_height) continue;
for (int col = 0; col < w; col++) {
int dx = x + col;
if (dx < 0 || dx >= fb_width) continue;
uint32_t* dst_row = (uint32_t*)((uint8_t*)back_buf + dy * fb_pitch);
dst_row[dx] = pixels[row * w + col];
}
if (!back_buf || !pixels || w <= 0 || h <= 0) return;
int src_x = 0;
int src_y = 0;
int dst_x = x;
int dst_y = y;
int copy_w = w;
int copy_h = h;
if (dst_x < 0) { src_x = -dst_x; copy_w += dst_x; dst_x = 0; }
if (dst_y < 0) { src_y = -dst_y; copy_h += dst_y; dst_y = 0; }
if (dst_x + copy_w > fb_width) copy_w = fb_width - dst_x;
if (dst_y + copy_h > fb_height) copy_h = fb_height - dst_y;
if (copy_w <= 0 || copy_h <= 0) return;
uint64_t row_bytes = (uint64_t)copy_w * sizeof(uint32_t);
for (int row = 0; row < copy_h; row++) {
uint32_t* dst = (uint32_t*)((uint8_t*)back_buf + (dst_y + row) * fb_pitch) + dst_x;
const uint32_t* src = pixels + (src_y + row) * w + src_x;
montauk::memcpy(dst, src, row_bytes);
}
}
inline void blit_alpha(int x, int y, int w, int h, const uint32_t* pixels) {
for (int row = 0; row < h; row++) {
int dy = y + row;
if (dy < 0 || dy >= fb_height) continue;
for (int col = 0; col < w; col++) {
int dx = x + col;
if (dx < 0 || dx >= fb_width) continue;
if (!back_buf || !pixels || w <= 0 || h <= 0) return;
uint32_t src = pixels[row * w + col];
uint8_t sa = (src >> 24) & 0xFF;
int src_x = 0;
int src_y = 0;
int dst_x = x;
int dst_y = y;
int copy_w = w;
int copy_h = h;
if (dst_x < 0) { src_x = -dst_x; copy_w += dst_x; dst_x = 0; }
if (dst_y < 0) { src_y = -dst_y; copy_h += dst_y; dst_y = 0; }
if (dst_x + copy_w > fb_width) copy_w = fb_width - dst_x;
if (dst_y + copy_h > fb_height) copy_h = fb_height - dst_y;
if (copy_w <= 0 || copy_h <= 0) return;
for (int row = 0; row < copy_h; row++) {
uint32_t* dst = (uint32_t*)((uint8_t*)back_buf + (dst_y + row) * fb_pitch) + dst_x;
const uint32_t* src = pixels + (src_y + row) * w + src_x;
for (int col = 0; col < copy_w; col++) {
uint32_t s = src[col];
uint8_t sa = (s >> 24) & 0xFF;
if (sa == 0) continue;
uint8_t sr = (src >> 16) & 0xFF;
uint8_t sg = (src >> 8) & 0xFF;
uint8_t sb = src & 0xFF;
if (sa == 255) {
uint32_t* dst_row = (uint32_t*)((uint8_t*)back_buf + dy * fb_pitch);
dst_row[dx] = src;
dst[col] = s;
continue;
}
Color sc = {sr, sg, sb, sa};
put_pixel_alpha(dx, dy, sc);
dst[col] = blend_pixel(dst[col], s, sa);
}
}
}
inline void copy_from(const uint32_t* pixels, int src_pitch_bytes) {
if (!back_buf || !pixels || src_pitch_bytes <= 0) return;
uint64_t row_bytes = (uint64_t)fb_width * sizeof(uint32_t);
for (int row = 0; row < fb_height; row++) {
uint32_t* dst = (uint32_t*)((uint8_t*)back_buf + row * fb_pitch);
const uint32_t* src = (const uint32_t*)((const uint8_t*)pixels + row * src_pitch_bytes);
montauk::memcpy(dst, src, row_bytes);
}
}
inline void clear(Color c) {
fill_rect(0, 0, fb_width, fb_height, c);
}
inline void flip() {
if (!hw_fb || !back_buf) return;
// Copy back buffer to hardware framebuffer, row by row (pitch may differ)
uint64_t row_bytes = (uint64_t)fb_width * sizeof(uint32_t);
for (int y = 0; y < fb_height; y++) {
void* src = (void*)((uint8_t*)back_buf + y * fb_pitch);
void* dst = (void*)((uint8_t*)hw_fb + y * fb_pitch);
uint32_t* src = (uint32_t*)((uint8_t*)back_buf + y * fb_pitch);
uint32_t* dst = (uint32_t*)((uint8_t*)hw_fb + y * fb_pitch);
montauk::memcpy(dst, src, row_bytes);
}
}