/* Graphics mode */
static HANDLE GraphicsConsoleBuffer = NULL;
static HANDLE ConsoleMutex = NULL;
-static BOOLEAN DoubleVision = FALSE;
+/* DoubleVision support */
+static BOOLEAN DoubleWidth = FALSE;
+static BOOLEAN DoubleHeight = FALSE;
/*
* VGA Hardware
return Result;
}
+static VOID VgaSetActiveScreenBuffer(HANDLE ScreenBuffer)
+{
+ /* Set the active buffer */
+ SetConsoleActiveScreenBuffer(ScreenBuffer);
+
+ /* Reinitialize the VDM menu */
+ DestroyVdmMenu();
+ CreateVdmMenu(ScreenBuffer);
+}
+
static BOOL VgaEnterGraphicsMode(PCOORD Resolution)
{
DWORD i;
LONG Height = Resolution->Y;
/* Use DoubleVision mode if the resolution is too small */
- if (Width < VGA_MINIMUM_WIDTH && Height < VGA_MINIMUM_HEIGHT)
- {
- DoubleVision = TRUE;
- Width *= 2;
- Height *= 2;
- }
- else
- {
- DoubleVision = FALSE;
- }
+ DoubleWidth = (Width < VGA_MINIMUM_WIDTH);
+ if (DoubleWidth) Width *= 2;
+ DoubleHeight = (Height < VGA_MINIMUM_HEIGHT);
+ if (DoubleHeight) Height *= 2;
/* Fill the bitmap info header */
- ZeroMemory(&BitmapInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
- BitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ RtlZeroMemory(&BitmapInfo->bmiHeader, sizeof(BitmapInfo->bmiHeader));
+ BitmapInfo->bmiHeader.biSize = sizeof(BitmapInfo->bmiHeader);
BitmapInfo->bmiHeader.biWidth = Width;
BitmapInfo->bmiHeader.biHeight = Height;
BitmapInfo->bmiHeader.biBitCount = 8;
ConsoleMutex = GraphicsBufferInfo.hMutex;
/* Clear the framebuffer */
- ZeroMemory(ConsoleFramebuffer, BitmapInfo->bmiHeader.biSizeImage);
+ RtlZeroMemory(ConsoleFramebuffer, BitmapInfo->bmiHeader.biSizeImage);
/* Set the active buffer */
- SetConsoleActiveScreenBuffer(GraphicsConsoleBuffer);
+ VgaSetActiveScreenBuffer(GraphicsConsoleBuffer);
/* Set the graphics mode palette */
SetConsolePalette(GraphicsConsoleBuffer,
ReleaseMutex(ConsoleMutex);
/* Switch back to the default console text buffer */
- // SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+ // VgaSetActiveScreenBuffer(TextConsoleBuffer);
/* Cleanup the video data */
CloseHandle(ConsoleMutex);
ConsoleFramebuffer = NULL;
CloseHandle(GraphicsConsoleBuffer);
GraphicsConsoleBuffer = NULL;
- DoubleVision = FALSE;
+
+ DoubleWidth = FALSE;
+ DoubleHeight = FALSE;
}
static BOOL VgaEnterTextMode(PCOORD Resolution)
DPRINT1("VgaEnterTextMode\n");
/* Switch to the text buffer */
- SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+ VgaSetActiveScreenBuffer(TextConsoleBuffer);
/* Adjust the text framebuffer if we changed the resolution */
if (TextResolution.X != Resolution->X ||
/* Enter new text mode */
if (!VgaEnterTextMode(&Resolution))
{
- DisplayMessage(L"An unexpected VGA error occurred while switching into text mode.");
+ DisplayMessage(L"An unexpected VGA error occurred while switching into text mode. Error: %u", GetLastError());
EmulatorTerminate();
return;
}
/* Enter graphics mode */
if (!VgaEnterGraphicsMode(&Resolution))
{
- DisplayMessage(L"An unexpected VGA error occurred while switching into graphics mode.");
+ DisplayMessage(L"An unexpected VGA error occurred while switching into graphics mode. Error: %u", GetLastError());
EmulatorTerminate();
return;
}
}
/* Take into account DoubleVision mode when checking for pixel updates */
- if (DoubleVision)
+ if (DoubleWidth && DoubleHeight)
{
/* Now check if the resulting pixel data has changed */
- if (GraphicsBuffer[(i * Resolution.X * 4) + (j * 2)] != PixelData)
+ if (GraphicsBuffer[(i * 2 * Resolution.X * 2) + (j * 2)] != PixelData)
{
/* Yes, write the new value */
- GraphicsBuffer[(i * Resolution.X * 4) + (j * 2)] = PixelData;
- GraphicsBuffer[(i * Resolution.X * 4) + (j * 2 + 1)] = PixelData;
+ GraphicsBuffer[(i * 2 * Resolution.X * 2) + (j * 2)] = PixelData;
+ GraphicsBuffer[(i * 2 * Resolution.X * 2) + (j * 2 + 1)] = PixelData;
GraphicsBuffer[((i * 2 + 1) * Resolution.X * 2) + (j * 2)] = PixelData;
GraphicsBuffer[((i * 2 + 1) * Resolution.X * 2) + (j * 2 + 1)] = PixelData;
VgaMarkForUpdate(i, j);
}
}
- else
+ else if (DoubleWidth && !DoubleHeight)
+ {
+ /* Now check if the resulting pixel data has changed */
+ if (GraphicsBuffer[(i * Resolution.X * 2) + (j * 2)] != PixelData)
+ {
+ /* Yes, write the new value */
+ GraphicsBuffer[(i * Resolution.X * 2) + (j * 2)] = PixelData;
+ GraphicsBuffer[(i * Resolution.X * 2) + (j * 2 + 1)] = PixelData;
+
+ /* Mark the specified pixel as changed */
+ VgaMarkForUpdate(i, j);
+ }
+ }
+ else if (!DoubleWidth && DoubleHeight)
+ {
+ /* Now check if the resulting pixel data has changed */
+ if (GraphicsBuffer[(i * 2 * Resolution.X) + j] != PixelData)
+ {
+ /* Yes, write the new value */
+ GraphicsBuffer[(i * 2 * Resolution.X) + j] = PixelData;
+ GraphicsBuffer[((i * 2 + 1) * Resolution.X) + j] = PixelData;
+
+ /* Mark the specified pixel as changed */
+ VgaMarkForUpdate(i, j);
+ }
+ }
+ else // if (!DoubleWidth && !DoubleHeight)
{
/* Now check if the resulting pixel data has changed */
if (GraphicsBuffer[i * Resolution.X + j] != PixelData)
CursorMoved = FALSE;
}
-static BYTE WINAPI VgaReadPort(ULONG Port)
+static BYTE WINAPI VgaReadPort(USHORT Port)
{
DPRINT("VgaReadPort: Port 0x%X\n", Port);
return 0;
}
-static VOID WINAPI VgaWritePort(ULONG Port, BYTE Data)
+static VOID WINAPI VgaWritePort(USHORT Port, BYTE Data)
{
DPRINT("VgaWritePort: Port 0x%X, Data 0x%02X\n", Port, Data);
ConsoleBufferHandle = GraphicsConsoleBuffer;
/* In DoubleVision mode, scale the update rectangle */
- if (DoubleVision)
+ if (DoubleWidth)
{
UpdateRectangle.Left *= 2;
- UpdateRectangle.Top *= 2;
- UpdateRectangle.Right = UpdateRectangle.Right * 2 + 1;
+ UpdateRectangle.Right = UpdateRectangle.Right * 2 + 1;
+ }
+ if (DoubleHeight)
+ {
+ UpdateRectangle.Top *= 2;
UpdateRectangle.Bottom = UpdateRectangle.Bottom * 2 + 1;
}
}
VOID VgaClearMemory(VOID)
{
- ZeroMemory(VgaMemory, sizeof(VgaMemory));
+ RtlZeroMemory(VgaMemory, sizeof(VgaMemory));
}
VOID VgaResetPalette(VOID)
PaletteChanged = TRUE;
}
+VOID VgaWriteFont(UINT FontNumber, CONST UCHAR *FontData, UINT Height)
+{
+ UINT i, j;
+ PUCHAR FontMemory = (PUCHAR)&VgaMemory[VGA_BANK_SIZE * VGA_FONT_BANK + (FontNumber * VGA_FONT_SIZE)];
+
+ ASSERT(Height <= VGA_MAX_FONT_HEIGHT);
+ for (i = 0 ; i < VGA_FONT_CHARACTERS; i++)
+ {
+ /* Write the character */
+ for (j = 0; j < Height; j++)
+ {
+ FontMemory[i * VGA_MAX_FONT_HEIGHT + j] = FontData[i * Height + j];
+ }
+ /* Clear the unused part */
+ for (j = Height; j < VGA_MAX_FONT_HEIGHT; j++)
+ {
+ FontMemory[i * VGA_MAX_FONT_HEIGHT + j] = 0;
+ }
+ }
+}
+
+VOID ScreenEventHandler(PWINDOW_BUFFER_SIZE_RECORD ScreenEvent)
+{
+ DPRINT1("Screen events not handled\n");
+}
BOOL VgaAttachToConsole(VOID)
{
SMALL_RECT ConRect;
/* Restore the old screen buffer */
- SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+ VgaSetActiveScreenBuffer(TextConsoleBuffer);
/* Restore the original console size */
ConRect.Left = 0;
/***/ VgaResetPalette(); /***/
/* Switch to the text buffer */
- SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+ VgaSetActiveScreenBuffer(TextConsoleBuffer);
/* Clear the VGA memory */
VgaClearMemory();