From 03a68ddd3959536d76a8c1bce515aae1cf6b5a27 Mon Sep 17 00:00:00 2001 From: "Chloe M." Date: Tue, 23 Jun 2026 02:55:38 +0000 Subject: [PATCH] stos: bootvid: Add boot splash blitter Signed-off-by: Chloe M. --- paw/stos/drivers/bootvid/fbio.c | 124 +++++++++++++++++++++++++++ paw/stos/head/drivers/bootvid/fbio.h | 4 + 2 files changed, 128 insertions(+) diff --git a/paw/stos/drivers/bootvid/fbio.c b/paw/stos/drivers/bootvid/fbio.c index a7407b8..8975aa5 100644 --- a/paw/stos/drivers/bootvid/fbio.c +++ b/paw/stos/drivers/bootvid/fbio.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "flanterm.h" #include "flanterm_backends/fb.h" @@ -28,6 +29,109 @@ static BOOTCONS_ATTR DefaultConsAttr = { .Background = DEFAULT_BG }; +/* + * Splash screen header + * + * @Width: Width of splash + * @Height: Height of splash + */ +typedef PACKED struct { + ULONG Width; + ULONG Height; +} SPLASH_HEADER; + +/* + * Pack RGB bits so it fits the framebuffer format + * + * @Red: Red value + * @Green: Green value + * @Blue: Blue value + */ +static inline ULONG +BootVidPackRgb(UCHAR Red, UCHAR Green, UCHAR Blue) +{ + return ((ULONG)Red << Framebuffer.RedMaskShift) + | ((ULONG)Green << Framebuffer.GreenMaskShift) + | ((ULONG)Blue << Framebuffer.BlueMaskShift); +} + +/* + * Blit the splash onto the screen + * + * @Fb: Framebuffer descriptor + * @Hdr: Splash header + * @FileSize: Splash file size + */ +static BOOLEAN +BlitSplash(BPAL_FRAMEBUFFER *Fb, SPLASH_HEADER *Hdr, USIZE FileSize) +{ + volatile ULONG *Row; + UCHAR *Pixels, *Base; + USIZE StartX, StartY; + USIZE SrcX, SrcY; + USIZE DrawW, DrawH; + USIZE PixelBytes; + ULONG Background; + USIZE ImgX, ImgY; + USIZE Off, Red; + UCHAR Green, Blue; + UCHAR Alpha; + + if (Hdr->Width == 0 || Hdr->Height == 0) { + return false; + } + + PixelBytes = (USIZE)Hdr->Width * (USIZE)Hdr->Height * 4; + if (FileSize < sizeof(SPLASH_HEADER) + PixelBytes) { + return false; + } + + if (Fb->Address == NULL || Fb->Pitch == 0) { + return false; + } + + Pixels = (UCHAR *)Hdr + sizeof(SPLASH_HEADER); + Base = Fb->Address; + + DrawW = Hdr->Width; + DrawH = Hdr->Height; + StartX = 0; + StartY = 0; + SrcX = 0; + SrcY = 0; + + if (DrawW < Fb->Width) { + StartX = (Fb->Width - DrawW) / 2; + } else if (DrawW > Fb->Width) { + SrcX = (DrawW - Fb->Width) / 2; + DrawW = Fb->Width; + } + + if (DrawH < Fb->Height) { + StartY = (Fb->Height - DrawH) / 2; + } else if (DrawH > Fb->Height) { + SrcY = (DrawH - Fb->Height) / 2; + DrawH = Fb->Height; + } + + /* Actually blit the splash */ + for (USIZE Y = 0; Y < DrawH; Y++) { + Row = (volatile ULONG *)(Base + ((StartY + Y) * Fb->Pitch)); + for (USIZE X = 0; X < DrawW; X++) { + ImgX = SrcX + X; + ImgY = SrcY + Y; + Off = (ImgY * Hdr->Width + ImgX) * 4; + Red = Pixels[Off + 0]; + Green = Pixels[Off + 1]; + Blue = Pixels[Off + 2]; + Alpha = Pixels[Off + 3]; + Row[StartX + X] = BootVidPackRgb(Red, Green, Blue); + } + } + + return true; +} + VOID BootVidInitCons(BOOTCONS_ATTR *Attr) { @@ -106,6 +210,26 @@ BootVidDeInitCons(VOID) BootConsEnabled = false; } +#include + +VOID +BootVidSplash(VOID) +{ + ST_STATUS Status; + EX_BPI_FILE File; + SPLASH_HEADER *Hdr; + + Status = ExPbiLookup("/boot/splash.rgba", &File); + if (Status != STATUS_SUCCESS) { + BootVidClear(DEFAULT_BG); + return; + } + + Hdr = File.Data; + if (!BlitSplash(&Framebuffer, Hdr, File.Size)) { + BootVidClear(DEFAULT_BG); + } +} VOID BootVidClear(ULONG Color) diff --git a/paw/stos/head/drivers/bootvid/fbio.h b/paw/stos/head/drivers/bootvid/fbio.h index b938a0d..c98381f 100644 --- a/paw/stos/head/drivers/bootvid/fbio.h +++ b/paw/stos/head/drivers/bootvid/fbio.h @@ -47,6 +47,10 @@ VOID BootVidDeInitCons(VOID); */ VOID BootVidConsWrite(const CHAR *String, USIZE Length); +/* + * Draw a splash screen + */ +VOID BootVidSplash(VOID); /* * Clear the screen with a background color