stos: bootvid: Add boot splash blitter
Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#include <drivers/bootvid/fbio.h>
|
#include <drivers/bootvid/fbio.h>
|
||||||
#include <ke/bpal.h>
|
#include <ke/bpal.h>
|
||||||
#include <ex/trace.h>
|
#include <ex/trace.h>
|
||||||
|
#include <ex/pbi.h>
|
||||||
#include <stdef.h>
|
#include <stdef.h>
|
||||||
#include "flanterm.h"
|
#include "flanterm.h"
|
||||||
#include "flanterm_backends/fb.h"
|
#include "flanterm_backends/fb.h"
|
||||||
@@ -28,6 +29,109 @@ static BOOTCONS_ATTR DefaultConsAttr = {
|
|||||||
.Background = DEFAULT_BG
|
.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
|
VOID
|
||||||
BootVidInitCons(BOOTCONS_ATTR *Attr)
|
BootVidInitCons(BOOTCONS_ATTR *Attr)
|
||||||
{
|
{
|
||||||
@@ -106,6 +210,26 @@ BootVidDeInitCons(VOID)
|
|||||||
BootConsEnabled = false;
|
BootConsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <ex/trace.h>
|
||||||
|
|
||||||
|
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
|
VOID
|
||||||
BootVidClear(ULONG Color)
|
BootVidClear(ULONG Color)
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ VOID BootVidDeInitCons(VOID);
|
|||||||
*/
|
*/
|
||||||
VOID BootVidConsWrite(const CHAR *String, USIZE Length);
|
VOID BootVidConsWrite(const CHAR *String, USIZE Length);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw a splash screen
|
||||||
|
*/
|
||||||
|
VOID BootVidSplash(VOID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the screen with a background color
|
* Clear the screen with a background color
|
||||||
|
|||||||
Reference in New Issue
Block a user