425 lines
10 KiB
C
425 lines
10 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
anim.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Animated logo module.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
There are two types of logo displayed when the system starts up.
|
||
|
|
||
|
1. The old one contains both progress bar and a rotation bar displayed over the logo bitmap.
|
||
|
The rotation bar is a blue-white line moving across the screen from left to right.
|
||
|
|
||
|
2. The new one (starting with Whistler) contains only a rotation bar and no progress bar.
|
||
|
The rotation bar in this case is a set of 5 dots (file dots.bmp) moving at the bottom
|
||
|
of the logo from left to right.
|
||
|
|
||
|
The rotation bars in both cases are updated on timer. The client of this module will use
|
||
|
global variables to chose an appropriate animation for workstation, server, full-scale bitmap.
|
||
|
header bitmap, etc. Here are the variables:
|
||
|
|
||
|
* RotBarSelection - specifies the rotation bar to display
|
||
|
* LogoSelection - specifies the logo to display: is it full screen or header logo
|
||
|
|
||
|
Two routines are used by other modules to display the animation. Both routines should be
|
||
|
called only after the glabal flags are set.
|
||
|
|
||
|
* InbvRotBarInit - initializes a rotation bar to be drawn; this routine must be called
|
||
|
immediately after the logo bitmap is shown on the screen.
|
||
|
|
||
|
* InbvRotateGuiBootDisplay - is a DPC routine for rotation bar update.
|
||
|
|
||
|
|
||
|
PIX_IN_DOTS ROTATION BAR
|
||
|
|
||
|
First, a logo bitmap shows up on the screen. There is a line of small "empty" circles under
|
||
|
the logo. The dots bitmap is moving from left to right along this line:
|
||
|
|
||
|
o o o O Q @ Q O o o o o o o o o o
|
||
|
-------->
|
||
|
|
||
|
To avoid appearance of dots trail left of the moving dots bitmap, an "empty" circle is copied
|
||
|
over the trail every time the dots bitmap moves right:
|
||
|
|
||
|
Before step #N:
|
||
|
|
||
|
o o o O Q @ Q O o o o o o o o o o
|
||
|
|
||
|
|
||
|
After step #N:
|
||
|
|
||
|
here the
|
||
|
"empty" circle
|
||
|
is placed ______ here is the
|
||
|
___ | dots bitmap
|
||
|
| ___v___
|
||
|
v | |
|
||
|
o o o o o O Q @ Q O o o o o o o o
|
||
|
|
||
|
|
||
|
When the dots show up on the beginning/end of rotation bar, only a part of it is displayed, e.g.:
|
||
|
|
||
|
Q @ Q O o o o o o o o o o o o o o
|
||
|
|
||
|
or
|
||
|
|
||
|
o o o o o o o o o o o o o o O Q @
|
||
|
|
||
|
To do this, the rotation bar area on the logo bitmap is put once to the off-screen memory and
|
||
|
any necessary parts of it are then being copied to the display:
|
||
|
|
||
|
____________
|
||
|
| |
|
||
|
| O Q @ Q O o o o o o o o o o o o o
|
||
|
| \_____/
|
||
|
| |________________________
|
||
|
|__________________________ |
|
||
|
| __V__
|
||
|
V / \
|
||
|
o o o o o o o o o o o o o O Q @ Q
|
||
|
|
||
|
The preparation work is performed in the call to RotBarDotsBmpInit (called via InbvRotBarInit).
|
||
|
The bitmap drawing operations are performed in RotBarDotsBmpUpdate (called from InbvRotateGuiBootDisplay).
|
||
|
|
||
|
|
||
|
BLUE LINE ROTATION BAR
|
||
|
|
||
|
Blue line data is captured from the logo bitmap, placed in a buffer, and then is displayed on each DPC call
|
||
|
over the logo bitmap. Every time RotBarBlueLineUpdate is called, the point of split is recalculated. The part
|
||
|
of the line which falls before the split is displayed at the end of line on the display; the part which falls
|
||
|
after the split is displayed on the beginning:
|
||
|
|
||
|
In the buffer (copy of original bitmap):
|
||
|
|
||
|
ooooooooooo*********************oooooooooooooo
|
||
|
|
|
||
|
split ______|
|
||
|
|
||
|
____ point of concatenation
|
||
|
Displayed image: |
|
||
|
V
|
||
|
******************ooooooooooooooooooooooooo***
|
||
|
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Peter Alschitz (petera) 08-Aug-2000 (Blue Line code moved from init.c by Steve Wood)
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "ntos.h"
|
||
|
#include "stdlib.h"
|
||
|
#include "stdio.h"
|
||
|
#include <string.h>
|
||
|
#include <inbv.h>
|
||
|
#include "anim.h"
|
||
|
#include <bootvid.h>
|
||
|
#include "vga.h"
|
||
|
|
||
|
// bitmap-specific data for rotation bar
|
||
|
ROT_BAR_TYPE RotBarSelection = RB_UNSPECIFIED;
|
||
|
// LOGO_TYPE LogoSelection = LOGO_UNSPECIFIED;
|
||
|
|
||
|
int AnimBarPos = 0;
|
||
|
LONG PaletteNum;
|
||
|
BOOLEAN FadingIn = TRUE;
|
||
|
|
||
|
typedef enum {
|
||
|
PLT_UNDEFINED,
|
||
|
PLT_START,
|
||
|
PLT_CYCLE,
|
||
|
PLT_COMPLETE
|
||
|
} PLT_RBAR_STATE;
|
||
|
|
||
|
PLT_RBAR_STATE PltRotBarStatus = PLT_UNDEFINED;
|
||
|
|
||
|
#define FADE_GRADES (20)
|
||
|
#define FULL_PALETTE_SIZE (16)
|
||
|
#define FULL_PALETTE_SIZE_BYTES (FULL_PALETTE_SIZE*sizeof(RGBQUAD))
|
||
|
|
||
|
UCHAR PaletteBmp [128]; // small bitmap
|
||
|
PRGBQUAD PalettePtr = (PRGBQUAD)(PaletteBmp + sizeof(BITMAPINFOHEADER));
|
||
|
PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER)PaletteBmp;
|
||
|
|
||
|
RGBQUAD MainPalette [FULL_PALETTE_SIZE] = { {0,0,0,0}, {21,26,32,0}, {70,70,70,0}, {210,62,45,0},
|
||
|
{1,101,83,0}, {5,53,178,0}, {126,126,126,0}, {0,146,137,0},
|
||
|
{252,127,94,0}, {32,107,247,0}, {255,166,141,0}, {4,220,142,0},
|
||
|
{27,188,243,0}, {188,188,188,0}, {252,252,252,0}, {255,255,255,0} };
|
||
|
|
||
|
#define COLOR_BLACK 0
|
||
|
#define COLOR_BLUE 2
|
||
|
#define COLOR_DARKGRAY 4
|
||
|
#define COLOR_GRAY 9
|
||
|
#define COLOR_WHITE 15
|
||
|
#define COLOR_FADE_TEXT 1
|
||
|
|
||
|
UCHAR Square1[36];
|
||
|
UCHAR Square2[36];
|
||
|
UCHAR Square3[36];
|
||
|
|
||
|
VOID
|
||
|
RotBarInit (VOID)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine is called to initialize 4-color rotation bar
|
||
|
and fade-in/fade-out effect.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
This routine is called during initialization when BOOTVID.DLL is loaded
|
||
|
and Logo bitmap is being displayed on the screen.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
pbih->biSize = sizeof (BITMAPINFOHEADER);
|
||
|
pbih->biWidth = 1;
|
||
|
pbih->biHeight = 1;
|
||
|
pbih->biPlanes = 1;
|
||
|
pbih->biBitCount = 4;
|
||
|
pbih->biCompression = 0; // BI_RGB
|
||
|
pbih->biSizeImage = 4;
|
||
|
pbih->biXPelsPerMeter = 2834;
|
||
|
pbih->biYPelsPerMeter = 2834;
|
||
|
pbih->biClrUsed = 0;
|
||
|
pbih->biClrImportant = 0;
|
||
|
|
||
|
PltRotBarStatus = PLT_START;
|
||
|
PaletteNum = 0;
|
||
|
AnimBarPos = 0;
|
||
|
|
||
|
VidScreenToBufferBlt(Square1,0,0,6,9,4);
|
||
|
VidScreenToBufferBlt(Square2,2+6,0,6,9,4);
|
||
|
VidScreenToBufferBlt(Square3,2*(2+6),0,6,9,4);
|
||
|
VidSolidColorFill(0,0,22,9,COLOR_BLACK);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
FadePalette (UCHAR factor)
|
||
|
{
|
||
|
int i;
|
||
|
for (i=0; i<FULL_PALETTE_SIZE; i++) {
|
||
|
PalettePtr[i].rgbBlue = (UCHAR)(factor * MainPalette[i].rgbBlue / FADE_GRADES);
|
||
|
PalettePtr[i].rgbGreen = (UCHAR)(factor * MainPalette[i].rgbGreen / FADE_GRADES);
|
||
|
PalettePtr[i].rgbRed = (UCHAR)(factor * MainPalette[i].rgbRed / FADE_GRADES);
|
||
|
PalettePtr[i].rgbReserved = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
FadePaletteColor (UCHAR factor, UCHAR color)
|
||
|
{
|
||
|
PalettePtr[color].rgbBlue = (UCHAR)(factor * MainPalette[color].rgbBlue / FADE_GRADES);
|
||
|
PalettePtr[color].rgbGreen = (UCHAR)(factor * MainPalette[color].rgbGreen / FADE_GRADES);
|
||
|
PalettePtr[color].rgbRed = (UCHAR)(factor * MainPalette[color].rgbRed / FADE_GRADES);
|
||
|
PalettePtr[color].rgbReserved = 0;
|
||
|
}
|
||
|
|
||
|
#define COLOR_BLACK 0
|
||
|
#define COLOR_BLUE 2
|
||
|
#define COLOR_DARKGRAY 4
|
||
|
#define COLOR_GRAY 9
|
||
|
#define COLOR_WHITE 15
|
||
|
|
||
|
#define BLACK_4CLR_BAR memset (PalettePtr+12, 0, CYCLE_PALETTE_SIZE_BYTES)
|
||
|
|
||
|
#define BAR_X (267-(8*3))
|
||
|
#define BAR_Y (354)
|
||
|
#define CELL_X(num) (BAR_X+8*(AnimBarPos+num-2))
|
||
|
#define DRAW_CELL(num) VidBufferToScreenBlt(Square##num,CELL_X(num),BAR_Y,6,9,4)
|
||
|
#define BLK_CELL VidSolidColorFill(BAR_X+8*((AnimBarPos+16)%18),BAR_Y,BAR_X+8*((AnimBarPos+16)%18)+6-1,BAR_Y+9-1,COLOR_BLACK)
|
||
|
|
||
|
VOID
|
||
|
RotBarUpdate (VOID)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine is called periodically to update the 4-color rotation bar.
|
||
|
From call to call it starts with fade-in effect, proceeds to palette-based
|
||
|
rotation bar animation, and then goes to fade-out effect.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
This routine is called from a DPC and cannot be paged.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
UCHAR color;
|
||
|
|
||
|
switch (PltRotBarStatus) {
|
||
|
|
||
|
|
||
|
case PLT_START:
|
||
|
FadePalette ((UCHAR)(PaletteNum));
|
||
|
FadePaletteColor (0, COLOR_FADE_TEXT); // #1 - color of fading text
|
||
|
if ((++PaletteNum)>=FADE_GRADES) {
|
||
|
PltRotBarStatus = PLT_CYCLE;
|
||
|
FadingIn = TRUE;
|
||
|
PaletteNum = 1;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case PLT_CYCLE:
|
||
|
switch (AnimBarPos) {
|
||
|
case 0:
|
||
|
BLK_CELL;
|
||
|
break;
|
||
|
case 1:
|
||
|
DRAW_CELL(3);
|
||
|
break;
|
||
|
case 2:
|
||
|
DRAW_CELL(2);
|
||
|
DRAW_CELL(3);
|
||
|
break;
|
||
|
case 16:
|
||
|
DRAW_CELL(1);
|
||
|
DRAW_CELL(2);
|
||
|
BLK_CELL;
|
||
|
break;
|
||
|
case 17:
|
||
|
DRAW_CELL(1);
|
||
|
BLK_CELL;
|
||
|
break;
|
||
|
default:
|
||
|
DRAW_CELL(1);
|
||
|
DRAW_CELL(2);
|
||
|
DRAW_CELL(3);
|
||
|
if (AnimBarPos>3)
|
||
|
BLK_CELL;
|
||
|
}
|
||
|
|
||
|
AnimBarPos++;
|
||
|
if ((AnimBarPos) > 17)
|
||
|
AnimBarPos = 0;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case PLT_UNDEFINED:
|
||
|
case PLT_COMPLETE:
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (InbvGetDisplayState() == INBV_DISPLAY_STATE_OWNED) {
|
||
|
VidBitBlt(PaletteBmp, 0, 480);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
InbvRotBarInit ()
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine is called to initialize rotation bar.
|
||
|
The choice between rotation bar types is according to
|
||
|
global variable RotBarSelection.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
This routine is called during initialization when BOOTVID.DLL
|
||
|
is loaded and Logo bitmap is being displayed on the screen.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
switch (RotBarSelection) {
|
||
|
|
||
|
case RB_SQUARE_CELLS:
|
||
|
RotBarInit();
|
||
|
break;
|
||
|
|
||
|
case RB_UNSPECIFIED:
|
||
|
default:
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
InbvRotateGuiBootDisplay(
|
||
|
IN PVOID Context
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine is called periodically to update the guiboot display.
|
||
|
It makes its choice between calling different rotation bar update
|
||
|
routines according to global variable RotBarSelection.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
This routine is called from a DPC and cannot be paged.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
LARGE_INTEGER Delay;
|
||
|
|
||
|
Delay.QuadPart = -10 * 1000 * 80; // 100 milliseconds
|
||
|
|
||
|
do {
|
||
|
|
||
|
KeDelayExecutionThread(KernelMode, FALSE, &Delay);
|
||
|
|
||
|
InbvAcquireLock();
|
||
|
|
||
|
if (InbvGetDisplayState() == INBV_DISPLAY_STATE_OWNED) {
|
||
|
|
||
|
switch(RotBarSelection) {
|
||
|
|
||
|
case RB_SQUARE_CELLS:
|
||
|
RotBarUpdate();
|
||
|
break;
|
||
|
|
||
|
case RB_UNSPECIFIED:
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
InbvReleaseLock();
|
||
|
|
||
|
} while (InbvCheckDisplayOwnership());
|
||
|
|
||
|
PsTerminateSystemThread(STATUS_SUCCESS);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
FinalizeBootLogo(VOID)
|
||
|
{
|
||
|
InbvAcquireLock();
|
||
|
if (InbvGetDisplayState() == INBV_DISPLAY_STATE_OWNED)
|
||
|
VidSolidColorFill(0,0,639,479, COLOR_BLACK);
|
||
|
PltRotBarStatus = PLT_COMPLETE;
|
||
|
InbvReleaseLock();
|
||
|
}
|