[NTOSKRNL]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 9 Dec 2012 21:43:51 +0000 (21:43 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 9 Dec 2012 21:43:51 +0000 (21:43 +0000)
Reintroduce the long-awaited boot-logo fading-in, removed since ReactOS 0.3.3 due to bootvid / inbv refactoring. Code taken from the old (ie. pre-ReactOS 0.3.3) bootvid.

svn path=/trunk/; revision=57855

reactos/ntoskrnl/inbv/inbv.c

index dc5f241..0bdf8ce 100644 (file)
@@ -24,6 +24,92 @@ ROT_BAR_TYPE RotBarSelection;
 ULONG PltRotBarStatus;
 BT_PROGRESS_INDICATOR InbvProgressIndicator = {0, 25, 0};
 
+/* FADING FUNCTION ***********************************************************/
+
+/** From include/psdk/wingdi.h **/
+typedef struct tagRGBQUAD
+{
+    UCHAR    rgbBlue;
+    UCHAR    rgbGreen;
+    UCHAR    rgbRed;
+    UCHAR    rgbReserved;
+} RGBQUAD,*LPRGBQUAD;
+/*******************************/
+
+static RGBQUAD _MainPalette[16];
+
+#define PALETTE_FADE_STEPS  15
+#define PALETTE_FADE_TIME   20 * 10000 /* 20ms */
+
+/** From bootvid/precomp.h **/
+//
+// Bitmap Header
+//
+typedef struct tagBITMAPINFOHEADER
+{
+    ULONG biSize;
+    LONG biWidth;
+    LONG biHeight;
+    USHORT biPlanes;
+    USHORT biBitCount;
+    ULONG biCompression;
+    ULONG biSizeImage;
+    LONG biXPelsPerMeter;
+    LONG biYPelsPerMeter;
+    ULONG biClrUsed;
+    ULONG biClrImportant;
+} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
+/****************************/
+
+static VOID
+NTAPI
+BootImageFadeProc(VOID)
+{
+    UCHAR PaletteBitmapBuffer[sizeof(BITMAPINFOHEADER) + sizeof(_MainPalette)];
+    PBITMAPINFOHEADER PaletteBitmap = (PBITMAPINFOHEADER)PaletteBitmapBuffer;
+    LPRGBQUAD Palette = (LPRGBQUAD)(PaletteBitmapBuffer + sizeof(BITMAPINFOHEADER));
+
+    ULONG Iteration, Index, ClrUsed;
+    LARGE_INTEGER Interval;
+
+    Interval.QuadPart = -PALETTE_FADE_TIME;
+
+    /*
+     * Build a bitmap containing the fade in palette. The palette entries
+     * are then processed in a loop and set using VidBitBlt function.
+     */
+    ClrUsed = sizeof(_MainPalette) / sizeof(_MainPalette[0]);
+    RtlZeroMemory(PaletteBitmap, sizeof(BITMAPINFOHEADER));
+    PaletteBitmap->biSize = sizeof(BITMAPINFOHEADER);
+    PaletteBitmap->biBitCount = 4; 
+    PaletteBitmap->biClrUsed = ClrUsed;
+
+    /*
+     * Main animation loop.
+     */
+    for (Iteration = 0; Iteration <= PALETTE_FADE_STEPS; ++Iteration)
+    {
+        for (Index = 0; Index < ClrUsed; Index++)
+        {
+            Palette[Index].rgbRed =
+                _MainPalette[Index].rgbRed * Iteration / PALETTE_FADE_STEPS;
+            Palette[Index].rgbGreen =
+                _MainPalette[Index].rgbGreen * Iteration / PALETTE_FADE_STEPS;
+            Palette[Index].rgbBlue =
+                _MainPalette[Index].rgbBlue * Iteration / PALETTE_FADE_STEPS;
+        }
+
+        VidBitBlt(PaletteBitmapBuffer, 0, 0);
+
+        /* Wait for a bit. */
+        KeDelayExecutionThread(KernelMode, FALSE, &Interval);
+    }
+
+    /* Wait for a bit. */
+    KeDelayExecutionThread(KernelMode, FALSE, &Interval);
+}
+
+
 /* FUNCTIONS *****************************************************************/
 
 PVOID
@@ -267,12 +353,11 @@ InbvDisplayString(IN PCHAR String)
         if (InbvBootDriverInstalled) VidDisplayString((PUCHAR) String);
 
         /* Print the string on the EMS port */
-               HeadlessDispatch(
-                       HeadlessCmdPutString,
-                       String,
-                       strlen(String) + sizeof(ANSI_NULL),
-                       NULL,
-                       NULL);
+        HeadlessDispatch(HeadlessCmdPutString,
+                         String,
+                         strlen(String) + sizeof(ANSI_NULL),
+                         NULL,
+                         NULL);
 
         /* Release the lock */
         InbvReleaseLock();
@@ -578,10 +663,13 @@ NTAPI
 INIT_FUNCTION
 DisplayBootBitmap(IN BOOLEAN TextMode)
 {
+    PBITMAPINFOHEADER BitmapInfoHeader;
+    LPRGBQUAD Palette;
+
     PVOID Header, Band, Text, Screen;
     ROT_BAR_TYPE TempRotBarSelection = RB_UNSPECIFIED;
-    UCHAR Buffer[64];
-    
+    // UCHAR Buffer[64];
+
     /* Check if the system thread has already been created */
     if (SysThreadCreated)
     {
@@ -665,19 +753,32 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
             /* Server product, display appropriate status bar color */
             InbvGetResourceAddress(IDB_BAR_SERVER);
         }
-        
+
         /* Make sure we had a logo */
         if (Screen)
         {
             /* Choose progress bar */
             TempRotBarSelection = RB_SQUARE_CELLS;
 
+            /*
+             * Save the main image palette and replace it with black palette, so
+             * we can do fade in effect later.
+             */
+            BitmapInfoHeader = (PBITMAPINFOHEADER)Screen;
+            Palette = (LPRGBQUAD)((PUCHAR)Screen + BitmapInfoHeader->biSize);
+            RtlCopyMemory(_MainPalette, Palette, sizeof(_MainPalette));
+            RtlZeroMemory(Palette, sizeof(_MainPalette));
+
             /* Blit the background */
             InbvBitBlt(Screen, 0, 0);
 
             /* Set progress bar coordinates and display it */
             InbvSetProgressBarCoordinates(257, 352);
-            
+
+            /* Display the boot logo and fade it in */
+            BootImageFadeProc();
+
+#if 0
             /* Check for non-workstation products */
             if (SharedUserData->NtProductType != NtProductWinNt)
             {
@@ -689,16 +790,17 @@ DisplayBootBitmap(IN BOOLEAN TextMode)
                 /* In setup mode, you haven't selected a SKU yet */
                 if (ExpInTextModeSetup) Text = NULL;
             }
-          }
-          
-          /* Draw the SKU text if it exits */
-          if (Text) InbvBitBlt(Text, 180, 121);
-          
-          /* Draw the progress bar bit */
-//          if (Bar) InbvBitBlt(Bar, 0, 0);
-
-          /* Set filter which will draw text display if needed */
-          InbvInstallDisplayStringFilter(DisplayFilter);
+#endif
+        }
+
+        /* Draw the SKU text if it exits */
+//      if (Text) InbvBitBlt(Text, 180, 121);
+
+        /* Draw the progress bar bit */
+//      if (Bar) InbvBitBlt(Bar, 0, 0);
+
+        /* Set filter which will draw text display if needed */
+        InbvInstallDisplayStringFilter(DisplayFilter);
     }
 
     /* Do we have a system thread? */