ReactOS 0.4.15-dev-8100-g1887773
common.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Boot Video Driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Platform-independent common helpers and defines
5 * COPYRIGHT: Copyright 2010 Gregor Schneider <gregor.schneider@reactos.org>
6 * Copyright 2011 Rafal Harabien <rafalh@reactos.org>
7 * Copyright 2020 Stanislav Motylkov <x86corez@gmail.com>
8 */
9
10#include "precomp.h"
11
12/* GLOBALS ********************************************************************/
13
15
18
20{
21 0,
22 0,
23 SCREEN_WIDTH - 1,
25};
26
27/*
28 * Boot video driver default palette is similar to the standard 16-color
29 * CGA palette, but it has Red and Blue channels swapped, and also dark
30 * and light gray colors swapped.
31 */
33{
34 RGB( 0, 0, 0), /* Black */
35 RGB(128, 0, 0), /* Red */
36 RGB( 0, 128, 0), /* Green */
37 RGB(128, 128, 0), /* Brown */
38 RGB( 0, 0, 128), /* Blue */
39 RGB(128, 0, 128), /* Magenta */
40 RGB( 0, 128, 128), /* Cyan */
41 RGB(128, 128, 128), /* Dark Gray */
42 RGB(192, 192, 192), /* Light Gray */
43 RGB(255, 0, 0), /* Light Red */
44 RGB( 0, 255, 0), /* Light Green */
45 RGB(255, 255, 0), /* Yellow */
46 RGB( 0, 0, 255), /* Light Blue */
47 RGB(255, 0, 255), /* Light Magenta */
48 RGB( 0, 255, 255), /* Light Cyan */
49 RGB(255, 255, 255), /* White */
50};
51
53
54/* PRIVATE FUNCTIONS **********************************************************/
55
56static VOID
58 _In_ ULONG Left,
63 _In_ ULONG BitsPerPixel,
65{
66 ULONG X, Y, Pixel;
69 const ULONG Bottom = Top + Height;
70 const ULONG Right = Left + Width;
71
72 /* Check if the buffer isn't 4bpp */
73 if (BitsPerPixel != 4)
74 {
75 /* FIXME: TODO */
76 DbgPrint("Unhandled BitBlt\n"
77 "%lux%lu @ (%lu|%lu)\n"
78 "Bits Per Pixel %lu\n"
79 "Buffer: %p. Delta: %lu\n",
80 Width,
81 Height,
82 Left,
83 Top,
84 BitsPerPixel,
85 Buffer,
86 Delta);
87 return;
88 }
89
91
92 /* 4bpp blitting */
93 for (Y = Top; Y < Bottom; ++Y)
94 {
96
97 for (X = Left, Pixel = 0;
98 X < Right;
99 ++X, ++Pixel)
100 {
101 if (Pixel % 2 == 0)
102 {
103 /* Extract colors at every two pixels */
104 Colors = *InputBuffer++;
105
106 SetPixel(X, Y, Colors >> 4);
107 }
108 else
109 {
110 SetPixel(X, Y, Colors & 0x0F);
111 }
112 }
113
114 Buffer += Delta;
115 }
116}
117
118static VOID
120 _In_ ULONG Left,
121 _In_ ULONG Top,
125{
126 ULONG YDelta;
127 ULONG x;
128 ULONG RleValue, NewRleValue;
129 ULONG Color, Color2;
130 ULONG i, j;
131 ULONG Code;
132
134
135 /* Set Y height and current X value and start loop */
136 YDelta = Top + Height - 1;
137 x = Left;
138 for (;;)
139 {
140 /* Get the current value and advance in the buffer */
141 RleValue = *Buffer;
142 Buffer++;
143 if (RleValue)
144 {
145 /* Check if we've gone past the edge */
146 if ((x + RleValue) > (Width + Left))
147 {
148 /* Fixup the pixel value */
149 RleValue = Left - x + Width;
150 }
151
152 /* Get the new value */
153 NewRleValue = *Buffer;
154
155 /* Get the two colors */
156 Color = NewRleValue >> 4;
157 Color2 = NewRleValue & 0xF;
158
159 /* Increase buffer position */
160 Buffer++;
161
162 /* Check if we need to do a fill */
163 if (Color == Color2)
164 {
165 /* Do a fill and continue the loop */
166 RleValue += x;
167 VidSolidColorFill(x, YDelta, RleValue - 1, YDelta, (UCHAR)Color);
168 x = RleValue;
169 continue;
170 }
171
172 /* Check if the pixel value is 1 or below */
173 if (RleValue > 1)
174 {
175 /* Set loop variables */
176 for (i = (RleValue - 2) / 2 + 1; i > 0; --i)
177 {
178 /* Set the pixels */
179 SetPixel(x, YDelta, (UCHAR)Color);
180 x++;
181 SetPixel(x, YDelta, (UCHAR)Color2);
182 x++;
183
184 /* Decrease pixel value */
185 RleValue -= 2;
186 }
187 }
188
189 /* Check if there is any value at all */
190 if (RleValue)
191 {
192 /* Set the pixel and increase position */
193 SetPixel(x, YDelta, (UCHAR)Color);
194 x++;
195 }
196
197 /* Start over */
198 continue;
199 }
200
201 /* Get the current pixel value */
202 RleValue = *Buffer;
203 Code = RleValue;
204 switch (Code)
205 {
206 /* Case 0 */
207 case 0:
208 {
209 /* Set new x value, decrease distance and restart */
210 x = Left;
211 YDelta--;
212 Buffer++;
213 continue;
214 }
215
216 /* Case 1 */
217 case 1:
218 {
219 /* Done */
220 return;
221 }
222
223 /* Case 2 */
224 case 2:
225 {
226 /* Set new x value, decrease distance and restart */
227 Buffer++;
228 x += *Buffer;
229 Buffer++;
230 YDelta -= *Buffer;
231 Buffer++;
232 continue;
233 }
234
235 /* Other values */
236 default:
237 {
238 Buffer++;
239 break;
240 }
241 }
242
243 /* Check if we've gone past the edge */
244 if ((x + RleValue) > (Width + Left))
245 {
246 /* Set fixed up loop count */
247 i = RleValue - Left - Width + x;
248
249 /* Fixup pixel value */
250 RleValue -= i;
251 }
252 else
253 {
254 /* Clear loop count */
255 i = 0;
256 }
257
258 /* Check the value now */
259 if (RleValue > 1)
260 {
261 /* Set loop variables */
262 for (j = (RleValue - 2) / 2 + 1; j > 0; --j)
263 {
264 /* Get the new value */
265 NewRleValue = *Buffer;
266
267 /* Get the two colors */
268 Color = NewRleValue >> 4;
269 Color2 = NewRleValue & 0xF;
270
271 /* Increase buffer position */
272 Buffer++;
273
274 /* Set the pixels */
275 SetPixel(x, YDelta, (UCHAR)Color);
276 x++;
277 SetPixel(x, YDelta, (UCHAR)Color2);
278 x++;
279
280 /* Decrease pixel value */
281 RleValue -= 2;
282 }
283 }
284
285 /* Check if there is any value at all */
286 if (RleValue)
287 {
288 /* Set the pixel and increase position */
289 Color = *Buffer >> 4;
290 Buffer++;
291 SetPixel(x, YDelta, (UCHAR)Color);
292 x++;
293 i--;
294 }
295
296 /* Check loop count now */
297 if ((LONG)i > 0)
298 {
299 /* Decrease it */
300 i--;
301
302 /* Set new position */
303 Buffer = Buffer + (i / 2) + 1;
304 }
305
306 /* Check if we need to increase the buffer */
307 if ((ULONG_PTR)Buffer & 1) Buffer++;
308 }
309}
310
311/* PUBLIC FUNCTIONS ***********************************************************/
312
313ULONG
314NTAPI
317{
318 ULONG OldColor;
319
320 /* Save the old color and set the new one */
321 OldColor = VidpTextColor;
323 return OldColor;
324}
325
326VOID
327NTAPI
330 _In_ ULONG Left,
331 _In_ ULONG Top,
332 _In_ BOOLEAN Transparent)
333{
334 ULONG BackColor;
335
336 /*
337 * If the caller wanted transparent, then send the special value (16),
338 * else use our default and call the helper routine.
339 */
340 BackColor = Transparent ? BV_COLOR_NONE : BV_COLOR_LIGHT_CYAN;
341
342 /* Loop every character and adjust the position */
343 for (; *String; ++String, Left += BOOTCHAR_WIDTH)
344 {
345 /* Display a character */
346 DisplayCharacter(*String, Left, Top, BV_COLOR_LIGHT_BLUE, BackColor);
347 }
348}
349
350VOID
351NTAPI
353 _In_ ULONG Left,
354 _In_ ULONG Top,
355 _In_ ULONG Right,
357{
358 /* Assert alignment */
359 ASSERT((Left % BOOTCHAR_WIDTH) == 0);
360 ASSERT((Right % BOOTCHAR_WIDTH) == BOOTCHAR_WIDTH - 1);
361
362 /* Set Scroll Region */
363 VidpScrollRegion[0] = Left;
365 VidpScrollRegion[2] = Right;
367
368 /* Set current X and Y */
369 VidpCurrentX = Left;
371}
372
373VOID
374NTAPI
377{
378 /* Start looping the string */
379 for (; *String; ++String)
380 {
381 /* Treat new-line separately */
382 if (*String == '\n')
383 {
384 /* Modify Y position */
387 {
388 /* Scroll the view and clear the current row */
392 }
393 else
394 {
395 /* Preserve the current row */
397 }
398
399 /* Update current X */
401
402 /* No need to clear this row */
403 ClearRow = FALSE;
404 }
405 else if (*String == '\r')
406 {
407 /* Update current X */
409
410 /* If a new-line does not follow we will clear the current row */
411 if (String[1] != '\n') ClearRow = TRUE;
412 }
413 else
414 {
415 /* Clear the current row if we had a return-carriage without a new-line */
416 if (ClearRow)
417 {
419 ClearRow = FALSE;
420 }
421
422 /* Display this character */
425
426 /* Check if we should scroll */
428 {
429 /* Update Y position and check if we should scroll it */
432 {
433 /* Scroll the view and clear the current row */
437 }
438 else
439 {
440 /* Preserve the current row */
442 }
443
444 /* Update current X */
446 }
447 }
448 }
449}
450
451VOID
452NTAPI
455 _In_ ULONG Left,
456 _In_ ULONG Top,
460{
461 /* Make sure we have a width and height */
462 if (!Width || !Height)
463 return;
464
465 /* Call the helper function */
466 BitBlt(Left, Top, Width, Height, Buffer, 4, Delta);
467}
468
469VOID
470NTAPI
473 _In_ ULONG Left,
474 _In_ ULONG Top)
475{
476 PBITMAPINFOHEADER BitmapInfoHeader;
477 LONG Delta;
478 PUCHAR BitmapOffset;
479 ULONG PaletteCount;
480
481 /* Get the Bitmap Header */
482 BitmapInfoHeader = (PBITMAPINFOHEADER)Buffer;
483
484 /* Initialize the palette */
485 PaletteCount = BitmapInfoHeader->biClrUsed ?
486 BitmapInfoHeader->biClrUsed : BV_MAX_COLORS;
487 InitPaletteWithTable((PULONG)(Buffer + BitmapInfoHeader->biSize),
488 PaletteCount);
489
490 /* Make sure we can support this bitmap */
491 ASSERT((BitmapInfoHeader->biBitCount * BitmapInfoHeader->biPlanes) <= 4);
492
493 /*
494 * Calculate the delta and align it on 32-bytes, then calculate
495 * the actual start of the bitmap data.
496 */
497 Delta = (BitmapInfoHeader->biBitCount * BitmapInfoHeader->biWidth) + 31;
498 Delta >>= 3;
499 Delta &= ~3;
500 BitmapOffset = Buffer + sizeof(BITMAPINFOHEADER) + PaletteCount * sizeof(ULONG);
501
502 /* Check the compression of the bitmap */
503 if (BitmapInfoHeader->biCompression == BI_RLE4)
504 {
505 /* Make sure we have a width and a height */
506 if ((BitmapInfoHeader->biWidth) && (BitmapInfoHeader->biHeight))
507 {
508 /* We can use RLE Bit Blt */
509 RleBitBlt(Left,
510 Top,
511 BitmapInfoHeader->biWidth,
512 BitmapInfoHeader->biHeight,
513 BitmapOffset);
514 }
515 }
516 else
517 {
518 /* Check if the height is negative */
519 if (BitmapInfoHeader->biHeight < 0)
520 {
521 /* Make it positive in the header */
522 BitmapInfoHeader->biHeight *= -1;
523 }
524 else
525 {
526 /* Update buffer offset */
527 BitmapOffset += ((BitmapInfoHeader->biHeight - 1) * Delta);
528 Delta *= -1;
529 }
530
531 /* Make sure we have a width and a height */
532 if ((BitmapInfoHeader->biWidth) && (BitmapInfoHeader->biHeight))
533 {
534 /* Do the BitBlt */
535 BitBlt(Left,
536 Top,
537 BitmapInfoHeader->biWidth,
538 BitmapInfoHeader->biHeight,
539 BitmapOffset,
540 BitmapInfoHeader->biBitCount,
541 Delta);
542 }
543 }
544}
unsigned char BOOLEAN
Colors
Definition: ansiprsr.h:4
VOID NTAPI VidSolidColorFill(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Right, _In_ ULONG Bottom, _In_ UCHAR Color)
Definition: bootvid.c:261
VOID PreserveRow(_In_ ULONG CurrentTop, _In_ ULONG TopDelta, _In_ BOOLEAN Restore)
Definition: bootvid.c:111
FORCEINLINE VOID SetPixel(_In_ ULONG Left, _In_ ULONG Top, _In_ UCHAR Color)
Definition: arm.h:55
VOID DisplayCharacter(_In_ CHAR Character, _In_ ULONG Left, _In_ ULONG Top, _In_ ULONG TextColor, _In_ ULONG BackColor)
Definition: bootvid.c:19
VOID DoScroll(_In_ ULONG Scroll)
Definition: bootvid.c:64
VOID InitPaletteWithTable(_In_ PULONG Table, _In_ ULONG Count)
Definition: bootvid.c:172
static LPHIST_ENTRY Bottom
Definition: history.c:54
static LPHIST_ENTRY Top
Definition: history.c:53
Definition: bufpool.h:45
#define Code
Definition: deflate.h:80
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define Y(I)
VOID NTAPI VidBitBlt(_In_ PUCHAR Buffer, _In_ ULONG Left, _In_ ULONG Top)
Definition: common.c:471
const RGBQUAD VidpDefaultPalette[BV_MAX_COLORS]
Definition: common.c:32
ULONG NTAPI VidSetTextColor(_In_ ULONG Color)
Definition: common.c:315
UCHAR VidpTextColor
Definition: common.c:14
ULONG VidpCurrentY
Definition: common.c:17
VOID NTAPI VidDisplayStringXY(_In_z_ PUCHAR String, _In_ ULONG Left, _In_ ULONG Top, _In_ BOOLEAN Transparent)
Definition: common.c:328
static VOID BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Delta)
Definition: common.c:57
VOID NTAPI VidBufferToScreenBlt(_In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_ ULONG Delta)
Definition: common.c:453
ULONG VidpCurrentX
Definition: common.c:16
VOID NTAPI VidDisplayString(_In_z_ PUCHAR String)
Definition: common.c:375
VOID NTAPI VidSetScrollRegion(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Right, _In_ ULONG Bottom)
Definition: common.c:352
static VOID RleBitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_ PUCHAR Buffer)
Definition: common.c:119
ULONG VidpScrollRegion[4]
Definition: common.c:19
static BOOLEAN ClearRow
Definition: common.c:52
#define BI_RLE4
Definition: precomp.h:57
struct tagBITMAPINFOHEADER * PBITMAPINFOHEADER
#define RGB(r, g, b)
Definition: precomp.h:71
ULONG RGBQUAD
Definition: precomp.h:59
#define BOOTCHAR_HEIGHT
Definition: precomp.h:36
#define BOOTCHAR_WIDTH
Definition: precomp.h:37
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define DbgPrint
Definition: hal.h:12
#define X(b, s)
#define ASSERT(a)
Definition: mode.c:44
#define _In_reads_bytes_(size)
Definition: ms_sal.h:321
#define _In_z_
Definition: ms_sal.h:313
#define _In_
Definition: ms_sal.h:308
#define SCREEN_WIDTH
Definition: pc98video.c:27
#define SCREEN_HEIGHT
Definition: pc98video.c:28
VOID PrepareForSetPixel(VOID)
Definition: vga.c:90
long LONG
Definition: pedump.c:60
#define BV_COLOR_WHITE
Definition: display.h:30
#define BV_COLOR_LIGHT_CYAN
Definition: display.h:29
#define BV_COLOR_LIGHT_BLUE
Definition: display.h:27
#define BV_COLOR_NONE
Definition: display.h:31
#define BV_MAX_COLORS
Definition: display.h:32
USHORT biBitCount
Definition: precomp.h:46
ULONG biCompression
Definition: precomp.h:47
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1701
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
static ULONG Delta
Definition: xboxvideo.c:33
unsigned char UCHAR
Definition: xmlstorage.h:181