mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[NTVDM]
- Do not recalculate at each refresh the new resolution that usually does not change (if it changes because of a modification of some VGA register, we detect that, and we change the vga mode). So keep the current resolution and use it in paint functions. - Really reenter a new text/graphic mode when needed (ie. when alphanumeric bit and computed resolution change), this avoids useless console screenbuffers recreations (and flickering), things go faster, yet the VGA registers are still updated (as expected). See r65379, r65018 and r65015 for more details. svn path=/trunk/; revision=65424
This commit is contained in:
parent
9219f1f8ef
commit
5dbe74176e
1 changed files with 55 additions and 40 deletions
|
@ -284,12 +284,14 @@ static BOOLEAN ModeChanged = FALSE;
|
||||||
static BOOLEAN CursorChanged = FALSE;
|
static BOOLEAN CursorChanged = FALSE;
|
||||||
static BOOLEAN PaletteChanged = FALSE;
|
static BOOLEAN PaletteChanged = FALSE;
|
||||||
|
|
||||||
static
|
typedef enum _SCREEN_MODE
|
||||||
enum SCREEN_MODE
|
|
||||||
{
|
{
|
||||||
TEXT_MODE,
|
TEXT_MODE,
|
||||||
GRAPHICS_MODE
|
GRAPHICS_MODE
|
||||||
} ScreenMode = TEXT_MODE;
|
} SCREEN_MODE, *PSCREEN_MODE;
|
||||||
|
|
||||||
|
static SCREEN_MODE ScreenMode = TEXT_MODE;
|
||||||
|
static COORD CurrResolution = {0};
|
||||||
|
|
||||||
static SMALL_RECT UpdateRectangle = { 0, 0, 0, 0 };
|
static SMALL_RECT UpdateRectangle = { 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
@ -920,8 +922,6 @@ static VOID VgaLeaveGraphicsMode(VOID)
|
||||||
|
|
||||||
static BOOL VgaEnterTextMode(PCOORD Resolution)
|
static BOOL VgaEnterTextMode(PCOORD Resolution)
|
||||||
{
|
{
|
||||||
DPRINT1("VgaEnterTextMode\n");
|
|
||||||
|
|
||||||
/* Switch to the text buffer */
|
/* Switch to the text buffer */
|
||||||
VgaSetActiveScreenBuffer(TextConsoleBuffer);
|
VgaSetActiveScreenBuffer(TextConsoleBuffer);
|
||||||
|
|
||||||
|
@ -977,7 +977,20 @@ static VOID VgaLeaveTextMode(VOID)
|
||||||
|
|
||||||
static VOID VgaChangeMode(VOID)
|
static VOID VgaChangeMode(VOID)
|
||||||
{
|
{
|
||||||
COORD Resolution = VgaGetDisplayResolution();
|
COORD NewResolution = VgaGetDisplayResolution();
|
||||||
|
SCREEN_MODE NewScreenMode =
|
||||||
|
!(VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA) ? TEXT_MODE
|
||||||
|
: GRAPHICS_MODE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No need to switch to a different screen mode + resolution
|
||||||
|
* if the new ones are the same as the old ones.
|
||||||
|
*/
|
||||||
|
if ((ScreenMode == NewScreenMode) &&
|
||||||
|
(CurrResolution.X == NewResolution.X && CurrResolution.Y == NewResolution.Y))
|
||||||
|
{
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
if (ScreenMode == GRAPHICS_MODE)
|
if (ScreenMode == GRAPHICS_MODE)
|
||||||
{
|
{
|
||||||
|
@ -990,11 +1003,16 @@ static VOID VgaChangeMode(VOID)
|
||||||
VgaLeaveTextMode();
|
VgaLeaveTextMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update the current resolution */
|
||||||
|
CurrResolution = NewResolution;
|
||||||
|
|
||||||
|
/* The new screen mode will be updated via the VgaEnterText/GraphicsMode functions */
|
||||||
|
|
||||||
/* Check if the new mode is alphanumeric */
|
/* Check if the new mode is alphanumeric */
|
||||||
if (!(VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA))
|
if (NewScreenMode == TEXT_MODE)
|
||||||
{
|
{
|
||||||
/* Enter new text mode */
|
/* Enter new text mode */
|
||||||
if (!VgaEnterTextMode(&Resolution))
|
if (!VgaEnterTextMode(&CurrResolution))
|
||||||
{
|
{
|
||||||
DisplayMessage(L"An unexpected VGA error occurred while switching into text mode. Error: %u", GetLastError());
|
DisplayMessage(L"An unexpected VGA error occurred while switching into text mode. Error: %u", GetLastError());
|
||||||
EmulatorTerminate();
|
EmulatorTerminate();
|
||||||
|
@ -1004,7 +1022,7 @@ static VOID VgaChangeMode(VOID)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Enter graphics mode */
|
/* Enter graphics mode */
|
||||||
if (!VgaEnterGraphicsMode(&Resolution))
|
if (!VgaEnterGraphicsMode(&CurrResolution))
|
||||||
{
|
{
|
||||||
DisplayMessage(L"An unexpected VGA error occurred while switching into graphics mode. Error: %u", GetLastError());
|
DisplayMessage(L"An unexpected VGA error occurred while switching into graphics mode. Error: %u", GetLastError());
|
||||||
EmulatorTerminate();
|
EmulatorTerminate();
|
||||||
|
@ -1012,12 +1030,14 @@ static VOID VgaChangeMode(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
|
||||||
/* Trigger a full update of the screen */
|
/* Trigger a full update of the screen */
|
||||||
NeedsUpdate = TRUE;
|
NeedsUpdate = TRUE;
|
||||||
UpdateRectangle.Left = 0;
|
UpdateRectangle.Left = 0;
|
||||||
UpdateRectangle.Top = 0;
|
UpdateRectangle.Top = 0;
|
||||||
UpdateRectangle.Right = Resolution.X;
|
UpdateRectangle.Right = CurrResolution.X;
|
||||||
UpdateRectangle.Bottom = Resolution.Y;
|
UpdateRectangle.Bottom = CurrResolution.Y;
|
||||||
|
|
||||||
/* Reset the mode change flag */
|
/* Reset the mode change flag */
|
||||||
ModeChanged = FALSE;
|
ModeChanged = FALSE;
|
||||||
|
@ -1026,7 +1046,6 @@ static VOID VgaChangeMode(VOID)
|
||||||
static VOID VgaUpdateFramebuffer(VOID)
|
static VOID VgaUpdateFramebuffer(VOID)
|
||||||
{
|
{
|
||||||
SHORT i, j, k;
|
SHORT i, j, k;
|
||||||
COORD Resolution = VgaGetDisplayResolution();
|
|
||||||
DWORD AddressSize = VgaGetAddressSize();
|
DWORD AddressSize = VgaGetAddressSize();
|
||||||
DWORD Address = MAKEWORD(VgaCrtcRegisters[VGA_CRTC_START_ADDR_LOW_REG],
|
DWORD Address = MAKEWORD(VgaCrtcRegisters[VGA_CRTC_START_ADDR_LOW_REG],
|
||||||
VgaCrtcRegisters[VGA_CRTC_START_ADDR_HIGH_REG]);
|
VgaCrtcRegisters[VGA_CRTC_START_ADDR_HIGH_REG]);
|
||||||
|
@ -1058,7 +1077,7 @@ static VOID VgaUpdateFramebuffer(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop through the scanlines */
|
/* Loop through the scanlines */
|
||||||
for (i = 0; i < Resolution.Y; i++)
|
for (i = 0; i < CurrResolution.Y; i++)
|
||||||
{
|
{
|
||||||
if ((VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_OE) && (i & 1))
|
if ((VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_OE) && (i & 1))
|
||||||
{
|
{
|
||||||
|
@ -1067,7 +1086,7 @@ static VOID VgaUpdateFramebuffer(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop through the pixels */
|
/* Loop through the pixels */
|
||||||
for (j = 0; j < Resolution.X; j++)
|
for (j = 0; j < CurrResolution.X; j++)
|
||||||
{
|
{
|
||||||
BYTE PixelData = 0;
|
BYTE PixelData = 0;
|
||||||
|
|
||||||
|
@ -1189,13 +1208,13 @@ static VOID VgaUpdateFramebuffer(VOID)
|
||||||
if (DoubleWidth && DoubleHeight)
|
if (DoubleWidth && DoubleHeight)
|
||||||
{
|
{
|
||||||
/* Now check if the resulting pixel data has changed */
|
/* Now check if the resulting pixel data has changed */
|
||||||
if (GraphicsBuffer[(i * 2 * Resolution.X * 2) + (j * 2)] != PixelData)
|
if (GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j * 2)] != PixelData)
|
||||||
{
|
{
|
||||||
/* Yes, write the new value */
|
/* Yes, write the new value */
|
||||||
GraphicsBuffer[(i * 2 * Resolution.X * 2) + (j * 2)] = PixelData;
|
GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j * 2)] = PixelData;
|
||||||
GraphicsBuffer[(i * 2 * Resolution.X * 2) + (j * 2 + 1)] = PixelData;
|
GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j * 2 + 1)] = PixelData;
|
||||||
GraphicsBuffer[((i * 2 + 1) * Resolution.X * 2) + (j * 2)] = PixelData;
|
GraphicsBuffer[((i * 2 + 1) * CurrResolution.X * 2) + (j * 2)] = PixelData;
|
||||||
GraphicsBuffer[((i * 2 + 1) * Resolution.X * 2) + (j * 2 + 1)] = PixelData;
|
GraphicsBuffer[((i * 2 + 1) * CurrResolution.X * 2) + (j * 2 + 1)] = PixelData;
|
||||||
|
|
||||||
/* Mark the specified pixel as changed */
|
/* Mark the specified pixel as changed */
|
||||||
VgaMarkForUpdate(i, j);
|
VgaMarkForUpdate(i, j);
|
||||||
|
@ -1204,11 +1223,11 @@ static VOID VgaUpdateFramebuffer(VOID)
|
||||||
else if (DoubleWidth && !DoubleHeight)
|
else if (DoubleWidth && !DoubleHeight)
|
||||||
{
|
{
|
||||||
/* Now check if the resulting pixel data has changed */
|
/* Now check if the resulting pixel data has changed */
|
||||||
if (GraphicsBuffer[(i * Resolution.X * 2) + (j * 2)] != PixelData)
|
if (GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2)] != PixelData)
|
||||||
{
|
{
|
||||||
/* Yes, write the new value */
|
/* Yes, write the new value */
|
||||||
GraphicsBuffer[(i * Resolution.X * 2) + (j * 2)] = PixelData;
|
GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2)] = PixelData;
|
||||||
GraphicsBuffer[(i * Resolution.X * 2) + (j * 2 + 1)] = PixelData;
|
GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2 + 1)] = PixelData;
|
||||||
|
|
||||||
/* Mark the specified pixel as changed */
|
/* Mark the specified pixel as changed */
|
||||||
VgaMarkForUpdate(i, j);
|
VgaMarkForUpdate(i, j);
|
||||||
|
@ -1217,11 +1236,11 @@ static VOID VgaUpdateFramebuffer(VOID)
|
||||||
else if (!DoubleWidth && DoubleHeight)
|
else if (!DoubleWidth && DoubleHeight)
|
||||||
{
|
{
|
||||||
/* Now check if the resulting pixel data has changed */
|
/* Now check if the resulting pixel data has changed */
|
||||||
if (GraphicsBuffer[(i * 2 * Resolution.X) + j] != PixelData)
|
if (GraphicsBuffer[(i * 2 * CurrResolution.X) + j] != PixelData)
|
||||||
{
|
{
|
||||||
/* Yes, write the new value */
|
/* Yes, write the new value */
|
||||||
GraphicsBuffer[(i * 2 * Resolution.X) + j] = PixelData;
|
GraphicsBuffer[(i * 2 * CurrResolution.X) + j] = PixelData;
|
||||||
GraphicsBuffer[((i * 2 + 1) * Resolution.X) + j] = PixelData;
|
GraphicsBuffer[((i * 2 + 1) * CurrResolution.X) + j] = PixelData;
|
||||||
|
|
||||||
/* Mark the specified pixel as changed */
|
/* Mark the specified pixel as changed */
|
||||||
VgaMarkForUpdate(i, j);
|
VgaMarkForUpdate(i, j);
|
||||||
|
@ -1230,10 +1249,10 @@ static VOID VgaUpdateFramebuffer(VOID)
|
||||||
else // if (!DoubleWidth && !DoubleHeight)
|
else // if (!DoubleWidth && !DoubleHeight)
|
||||||
{
|
{
|
||||||
/* Now check if the resulting pixel data has changed */
|
/* Now check if the resulting pixel data has changed */
|
||||||
if (GraphicsBuffer[i * Resolution.X + j] != PixelData)
|
if (GraphicsBuffer[i * CurrResolution.X + j] != PixelData)
|
||||||
{
|
{
|
||||||
/* Yes, write the new value */
|
/* Yes, write the new value */
|
||||||
GraphicsBuffer[i * Resolution.X + j] = PixelData;
|
GraphicsBuffer[i * CurrResolution.X + j] = PixelData;
|
||||||
|
|
||||||
/* Mark the specified pixel as changed */
|
/* Mark the specified pixel as changed */
|
||||||
VgaMarkForUpdate(i, j);
|
VgaMarkForUpdate(i, j);
|
||||||
|
@ -1268,10 +1287,10 @@ static VOID VgaUpdateFramebuffer(VOID)
|
||||||
CHAR_CELL CharInfo;
|
CHAR_CELL CharInfo;
|
||||||
|
|
||||||
/* Loop through the scanlines */
|
/* Loop through the scanlines */
|
||||||
for (i = 0; i < Resolution.Y; i++)
|
for (i = 0; i < CurrResolution.Y; i++)
|
||||||
{
|
{
|
||||||
/* Loop through the characters */
|
/* Loop through the characters */
|
||||||
for (j = 0; j < Resolution.X; j++)
|
for (j = 0; j < CurrResolution.X; j++)
|
||||||
{
|
{
|
||||||
CurrentAddr = LOWORD((Address + j) * AddressSize);
|
CurrentAddr = LOWORD((Address + j) * AddressSize);
|
||||||
|
|
||||||
|
@ -1282,11 +1301,11 @@ static VOID VgaUpdateFramebuffer(VOID)
|
||||||
CharInfo.Attributes = VgaMemory[CurrentAddr + VGA_BANK_SIZE];
|
CharInfo.Attributes = VgaMemory[CurrentAddr + VGA_BANK_SIZE];
|
||||||
|
|
||||||
/* Now check if the resulting character data has changed */
|
/* Now check if the resulting character data has changed */
|
||||||
if ((CharBuffer[i * Resolution.X + j].Char != CharInfo.Char) ||
|
if ((CharBuffer[i * CurrResolution.X + j].Char != CharInfo.Char) ||
|
||||||
(CharBuffer[i * Resolution.X + j].Attributes != CharInfo.Attributes))
|
(CharBuffer[i * CurrResolution.X + j].Attributes != CharInfo.Attributes))
|
||||||
{
|
{
|
||||||
/* Yes, write the new value */
|
/* Yes, write the new value */
|
||||||
CharBuffer[i * Resolution.X + j] = CharInfo;
|
CharBuffer[i * CurrResolution.X + j] = CharInfo;
|
||||||
|
|
||||||
/* Mark the specified cell as changed */
|
/* Mark the specified cell as changed */
|
||||||
VgaMarkForUpdate(i, j);
|
VgaMarkForUpdate(i, j);
|
||||||
|
@ -1787,7 +1806,6 @@ COORD VgaGetDisplayResolution(VOID)
|
||||||
VOID VgaRefreshDisplay(VOID)
|
VOID VgaRefreshDisplay(VOID)
|
||||||
{
|
{
|
||||||
HANDLE ConsoleBufferHandle = NULL;
|
HANDLE ConsoleBufferHandle = NULL;
|
||||||
COORD Resolution;
|
|
||||||
|
|
||||||
/* Set the vertical retrace flag */
|
/* Set the vertical retrace flag */
|
||||||
InVerticalRetrace = TRUE;
|
InVerticalRetrace = TRUE;
|
||||||
|
@ -1802,17 +1820,14 @@ VOID VgaRefreshDisplay(VOID)
|
||||||
/* Change the text cursor appearance */
|
/* Change the text cursor appearance */
|
||||||
if (CursorChanged) VgaUpdateTextCursor();
|
if (CursorChanged) VgaUpdateTextCursor();
|
||||||
|
|
||||||
/* Retrieve the current resolution */
|
|
||||||
Resolution = VgaGetDisplayResolution();
|
|
||||||
|
|
||||||
if (PaletteChanged)
|
if (PaletteChanged)
|
||||||
{
|
{
|
||||||
/* Trigger a full update of the screen */
|
/* Trigger a full update of the screen */
|
||||||
NeedsUpdate = TRUE;
|
NeedsUpdate = TRUE;
|
||||||
UpdateRectangle.Left = 0;
|
UpdateRectangle.Left = 0;
|
||||||
UpdateRectangle.Top = 0;
|
UpdateRectangle.Top = 0;
|
||||||
UpdateRectangle.Right = Resolution.X;
|
UpdateRectangle.Right = CurrResolution.X;
|
||||||
UpdateRectangle.Bottom = Resolution.Y;
|
UpdateRectangle.Bottom = CurrResolution.Y;
|
||||||
|
|
||||||
PaletteChanged = FALSE;
|
PaletteChanged = FALSE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue