[NTOS:INBV] Implement BitBltPalette() and BitBltAligned() and use them for aligning bitmaps. (#1649)

Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
This commit is contained in:
Yaroslav Kibysh 2019-06-11 22:27:25 +03:00 committed by Hermès Bélusca-Maïto
parent 3625238ecb
commit dc2eb409c1
No known key found for this signature in database
GPG Key ID: 3B2539C65E7B93D0

View File

@ -5,6 +5,10 @@
#include <debug.h>
#include "bootvid/bootvid.h"
/* See also mm/ARM3/miarm.h */
#define MM_READONLY 1 // PAGE_READONLY
#define MM_READWRITE 4 // PAGE_WRITECOPY
#ifndef TAG_OSTR
#define TAG_OSTR 'RTSO'
#endif
@ -28,6 +32,29 @@
*/
// #define REACTOS_SKUS
/*
* Screen resolution (for default VGA)
*/
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
/*
* BitBltAligned() alignments
*/
typedef enum _BBLT_VERT_ALIGNMENT
{
AL_VERTICAL_TOP = 0,
AL_VERTICAL_CENTER,
AL_VERTICAL_BOTTOM
} BBLT_VERT_ALIGNMENT;
typedef enum _BBLT_HORZ_ALIGNMENT
{
AL_HORIZONTAL_LEFT = 0,
AL_HORIZONTAL_CENTER,
AL_HORIZONTAL_RIGHT
} BBLT_HORZ_ALIGNMENT;
/*
* Enable this define when Inbv will support rotating progress bar.
*/
@ -210,6 +237,96 @@ BootLogoFadeIn(VOID)
}
}
static VOID
BitBltPalette(
IN PVOID Image,
IN BOOLEAN NoPalette,
IN ULONG X,
IN ULONG Y)
{
LPRGBQUAD Palette;
RGBQUAD OrigPalette[RTL_NUMBER_OF(MainPalette)];
/* If requested, remove the palette from the image */
if (NoPalette)
{
/* Get bitmap header and palette */
PBITMAPINFOHEADER BitmapInfoHeader = Image;
Palette = (LPRGBQUAD)((PUCHAR)Image + BitmapInfoHeader->biSize);
/* Save the image original palette and remove palette information */
RtlCopyMemory(OrigPalette, Palette, sizeof(OrigPalette));
RtlZeroMemory(Palette, sizeof(OrigPalette));
}
/* Draw the image */
InbvBitBlt(Image, X, Y);
/* Restore the image original palette */
if (NoPalette)
{
RtlCopyMemory(Palette, OrigPalette, sizeof(OrigPalette));
}
}
static VOID
BitBltAligned(
IN PVOID Image,
IN BOOLEAN NoPalette,
IN BBLT_HORZ_ALIGNMENT HorizontalAlignment,
IN BBLT_VERT_ALIGNMENT VerticalAlignment,
IN ULONG MarginLeft,
IN ULONG MarginTop,
IN ULONG MarginRight,
IN ULONG MarginBottom)
{
PBITMAPINFOHEADER BitmapInfoHeader = Image;
ULONG X, Y;
/* Calculate X */
switch (HorizontalAlignment)
{
case AL_HORIZONTAL_LEFT:
X = MarginLeft - MarginRight;
break;
case AL_HORIZONTAL_CENTER:
X = MarginLeft - MarginRight + (SCREEN_WIDTH - BitmapInfoHeader->biWidth + 1) / 2;
break;
case AL_HORIZONTAL_RIGHT:
X = MarginLeft - MarginRight + SCREEN_WIDTH - BitmapInfoHeader->biWidth;
break;
default:
/* Unknown */
return;
}
/* Calculate Y */
switch (VerticalAlignment)
{
case AL_VERTICAL_TOP:
Y = MarginTop - MarginBottom;
break;
case AL_VERTICAL_CENTER:
Y = MarginTop - MarginBottom + (SCREEN_HEIGHT - BitmapInfoHeader->biHeight + 1) / 2;
break;
case AL_VERTICAL_BOTTOM:
Y = MarginTop - MarginBottom + SCREEN_HEIGHT - BitmapInfoHeader->biHeight;
break;
default:
/* Unknown */
return;
}
/* Finally draw the image */
BitBltPalette(Image, NoPalette, X, Y);
}
/* FUNCTIONS *****************************************************************/
INIT_FUNCTION
@ -975,6 +1092,12 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
/* Check if this is text mode */
if (TextMode)
{
/*
* Make the kernel resource section temporarily writable,
* as we are going to change the bitmaps' palette in place.
*/
MmChangeKernelResourceSectionProtection(MM_READWRITE);
/* Check the type of the OS: workstation or server */
if (SharedUserData->NtProductType == NtProductWinNt)
{
@ -1006,15 +1129,32 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
if (Header && Footer)
{
/* BitBlt them on the screen */
InbvBitBlt(Footer, 0, 419);
InbvBitBlt(Header, 0, 0);
BitBltAligned(Footer,
TRUE,
AL_HORIZONTAL_CENTER,
AL_VERTICAL_BOTTOM,
0, 0, 0, 59);
BitBltAligned(Header,
FALSE,
AL_HORIZONTAL_CENTER,
AL_VERTICAL_TOP,
0, 0, 0, 0);
}
/* Restore the kernel resource section protection to be read-only */
MmChangeKernelResourceSectionProtection(MM_READONLY);
}
else
{
/* Is the boot driver installed? */
if (!InbvBootDriverInstalled) return;
/*
* Make the kernel resource section temporarily writable,
* as we are going to change the bitmaps' palette in place.
*/
MmChangeKernelResourceSectionProtection(MM_READWRITE);
/* Load the standard boot screen */
Screen = InbvGetResourceAddress(IDB_BOOT_SCREEN);
@ -1059,20 +1199,13 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
/* Make sure we have a logo */
if (Screen)
{
PBITMAPINFOHEADER BitmapInfoHeader;
LPRGBQUAD Palette;
/*
* Save the main image palette and replace it with black palette,
* so that we can do fade-in effect later.
*/
BitmapInfoHeader = (PBITMAPINFOHEADER)Screen;
Palette = (LPRGBQUAD)((PUCHAR)Screen + BitmapInfoHeader->biSize);
/* Save the main image palette for implementing the fade-in effect */
PBITMAPINFOHEADER BitmapInfoHeader = Screen;
LPRGBQUAD Palette = (LPRGBQUAD)((PUCHAR)Screen + BitmapInfoHeader->biSize);
RtlCopyMemory(MainPalette, Palette, sizeof(MainPalette));
RtlZeroMemory(Palette, sizeof(MainPalette));
/* Blit the background */
InbvBitBlt(Screen, 0, 0);
BitBltPalette(Screen, TRUE, 0, 0);
#ifdef INBV_ROTBAR_IMPLEMENTED
/* Choose progress bar */
@ -1099,7 +1232,7 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
#ifdef REACTOS_SKUS
/* Draw the SKU text if it exits */
if (Text) InbvBitBlt(Text, 180, 121);
if (Text) BitBltPalette(Text, TRUE, 180, 121);
#endif
#ifdef INBV_ROTBAR_IMPLEMENTED
@ -1126,7 +1259,7 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
if (LineBmp)
{
/* Draw the line and store it in global buffer */
InbvBitBlt(LineBmp, 0, 474);
BitBltPalette(LineBmp, TRUE, 0, 474);
InbvScreenToBufferBlt(RotLineBuffer, 0, 474, 640, 6, 640);
}
}
@ -1137,6 +1270,9 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
}
#endif
/* Restore the kernel resource section protection to be read-only */
MmChangeKernelResourceSectionProtection(MM_READONLY);
/* Display the boot logo and fade it in */
BootLogoFadeIn();
@ -1194,10 +1330,10 @@ DisplayFilter(PCHAR *String)
static BOOLEAN DotHack = TRUE;
/* If "." is given set *String to empty string */
if(DotHack && strcmp(*String, ".") == 0)
if (DotHack && strcmp(*String, ".") == 0)
*String = "";
if(**String)
if (**String)
{
/* Remove the filter */
InbvInstallDisplayStringFilter(NULL);