ReactOS 0.4.16-dev-2104-gb84fa49
vidfb.c
Go to the documentation of this file.
1/*
2 * PROJECT: FreeLoader
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Video support for linear framebuffers
5 * COPYRIGHT: Authors of uefivid.c and xboxvideo.c
6 * Copyright 2025 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
7 */
8
9#include <freeldr.h>
10#include "vidfb.h"
11#include "vgafont.h"
12
13#include <debug.h>
15
16/* This is used to introduce artificial symmetric borders at the top and bottom */
17#define TOP_BOTTOM_LINES 0
18
19
20/* GLOBALS ********************************************************************/
21
22typedef struct _FRAMEBUFFER_INFO
23{
26
27 /* Horizontal and Vertical resolution in pixels */
30
31 ULONG PixelsPerScanLine; // aka. "Pitch" or "ScreenStride", but Stride is in bytes or bits...
32 ULONG BitsPerPixel; // aka. "PixelStride".
33
34 /* Physical format of the pixel for BPP > 8, specified by bit-mask */
36
40 ULONG Delta; // aka. "Pitch": actual size in bytes of a scanline.
42
44
45
46/* FUNCTIONS ******************************************************************/
47
48#if DBG
49static VOID
50VidFbPrintFramebufferInfo(VOID)
51{
52 TRACE("Framebuffer format:\n");
53 TRACE(" BaseAddress : 0x%X\n", framebufInfo.BaseAddress);
54 TRACE(" BufferSize : %lu\n", framebufInfo.BufferSize);
55 TRACE(" ScreenWidth : %lu\n", framebufInfo.ScreenWidth);
56 TRACE(" ScreenHeight : %lu\n", framebufInfo.ScreenHeight);
57 TRACE(" PixelsPerScanLine : %lu\n", framebufInfo.PixelsPerScanLine);
58 TRACE(" BitsPerPixel : %lu\n", framebufInfo.BitsPerPixel);
59 TRACE(" BytesPerPixel : %lu\n", framebufInfo.BytesPerPixel);
60 TRACE(" Delta : %lu\n", framebufInfo.Delta);
61 TRACE(" ARGB masks: : %08x/%08x/%08x/%08x\n",
66}
67#endif
68
102 _In_ UINT32 PixelsPerScanLine,
103 _In_ UINT32 BitsPerPixel,
104 _In_opt_ PPIXEL_BITMASK PixelMasks)
105{
107
109
114 framebufInfo.PixelsPerScanLine = PixelsPerScanLine;
115 framebufInfo.BitsPerPixel = BitsPerPixel;
116
117 framebufInfo.BytesPerPixel = ((BitsPerPixel + 7) & ~7) / 8; // Round up to nearest byte.
118 framebufInfo.Delta = (PixelsPerScanLine * framebufInfo.BytesPerPixel + 3) & ~3;
119
120 /* We currently only support 32bpp */
121 if (BitsPerPixel != 32)
122 {
123 /* Unsupported BPP */
124 ERR("Unsupported %lu bits per pixel format\n", BitsPerPixel);
125 return FALSE;
126 }
127
128 //ASSERT((BitsPerPixel <= 8 && !PixelMasks) || (BitsPerPixel > 8));
129 if (BitsPerPixel > 8)
130 {
131 if (!PixelMasks ||
132 (PixelMasks->RedMask == 0 &&
133 PixelMasks->GreenMask == 0 &&
134 PixelMasks->BlueMask == 0 /* &&
135 PixelMasks->ReservedMask == 0 */))
136 {
137 /* Determine pixel mask given color depth and color channel */
138 switch (BitsPerPixel)
139 {
140 case 32:
141 case 24: /* 8:8:8 */
142 BitMasks->RedMask = 0x00FF0000; // 0x00FF0000;
143 BitMasks->GreenMask = 0x0000FF00; // 0x00FF0000 >> 8;
144 BitMasks->BlueMask = 0x000000FF; // 0x00FF0000 >> 16;
145 BitMasks->ReservedMask = ((1 << (BitsPerPixel - 24)) - 1) << 24;
146 break;
147 case 16: /* 5:6:5 */
148 BitMasks->RedMask = 0xF800; // 0xF800;
149 BitMasks->GreenMask = 0x07E0; // (0xF800 >> 5) | 0x20;
150 BitMasks->BlueMask = 0x001F; // 0xF800 >> 11;
151 BitMasks->ReservedMask = 0;
152 break;
153 case 15: /* 5:5:5 */
154 BitMasks->RedMask = 0x7C00; // 0x7C00;
155 BitMasks->GreenMask = 0x03E0; // 0x7C00 >> 5;
156 BitMasks->BlueMask = 0x001F; // 0x7C00 >> 10;
157 BitMasks->ReservedMask = 0x8000;
158 break;
159 default:
160 /* Unsupported BPP */
162 RtlZeroMemory(BitMasks, sizeof(*BitMasks));
163 }
164 }
165 else
166 {
167 /* Copy the pixel masks */
168 RtlCopyMemory(BitMasks, PixelMasks, sizeof(*BitMasks));
169 }
170 }
171 else
172 {
173 /* Palettized modes don't use masks */
174 RtlZeroMemory(BitMasks, sizeof(*BitMasks));
175 }
176
177#if DBG
178 VidFbPrintFramebufferInfo();
179 {
180 ULONG BppFromMasks =
181 PixelBitmasksToBpp(BitMasks->RedMask,
182 BitMasks->GreenMask,
183 BitMasks->BlueMask,
184 BitMasks->ReservedMask);
185 TRACE("BitsPerPixel = %lu , BppFromMasks = %lu\n", BitsPerPixel, BppFromMasks);
186 //ASSERT(BitsPerPixel == BppFromMasks);
187 }
188#endif
189
190 return TRUE;
191}
192
193VOID
196 _In_ BOOLEAN FullScreen)
197{
198 ULONG Line, Col;
199 PUINT32 p;
200
201 for (Line = 0; Line < framebufInfo.ScreenHeight - (FullScreen ? 0 : 2 * TOP_BOTTOM_LINES); Line++)
202 {
204 for (Col = 0; Col < framebufInfo.ScreenWidth; Col++)
205 {
206 *p++ = Color;
207 }
208 }
209}
210
216VOID
218 _In_ UCHAR Char,
219 _In_ ULONG X,
220 _In_ ULONG Y,
221 _In_ UINT32 FgColor,
222 _In_ UINT32 BgColor)
223{
224 const UCHAR* FontPtr;
225 PUINT32 Pixel;
226 UCHAR Mask;
227 ULONG Line, Col;
228
229 /* Don't display outside of the screen, nor partial characters */
232 {
233 return;
234 }
235
236 FontPtr = BitmapFont8x16 + Char * CHAR_HEIGHT;
238 (Y + TOP_BOTTOM_LINES) * framebufInfo.Delta + X * sizeof(UINT32));
239
240 for (Line = 0; Line < CHAR_HEIGHT; Line++)
241 {
242 Mask = 0x80;
243 for (Col = 0; Col < CHAR_WIDTH; Col++)
244 {
245 Pixel[Col] = (0 != (FontPtr[Line] & Mask) ? FgColor : BgColor);
246 Mask = Mask >> 1;
247 }
248 Pixel = (PUINT32)((PUCHAR)Pixel + framebufInfo.Delta);
249 }
250}
251
257VOID
262{
266}
267
273ULONG
275{
278}
279
280VOID
283 _In_ ULONG Scroll)
284{
288
289 while (PixelCount--)
290 *Dst++ = *Src++;
291
292 for (PixelCount = 0; PixelCount < framebufInfo.ScreenWidth * Scroll; PixelCount++)
293 *Dst++ = Color;
294}
295
296#if 0
297VOID
298VidFbSetTextCursorPosition(UCHAR X, UCHAR Y)
299{
300 /* We don't have a cursor yet */
301}
302
303VOID
304VidFbHideShowTextCursor(BOOLEAN Show)
305{
306 /* We don't have a cursor yet */
307}
308
310VidFbIsPaletteFixed(VOID)
311{
312 return FALSE;
313}
314
315VOID
316VidFbSetPaletteColor(
319{
320 /* Not supported */
321}
322
323VOID
324VidFbGetPaletteColor(
327{
328 /* Not supported */
329}
330#endif
331
332
333
334/*
335 * PROJECT: FreeLoader
336 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
337 * or MIT (https://spdx.org/licenses/MIT)
338 * PURPOSE: Linear framebuffer based console support
339 * COPYRIGHT: Copyright 2025 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
340 */
341
342#define VGA_CHAR_SIZE 2
343
344#define FBCONS_WIDTH (framebufInfo.ScreenWidth / CHAR_WIDTH)
345#define FBCONS_HEIGHT ((framebufInfo.ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT)
346
347static inline
348UINT32
350 _In_ UCHAR Attr)
351{
353 Intensity = (0 == (Attr & 0x08) ? 127 : 255);
354
355 return 0xff000000 |
356 (0 == (Attr & 0x04) ? 0 : (Intensity << 16)) |
357 (0 == (Attr & 0x02) ? 0 : (Intensity << 8)) |
358 (0 == (Attr & 0x01) ? 0 : Intensity);
359}
360
366static VOID
368 _In_ UCHAR Attr,
369 _Out_ PUINT32 FgColor,
370 _Out_ PUINT32 BgColor)
371{
372 *FgColor = FbConsAttrToSingleColor(Attr & 0x0F);
373 *BgColor = FbConsAttrToSingleColor((Attr >> 4) & 0x0F);
374}
375
376VOID
378 _In_ UCHAR Attr)
379{
380 UINT32 FgColor, BgColor;
381 FbConsAttrToColors(Attr, &FgColor, &BgColor);
383}
384
390VOID
392 _In_ UCHAR Char,
393 _In_ ULONG Column,
394 _In_ ULONG Row,
395 _In_ UINT32 FgColor,
396 _In_ UINT32 BgColor)
397{
398 /* Don't display outside of the screen */
399 if ((Column >= FBCONS_WIDTH) || (Row >= FBCONS_HEIGHT))
400 return;
401 VidFbOutputChar(Char, Column * CHAR_WIDTH, Row * CHAR_HEIGHT, FgColor, BgColor);
402}
403
408VOID
410 _In_ UCHAR Char,
411 _In_ UCHAR Attr,
412 _In_ ULONG Column,
413 _In_ ULONG Row)
414{
415 UINT32 FgColor, BgColor;
416 FbConsAttrToColors(Attr, &FgColor, &BgColor);
417 FbConsOutputChar(Char, Column, Row, FgColor, BgColor);
418}
419
425VOID
430{
431 // VidFbGetDisplaySize(Width, Height, Depth);
432 // *Width /= CHAR_WIDTH;
433 // *Height /= CHAR_HEIGHT;
437}
438
444ULONG
446{
448}
449
454// TODO: Write a VidFb "BitBlt" equivalent.
455VOID
458{
459 PUCHAR OffScreenBuffer = (PUCHAR)Buffer;
460 ULONG Row, Col;
461
462 // ULONG Width, Height, Depth;
463 // FbConsGetDisplaySize(&Width, &Height, &Depth);
465
466 for (Row = 0; Row < Height; ++Row)
467 {
468 for (Col = 0; Col < Width; ++Col)
469 {
470 FbConsPutChar(OffScreenBuffer[0], OffScreenBuffer[1], Col, Row);
471 OffScreenBuffer += VGA_CHAR_SIZE;
472 }
473 }
474}
475
476VOID
478 _In_ UCHAR Attr)
479{
480 UINT32 BgColor, Dummy;
481 FbConsAttrToColors(Attr, &Dummy, &BgColor);
482 VidFbScrollUp(BgColor, CHAR_HEIGHT);
483}
unsigned char BOOLEAN
unsigned int UINT32
#define ERR(fmt,...)
Definition: precomp.h:57
unsigned int * PUINT32
Definition: basetsd.h:119
@ Green
Definition: bl.h:199
@ Red
Definition: bl.h:201
@ Blue
Definition: bl.h:198
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
Definition: bufpool.h:45
#define BufferSize
Definition: mmc.h:75
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define Y(I)
unsigned int Mask
Definition: fpcontrol.c:82
GLfloat GLfloat p
Definition: glext.h:8902
#define Dst
Definition: mesh.h:153
static WORD Intensity(RGBQUAD clr)
Definition: msrle32.c:44
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
static ULONG ScreenWidth
Definition: pcvideo.c:116
static ULONG ScreenHeight
Definition: pcvideo.c:117
#define TRACE(s)
Definition: solgame.cpp:4
Definition: ncftp.h:79
Definition: ui.h:200
ULONG BufferSize
Definition: vidfb.c:25
ULONG_PTR BaseAddress
Definition: vidfb.c:24
ULONG PixelsPerScanLine
Definition: vidfb.c:31
ULONG ScreenHeight
Definition: vidfb.c:29
ULONG BitsPerPixel
Definition: vidfb.c:32
ULONG Delta
Definition: vidfb.c:40
PIXEL_BITMASK PixelMasks
Definition: vidfb.c:35
ULONG BytesPerPixel
Definition: vidfb.c:39
ULONG ScreenWidth
Definition: vidfb.c:28
Physical format of an RGB pixel, specified with per-component bit-masks. A bit being set defines thos...
Definition: vidfb.h:22
ULONG RedMask
Definition: vidfb.h:23
ULONG BlueMask
Definition: vidfb.h:25
ULONG GreenMask
Definition: vidfb.h:24
ULONG ReservedMask
Definition: vidfb.h:26
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
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
const UCHAR BitmapFont8x16[256 *CHAR_HEIGHT]
Definition: vgafont.c:13
#define CHAR_WIDTH
Definition: vgafont.h:10
#define CHAR_HEIGHT
Definition: vgafont.h:11
VOID FbConsScrollUp(_In_ UCHAR Attr)
Definition: vidfb.c:477
VOID FbConsClearScreen(_In_ UCHAR Attr)
Definition: vidfb.c:377
#define FBCONS_WIDTH
Definition: vidfb.c:344
#define TOP_BOTTOM_LINES
Definition: vidfb.c:17
VOID FbConsGetDisplaySize(_Out_ PULONG Width, _Out_ PULONG Height, _Out_ PULONG Depth)
Returns the width and height in number of CGA characters/attributes, of a full text-mode CGA-style ch...
Definition: vidfb.c:426
#define VGA_CHAR_SIZE
Definition: vidfb.c:342
ULONG VidFbGetBufferSize(VOID)
Returns the size in bytes, of a full graphics pixel buffer rectangle that can fill the whole visible ...
Definition: vidfb.c:274
FRAMEBUFFER_INFO framebufInfo
Definition: vidfb.c:43
VOID VidFbClearScreenColor(_In_ UINT32 Color, _In_ BOOLEAN FullScreen)
Definition: vidfb.c:194
#define FBCONS_HEIGHT
Definition: vidfb.c:345
VOID VidFbScrollUp(_In_ UINT32 Color, _In_ ULONG Scroll)
Definition: vidfb.c:281
ULONG FbConsGetBufferSize(VOID)
Returns the size in bytes, of a full text-mode CGA-style character buffer rectangle that can fill the...
Definition: vidfb.c:445
struct _FRAMEBUFFER_INFO FRAMEBUFFER_INFO
static VOID FbConsAttrToColors(_In_ UCHAR Attr, _Out_ PUINT32 FgColor, _Out_ PUINT32 BgColor)
Maps a text-mode CGA-style character attribute to separate foreground and background ARGB colors.
Definition: vidfb.c:367
BOOLEAN VidFbInitializeVideo(_In_ ULONG_PTR BaseAddress, _In_ ULONG BufferSize, _In_ UINT32 ScreenWidth, _In_ UINT32 ScreenHeight, _In_ UINT32 PixelsPerScanLine, _In_ UINT32 BitsPerPixel, _In_opt_ PPIXEL_BITMASK PixelMasks)
Initializes internal framebuffer information based on the given parameters.
Definition: vidfb.c:97
VOID FbConsPutChar(_In_ UCHAR Char, _In_ UCHAR Attr, _In_ ULONG Column, _In_ ULONG Row)
Displays a character with specific text attributes at a given position.
Definition: vidfb.c:409
static UINT32 FbConsAttrToSingleColor(_In_ UCHAR Attr)
Definition: vidfb.c:349
VOID FbConsOutputChar(_In_ UCHAR Char, _In_ ULONG Column, _In_ ULONG Row, _In_ UINT32 FgColor, _In_ UINT32 BgColor)
Displays a character at a given position with specific foreground and background colors.
Definition: vidfb.c:391
VOID VidFbOutputChar(_In_ UCHAR Char, _In_ ULONG X, _In_ ULONG Y, _In_ UINT32 FgColor, _In_ UINT32 BgColor)
Displays a character at a given pixel position with specific foreground and background colors.
Definition: vidfb.c:217
VOID VidFbGetDisplaySize(_Out_ PULONG Width, _Out_ PULONG Height, _Out_ PULONG Depth)
Returns the width and height in pixels, of the whole visible area of the graphics framebuffer.
Definition: vidfb.c:258
VOID FbConsCopyOffScreenBufferToVRAM(_In_ PVOID Buffer)
Copies a full text-mode CGA-style character buffer rectangle to the console.
Definition: vidfb.c:456
struct _FRAMEBUFFER_INFO * PFRAMEBUFFER_INFO
FORCEINLINE ULONG PixelBitmasksToBpp(_In_ ULONG RedMask, _In_ ULONG GreenMask, _In_ ULONG BlueMask, _In_ ULONG ReservedMask)
Calculates the number of bits per pixel ("PixelDepth") for the given pixel format,...
Definition: vidfb.h:41
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION _In_ ULONG _In_ SIZE_T _In_ ULONG _In_ USHORT Depth
Definition: exfuncs.h:819
unsigned char UCHAR
Definition: xmlstorage.h:181