Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

424 lines
10 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. anim.c
  5. Abstract:
  6. Animated logo module.
  7. Notes:
  8. There are two types of logo displayed when the system starts up.
  9. 1. The old one contains both progress bar and a rotation bar displayed over the logo bitmap.
  10. The rotation bar is a blue-white line moving across the screen from left to right.
  11. 2. The new one (starting with Whistler) contains only a rotation bar and no progress bar.
  12. The rotation bar in this case is a set of 5 dots (file dots.bmp) moving at the bottom
  13. of the logo from left to right.
  14. The rotation bars in both cases are updated on timer. The client of this module will use
  15. global variables to chose an appropriate animation for workstation, server, full-scale bitmap.
  16. header bitmap, etc. Here are the variables:
  17. * RotBarSelection - specifies the rotation bar to display
  18. * LogoSelection - specifies the logo to display: is it full screen or header logo
  19. Two routines are used by other modules to display the animation. Both routines should be
  20. called only after the glabal flags are set.
  21. * InbvRotBarInit - initializes a rotation bar to be drawn; this routine must be called
  22. immediately after the logo bitmap is shown on the screen.
  23. * InbvRotateGuiBootDisplay - is a DPC routine for rotation bar update.
  24. PIX_IN_DOTS ROTATION BAR
  25. First, a logo bitmap shows up on the screen. There is a line of small "empty" circles under
  26. the logo. The dots bitmap is moving from left to right along this line:
  27. o o o O Q @ Q O o o o o o o o o o
  28. -------->
  29. To avoid appearance of dots trail left of the moving dots bitmap, an "empty" circle is copied
  30. over the trail every time the dots bitmap moves right:
  31. Before step #N:
  32. o o o O Q @ Q O o o o o o o o o o
  33. After step #N:
  34. here the
  35. "empty" circle
  36. is placed ______ here is the
  37. ___ | dots bitmap
  38. | ___v___
  39. v | |
  40. o o o o o O Q @ Q O o o o o o o o
  41. When the dots show up on the beginning/end of rotation bar, only a part of it is displayed, e.g.:
  42. Q @ Q O o o o o o o o o o o o o o
  43. or
  44. o o o o o o o o o o o o o o O Q @
  45. To do this, the rotation bar area on the logo bitmap is put once to the off-screen memory and
  46. any necessary parts of it are then being copied to the display:
  47. ____________
  48. | |
  49. | O Q @ Q O o o o o o o o o o o o o
  50. | \_____/
  51. | |________________________
  52. |__________________________ |
  53. | __V__
  54. V / \
  55. o o o o o o o o o o o o o O Q @ Q
  56. The preparation work is performed in the call to RotBarDotsBmpInit (called via InbvRotBarInit).
  57. The bitmap drawing operations are performed in RotBarDotsBmpUpdate (called from InbvRotateGuiBootDisplay).
  58. BLUE LINE ROTATION BAR
  59. Blue line data is captured from the logo bitmap, placed in a buffer, and then is displayed on each DPC call
  60. over the logo bitmap. Every time RotBarBlueLineUpdate is called, the point of split is recalculated. The part
  61. of the line which falls before the split is displayed at the end of line on the display; the part which falls
  62. after the split is displayed on the beginning:
  63. In the buffer (copy of original bitmap):
  64. ooooooooooo*********************oooooooooooooo
  65. |
  66. split ______|
  67. ____ point of concatenation
  68. Displayed image: |
  69. V
  70. ******************ooooooooooooooooooooooooo***
  71. Author:
  72. Peter Alschitz (petera) 08-Aug-2000 (Blue Line code moved from init.c by Steve Wood)
  73. Revision History:
  74. --*/
  75. #include "ntos.h"
  76. #include "stdlib.h"
  77. #include "stdio.h"
  78. #include <string.h>
  79. #include <inbv.h>
  80. #include "anim.h"
  81. #include <bootvid.h>
  82. #include "vga.h"
  83. // bitmap-specific data for rotation bar
  84. ROT_BAR_TYPE RotBarSelection = RB_UNSPECIFIED;
  85. // LOGO_TYPE LogoSelection = LOGO_UNSPECIFIED;
  86. int AnimBarPos = 0;
  87. LONG PaletteNum;
  88. BOOLEAN FadingIn = TRUE;
  89. typedef enum {
  90. PLT_UNDEFINED,
  91. PLT_START,
  92. PLT_CYCLE,
  93. PLT_COMPLETE
  94. } PLT_RBAR_STATE;
  95. PLT_RBAR_STATE PltRotBarStatus = PLT_UNDEFINED;
  96. #define FADE_GRADES (20)
  97. #define FULL_PALETTE_SIZE (16)
  98. #define FULL_PALETTE_SIZE_BYTES (FULL_PALETTE_SIZE*sizeof(RGBQUAD))
  99. UCHAR PaletteBmp [128]; // small bitmap
  100. PRGBQUAD PalettePtr = (PRGBQUAD)(PaletteBmp + sizeof(BITMAPINFOHEADER));
  101. PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER)PaletteBmp;
  102. RGBQUAD MainPalette [FULL_PALETTE_SIZE] = { {0,0,0,0}, {21,26,32,0}, {70,70,70,0}, {210,62,45,0},
  103. {1,101,83,0}, {5,53,178,0}, {126,126,126,0}, {0,146,137,0},
  104. {252,127,94,0}, {32,107,247,0}, {255,166,141,0}, {4,220,142,0},
  105. {27,188,243,0}, {188,188,188,0}, {252,252,252,0}, {255,255,255,0} };
  106. #define COLOR_BLACK 0
  107. #define COLOR_BLUE 2
  108. #define COLOR_DARKGRAY 4
  109. #define COLOR_GRAY 9
  110. #define COLOR_WHITE 15
  111. #define COLOR_FADE_TEXT 1
  112. UCHAR Square1[36];
  113. UCHAR Square2[36];
  114. UCHAR Square3[36];
  115. VOID
  116. RotBarInit (VOID)
  117. /*++
  118. Routine Description:
  119. This routine is called to initialize 4-color rotation bar
  120. and fade-in/fade-out effect.
  121. Return Value:
  122. None.
  123. Environment:
  124. This routine is called during initialization when BOOTVID.DLL is loaded
  125. and Logo bitmap is being displayed on the screen.
  126. --*/
  127. {
  128. pbih->biSize = sizeof (BITMAPINFOHEADER);
  129. pbih->biWidth = 1;
  130. pbih->biHeight = 1;
  131. pbih->biPlanes = 1;
  132. pbih->biBitCount = 4;
  133. pbih->biCompression = 0; // BI_RGB
  134. pbih->biSizeImage = 4;
  135. pbih->biXPelsPerMeter = 2834;
  136. pbih->biYPelsPerMeter = 2834;
  137. pbih->biClrUsed = 0;
  138. pbih->biClrImportant = 0;
  139. PltRotBarStatus = PLT_START;
  140. PaletteNum = 0;
  141. AnimBarPos = 0;
  142. VidScreenToBufferBlt(Square1,0,0,6,9,4);
  143. VidScreenToBufferBlt(Square2,2+6,0,6,9,4);
  144. VidScreenToBufferBlt(Square3,2*(2+6),0,6,9,4);
  145. VidSolidColorFill(0,0,22,9,COLOR_BLACK);
  146. }
  147. VOID
  148. FadePalette (UCHAR factor)
  149. {
  150. int i;
  151. for (i=0; i<FULL_PALETTE_SIZE; i++) {
  152. PalettePtr[i].rgbBlue = (UCHAR)(factor * MainPalette[i].rgbBlue / FADE_GRADES);
  153. PalettePtr[i].rgbGreen = (UCHAR)(factor * MainPalette[i].rgbGreen / FADE_GRADES);
  154. PalettePtr[i].rgbRed = (UCHAR)(factor * MainPalette[i].rgbRed / FADE_GRADES);
  155. PalettePtr[i].rgbReserved = 0;
  156. }
  157. }
  158. VOID
  159. FadePaletteColor (UCHAR factor, UCHAR color)
  160. {
  161. PalettePtr[color].rgbBlue = (UCHAR)(factor * MainPalette[color].rgbBlue / FADE_GRADES);
  162. PalettePtr[color].rgbGreen = (UCHAR)(factor * MainPalette[color].rgbGreen / FADE_GRADES);
  163. PalettePtr[color].rgbRed = (UCHAR)(factor * MainPalette[color].rgbRed / FADE_GRADES);
  164. PalettePtr[color].rgbReserved = 0;
  165. }
  166. #define COLOR_BLACK 0
  167. #define COLOR_BLUE 2
  168. #define COLOR_DARKGRAY 4
  169. #define COLOR_GRAY 9
  170. #define COLOR_WHITE 15
  171. #define BLACK_4CLR_BAR memset (PalettePtr+12, 0, CYCLE_PALETTE_SIZE_BYTES)
  172. #define BAR_X (267-(8*3))
  173. #define BAR_Y (354)
  174. #define CELL_X(num) (BAR_X+8*(AnimBarPos+num-2))
  175. #define DRAW_CELL(num) VidBufferToScreenBlt(Square##num,CELL_X(num),BAR_Y,6,9,4)
  176. #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)
  177. VOID
  178. RotBarUpdate (VOID)
  179. /*++
  180. Routine Description:
  181. This routine is called periodically to update the 4-color rotation bar.
  182. From call to call it starts with fade-in effect, proceeds to palette-based
  183. rotation bar animation, and then goes to fade-out effect.
  184. Return Value:
  185. None.
  186. Environment:
  187. This routine is called from a DPC and cannot be paged.
  188. --*/
  189. {
  190. UCHAR color;
  191. switch (PltRotBarStatus) {
  192. case PLT_START:
  193. FadePalette ((UCHAR)(PaletteNum));
  194. FadePaletteColor (0, COLOR_FADE_TEXT); // #1 - color of fading text
  195. if ((++PaletteNum)>=FADE_GRADES) {
  196. PltRotBarStatus = PLT_CYCLE;
  197. FadingIn = TRUE;
  198. PaletteNum = 1;
  199. }
  200. break;
  201. case PLT_CYCLE:
  202. switch (AnimBarPos) {
  203. case 0:
  204. BLK_CELL;
  205. break;
  206. case 1:
  207. DRAW_CELL(3);
  208. break;
  209. case 2:
  210. DRAW_CELL(2);
  211. DRAW_CELL(3);
  212. break;
  213. case 16:
  214. DRAW_CELL(1);
  215. DRAW_CELL(2);
  216. BLK_CELL;
  217. break;
  218. case 17:
  219. DRAW_CELL(1);
  220. BLK_CELL;
  221. break;
  222. default:
  223. DRAW_CELL(1);
  224. DRAW_CELL(2);
  225. DRAW_CELL(3);
  226. if (AnimBarPos>3)
  227. BLK_CELL;
  228. }
  229. AnimBarPos++;
  230. if ((AnimBarPos) > 17)
  231. AnimBarPos = 0;
  232. break;
  233. case PLT_UNDEFINED:
  234. case PLT_COMPLETE:
  235. return;
  236. }
  237. if (InbvGetDisplayState() == INBV_DISPLAY_STATE_OWNED) {
  238. VidBitBlt(PaletteBmp, 0, 480);
  239. }
  240. }
  241. VOID
  242. InbvRotBarInit ()
  243. /*++
  244. Routine Description:
  245. This routine is called to initialize rotation bar.
  246. The choice between rotation bar types is according to
  247. global variable RotBarSelection.
  248. Return Value:
  249. None.
  250. Environment:
  251. This routine is called during initialization when BOOTVID.DLL
  252. is loaded and Logo bitmap is being displayed on the screen.
  253. --*/
  254. {
  255. switch (RotBarSelection) {
  256. case RB_SQUARE_CELLS:
  257. RotBarInit();
  258. break;
  259. case RB_UNSPECIFIED:
  260. default:
  261. break;
  262. }
  263. }
  264. VOID
  265. InbvRotateGuiBootDisplay(
  266. IN PVOID Context
  267. )
  268. /*++
  269. Routine Description:
  270. This routine is called periodically to update the guiboot display.
  271. It makes its choice between calling different rotation bar update
  272. routines according to global variable RotBarSelection.
  273. Return Value:
  274. None.
  275. Environment:
  276. This routine is called from a DPC and cannot be paged.
  277. --*/
  278. {
  279. LARGE_INTEGER Delay;
  280. Delay.QuadPart = -10 * 1000 * 80; // 100 milliseconds
  281. do {
  282. KeDelayExecutionThread(KernelMode, FALSE, &Delay);
  283. InbvAcquireLock();
  284. if (InbvGetDisplayState() == INBV_DISPLAY_STATE_OWNED) {
  285. switch(RotBarSelection) {
  286. case RB_SQUARE_CELLS:
  287. RotBarUpdate();
  288. break;
  289. case RB_UNSPECIFIED:
  290. default:
  291. break;
  292. }
  293. }
  294. InbvReleaseLock();
  295. } while (InbvCheckDisplayOwnership());
  296. PsTerminateSystemThread(STATUS_SUCCESS);
  297. }
  298. VOID
  299. FinalizeBootLogo(VOID)
  300. {
  301. InbvAcquireLock();
  302. if (InbvGetDisplayState() == INBV_DISPLAY_STATE_OWNED)
  303. VidSolidColorFill(0,0,639,479, COLOR_BLACK);
  304. PltRotBarStatus = PLT_COMPLETE;
  305. InbvReleaseLock();
  306. }