using XFESystem.Branding; namespace XFESystem.NativeKernel; public static unsafe class Framebuffer { public static byte* Address; public static uint Width, Height, Pitch; static byte _redShift, _greenShift, _blueShift; public static bool Ready; public static bool Initialize(LimineFramebuffer* source) { Ready = false; if (source == null || source->Address == null || source->BitsPerPixel != 32 || source->MemoryModel != 1 || source->Width == 0 || source->Height == 0 || source->Width > 16384 || source->Height > 16384 || source->Pitch < source->Width * 4 || source->Pitch > 1024 * 1024 || (source->Pitch & 3) != 0 || source->RedSize != 8 || source->GreenSize != 8 || source->BlueSize != 8 || source->RedShift > 24 || source->GreenShift > 24 || source->BlueShift > 24) return false; uint red = 255u << source->RedShift, green = 255u << source->GreenShift, blue = 255u << source->BlueShift; if ((red & green) != 0 || (red & blue) != 0 || (green & blue) != 0 || (ulong)source->Address > ~0UL - source->Pitch * source->Height) return false; Address = source->Address; Width = (uint)source->Width; Height = (uint)source->Height; Pitch = (uint)source->Pitch; _redShift = source->RedShift; _greenShift = source->GreenShift; _blueShift = source->BlueShift; Ready = true; return true; } public static uint Pack(uint rgb) => (((rgb >> 16) & 255) << _redShift) | (((rgb >> 8) & 255) << _greenShift) | ((rgb & 255) << _blueShift); public static void Pixel(int x, int y, uint rgb) { if (Ready && x >= 0 && y >= 0 && (uint)x < Width && (uint)y < Height) *(uint*)(Address + (ulong)(uint)y * Pitch + (ulong)(uint)x * 4) = Pack(rgb); } public static void Rectangle(int x, int y, int width, int height, uint rgb) { if (!Ready || width <= 0 || height <= 0) return; long right = (long)x + width, bottom = (long)y + height; if (right <= 0 || bottom <= 0 || x >= (long)Width || y >= (long)Height) return; int left = x < 0 ? 0 : x, top = y < 0 ? 0 : y; int r = right > Width ? (int)Width : (int)right, b = bottom > Height ? (int)Height : (int)bottom; uint color = Pack(rgb); for (int py = top; py < b; py++) { uint* row = (uint*)(Address + (ulong)(uint)py * Pitch); for (int px = left; px < r; px++) row[px] = color; } } public static void Fill(uint rgb) => Rectangle(0, 0, (int)Width, (int)Height, rgb); public static void BootStage(uint stage, bool failure = false) { if (!Ready) return; if (failure) BootSplash.Blackout(); // Boot diagnostics belong to serial. There are no progress strips, // stage numbers or error text on the user's display. Native.MemoryBarrier(); } public static void PaintBoot(uint* backbuffer, ulong elapsedMilliseconds, bool waiting) { if (!Ready || backbuffer == null) return; BootVisual.Draw(backbuffer, (int)Width, (int)Height, (int)Width, elapsedMilliseconds, waiting, _redShift, _greenShift, _blueShift); // Never erase the visible logo to construct its next frame. Copy only // the complete dirty region; firmware pitch padding remains untouched. int size = BootVisual.LogoSize((int)Width, (int)Height), cx = (int)Width / 2; int top = BootVisual.CenterY((int)Height) - size - 12; int bottom = BootVisual.LoaderY((int)Width, (int)Height) + 32; Native.MemoryBarrier(); for (int y = top < 0 ? 0 : top; y < bottom && y < Height; y++) { uint* output = (uint*)(Address + (ulong)(uint)y * Pitch); uint* input = backbuffer + (ulong)(uint)y * Width; for (int x = cx - size - 12; x <= cx + size + 12; x++) if (x >= 0 && x < Width) output[x] = input[x]; } Native.MemoryBarrier(); } public static bool SelfTest() { if (!Ready) return false; uint* first = (uint*)Address; uint saved = *first; Pixel(0, 0, 0x2ea8df); Native.MemoryBarrier(); bool result = *first == Pack(0x2ea8df); *first = saved; Native.MemoryBarrier(); return result; } }