Author: aandrejevic
Date: Tue May 20 18:46:50 2014
New Revision: 63385
URL:
http://svn.reactos.org/svn/reactos?rev=63385&view=rev
Log:
[NTVDM]
Use a separate palette for text mode. Previously the text mode palette was equal to the
first 16 entries of the graphical palette, which is wrong since the AC registers can be
used to select arbitrary colors from the DAC.
Modified:
trunk/reactos/subsystems/ntvdm/hardware/vga.c
Modified: trunk/reactos/subsystems/ntvdm/hardware/vga.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/hardware/…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/hardware/vga.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/hardware/vga.c [iso-8859-1] Tue May 20 18:46:50 2014
@@ -172,6 +172,32 @@
#endif
/*
+ * Default 16-color palette for foreground and background
+ * (corresponding flags in comments).
+ * Taken from subsystems/win32/winsrv/consrv/frontends/gui/conwnd.c
+ */
+static const COLORREF ConsoleColors[16] =
+{
+ RGB(0, 0, 0), // (Black)
+ RGB(0, 0, 128), // BLUE
+ RGB(0, 128, 0), // GREEN
+ RGB(0, 128, 128), // BLUE | GREEN
+ RGB(128, 0, 0), // RED
+ RGB(128, 0, 128), // BLUE | RED
+ RGB(128, 128, 0), // GREEN | RED
+ RGB(192, 192, 192), // BLUE | GREEN | RED
+
+ RGB(128, 128, 128), // (Grey) INTENSITY
+ RGB(0, 0, 255), // BLUE | INTENSITY
+ RGB(0, 255, 0), // GREEN | INTENSITY
+ RGB(0, 255, 255), // BLUE | GREEN | INTENSITY
+ RGB(255, 0, 0), // RED | INTENSITY
+ RGB(255, 0, 255), // BLUE | RED | INTENSITY
+ RGB(255, 255, 0), // GREEN | RED | INTENSITY
+ RGB(255, 255, 255) // BLUE | GREEN | RED | INTENSITY
+};
+
+/*
* Console interface -- VGA-mode-agnostic
*/
typedef struct _CHAR_CELL
@@ -184,6 +210,7 @@
static LPVOID ConsoleFramebuffer = NULL; // Active framebuffer, points to
// either TextFramebuffer or a valid
// graphics framebuffer.
+static HPALETTE TextPaletteHandle = NULL;
static HPALETTE PaletteHandle = NULL;
static HANDLE StartEvent = NULL;
@@ -774,7 +801,7 @@
static VOID VgaWriteDac(BYTE Data)
{
- INT PaletteIndex;
+ INT i, PaletteIndex;
PALETTEENTRY Entry;
/* Set the value */
@@ -789,8 +816,20 @@
Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 2]);
Entry.peFlags = 0;
- /* Update the palette entry and set the palette change flag */
+ /* Update the palette entry */
SetPaletteEntries(PaletteHandle, PaletteIndex, 1, &Entry);
+
+ /* Check which text palette entries are affected */
+ for (i = 0; i <= VGA_AC_PAL_F_REG; i++)
+ {
+ if (VgaAcRegisters[i] == PaletteIndex)
+ {
+ /* Update the text palette entry */
+ SetPaletteEntries(TextPaletteHandle, i, 1, &Entry);
+ }
+ }
+
+ /* Set the palette changed flag */
PaletteChanged = TRUE;
/* Update the index */
@@ -800,6 +839,8 @@
static VOID VgaWriteAc(BYTE Data)
{
+ PALETTEENTRY Entry;
+
ASSERT(VgaAcIndex < VGA_AC_MAX_REG);
/* Save the value */
@@ -810,8 +851,17 @@
// DbgPrint(" AC Palette Writing %d to index %d\n", Data,
VgaAcIndex);
if (VgaAcRegisters[VgaAcIndex] != Data)
{
- /* Update the AC register and set the palette change flag */
+ /* Update the AC register */
VgaAcRegisters[VgaAcIndex] = Data;
+
+ /* Fill the entry structure */
+ Entry.peRed = VGA_DAC_TO_COLOR(VgaDacRegisters[Data * 3]);
+ Entry.peGreen = VGA_DAC_TO_COLOR(VgaDacRegisters[Data * 3 + 1]);
+ Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacRegisters[Data * 3 + 2]);
+ Entry.peFlags = 0;
+
+ /* Update the palette entry and set the palette change flag */
+ SetPaletteEntries(TextPaletteHandle, VgaAcIndex, 1, &Entry);
PaletteChanged = TRUE;
}
}
@@ -843,33 +893,62 @@
static BOOLEAN VgaInitializePalette(VOID)
{
- LPLOGPALETTE Palette;
-
- /* Allocate storage space for the palette */
+ INT i;
+ BOOLEAN Result = FALSE;
+ LPLOGPALETTE Palette, TextPalette;
+
+ /* Allocate storage space for the palettes */
Palette = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(LOGPALETTE) +
- VGA_MAX_COLORS * sizeof(PALETTEENTRY));
- if (Palette == NULL) return FALSE;
-
- /* Initialize the palette */
- Palette->palVersion = 0x0300;
+ VGA_MAX_COLORS * sizeof(PALETTEENTRY));
+ TextPalette = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(LOGPALETTE) +
+ (VGA_AC_PAL_F_REG + 1) *
sizeof(PALETTEENTRY));
+ if ((Palette == NULL) || (TextPalette == NULL)) goto Cleanup;
+
+ /* Initialize the palettes */
+ Palette->palVersion = TextPalette->palVersion = 0x0300;
Palette->palNumEntries = VGA_MAX_COLORS;
-
- /* Restore the default palette */
+ TextPalette->palNumEntries = VGA_AC_PAL_F_REG + 1;
+
+ /* Restore the default graphics palette */
VgaRestoreDefaultPalette(Palette->palPalEntry, Palette->palNumEntries);
- /* Create the palette */
+ /* Set the default text palette */
+ for (i = 0; i < TextPalette->palNumEntries; i++)
+ {
+ /* Set the palette entries */
+ TextPalette->palPalEntry[i].peRed = GetRValue(ConsoleColors[i]);
+ TextPalette->palPalEntry[i].peGreen = GetGValue(ConsoleColors[i]);
+ TextPalette->palPalEntry[i].peBlue = GetBValue(ConsoleColors[i]);
+ TextPalette->palPalEntry[i].peFlags = 0;
+ }
+
+ /* Create the palettes */
PaletteHandle = CreatePalette(Palette);
-
- /* Free the palette */
- HeapFree(GetProcessHeap(), 0, Palette);
-
- /* Fail if the palette wasn't successfully created... */
- if (PaletteHandle == NULL) return FALSE;
-
- /* ... otherwise return success */
- return TRUE;
+ TextPaletteHandle = CreatePalette(TextPalette);
+
+ if (PaletteHandle != NULL && TextPaletteHandle != NULL)
+ {
+ /* The palettes have been created successfully */
+ Result = TRUE;
+ }
+
+Cleanup:
+ /* Free the palettes */
+ if (Palette) HeapFree(GetProcessHeap(), 0, Palette);
+ if (TextPalette) HeapFree(GetProcessHeap(), 0, TextPalette);
+
+ if (!Result)
+ {
+ /* Something failed, delete the palettes */
+ if (PaletteHandle) DeleteObject(PaletteHandle);
+ if (TextPaletteHandle) DeleteObject(TextPaletteHandle);
+ }
+
+ return Result;
}
static BOOL VgaEnterGraphicsMode(PCOORD Resolution)
@@ -1001,7 +1080,7 @@
* screen-buffers, which is a new feature on ReactOS).
*/
SetConsolePalette(TextConsoleBuffer,
- PaletteHandle,
+ TextPaletteHandle,
SYSPAL_NOSTATIC256);
/* Set the screen mode flag */