Author: aandrejevic
Date: Thu Mar 10 00:59:50 2016
New Revision: 70990
URL:
http://svn.reactos.org/svn/reactos?rev=70990&view=rev
Log:
[NTVDM]
Implement PaintMouseCursor and EraseMouseCursor for video modes 12h and 13h.
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.h
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c [iso-8859-1] Thu Mar 10 00:59:50
2016
@@ -146,19 +146,11 @@
static VOID PaintMouseCursor(VOID)
{
- COORD Position = DriverState.Position;
-
- /* Apply the clipping rectangle */
- if (Position.X < DriverState.MinX) Position.X = DriverState.MinX;
- if (Position.X > DriverState.MaxX) Position.X = DriverState.MaxX;
- if (Position.Y < DriverState.MinY) Position.Y = DriverState.MinY;
- if (Position.Y > DriverState.MaxY) Position.Y = DriverState.MaxY;
-
if (Bda->VideoMode <= 3)
{
WORD Character;
- WORD CellX = Position.X / 8;
- WORD CellY = Position.Y / 8;
+ WORD CellX = DriverState.Position.X / 8;
+ WORD CellY = DriverState.Position.Y / 8;
DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Bda->VideoPage *
Bda->VideoPageSize);
EmulatorReadMemory(&EmulatorContext,
@@ -177,6 +169,109 @@
(LPVOID)&Character,
sizeof(WORD));
}
+ else if (Bda->VideoMode == 0x12)
+ {
+ INT i, j;
+ BYTE OldMask;
+ BYTE OldMap;
+
+ /* Save the write mask */
+ IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_MASK_REG);
+ OldMask = IOReadB(VGA_SEQ_DATA);
+
+ /* And the selected reading plane */
+ IOWriteB(VGA_GC_INDEX, VGA_GC_READ_MAP_SEL_REG);
+ OldMap = IOReadB(VGA_GC_DATA);
+
+ for (i = 0; i < 16; i++)
+ {
+ WORD CursorLine[4];
+ DWORD VideoAddress = TO_LINEAR(GRAPHICS_VIDEO_SEG, Bda->VideoPage *
Bda->VideoPageSize)
+ + ((DriverState.Position.Y + i) * 640 +
DriverState.Position.X) / 8;
+
+ for (j = 0; j < 4; j++)
+ {
+ /* Select the reading plane */
+ IOWriteB(VGA_GC_INDEX, VGA_GC_READ_MAP_SEL_REG);
+ IOWriteB(VGA_GC_DATA, j);
+
+ /* Read a part of the scanline */
+ EmulatorReadMemory(&EmulatorContext, VideoAddress,
&CursorLine[j], sizeof(CursorLine[j]));
+ }
+
+ /* Save the data below the cursor */
+ for (j = 0; j < 16; j++)
+ {
+ DriverState.GraphicsData[i * 16 + j] = 0;
+
+ if (CursorLine[0] & (1 << j)) DriverState.GraphicsData[i * 16 +
j] |= 1 << 0;
+ if (CursorLine[1] & (1 << j)) DriverState.GraphicsData[i * 16 +
j] |= 1 << 1;
+ if (CursorLine[2] & (1 << j)) DriverState.GraphicsData[i * 16 +
j] |= 1 << 2;
+ if (CursorLine[3] & (1 << j)) DriverState.GraphicsData[i * 16 +
j] |= 1 << 3;
+ }
+
+ for (j = 0; j < 4; j++)
+ {
+ /* Apply the screen mask */
+ CursorLine[j] &=
MAKEWORD(HIBYTE(DriverState.GraphicsCursor.ScreenMask[i]),
+
LOBYTE(DriverState.GraphicsCursor.ScreenMask[i]));
+
+ /* And the cursor mask */
+ CursorLine[j] ^=
MAKEWORD(HIBYTE(DriverState.GraphicsCursor.CursorMask[i]),
+
LOBYTE(DriverState.GraphicsCursor.CursorMask[i]));
+
+ /* Select the writing plane */
+ IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_MASK_REG);
+ IOWriteB(VGA_SEQ_DATA, 1 << j);
+
+ /* Write the cursor data for this scanline */
+ EmulatorWriteMemory(&EmulatorContext, VideoAddress,
&CursorLine[j], sizeof(CursorLine[j]));
+ }
+ }
+
+ /* Restore the old mask */
+ IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_MASK_REG);
+ IOWriteB(VGA_SEQ_DATA, OldMask);
+
+ /* And the old reading plane */
+ IOWriteB(VGA_GC_INDEX, VGA_GC_READ_MAP_SEL_REG);
+ IOWriteB(VGA_GC_DATA, OldMap);
+ }
+ else if (Bda->VideoMode == 0x13)
+ {
+ INT i, j;
+
+ for (i = 0; i < 16; i++)
+ {
+ BYTE CursorLine[16];
+ DWORD VideoAddress = TO_LINEAR(GRAPHICS_VIDEO_SEG, Bda->VideoPage *
Bda->VideoPageSize)
+ + (DriverState.Position.Y + i) * 320 +
DriverState.Position.X;
+
+ /* Read a part of the scanline */
+ EmulatorReadMemory(&EmulatorContext,
+ VideoAddress,
+ &DriverState.GraphicsData[i * 16],
+ sizeof(CursorLine));
+
+ for (j = 0; j < 16; j++)
+ {
+ /* Apply the screen mask by leaving only the masked pixels intact */
+ CursorLine[j] = (DriverState.GraphicsCursor.ScreenMask[i] & (1
<< j))
+ ? DriverState.GraphicsData[i * 16]
+ : 0x00;
+
+ /* Apply the cursor mask... */
+ if (DriverState.GraphicsCursor.CursorMask[i] & (1 << j))
+ {
+ /* ... by inverting the color of each masked pixel */
+ CursorLine[j] ^= 0x0F;
+ }
+ }
+
+ /* Write the cursor data for this scanline */
+ EmulatorWriteMemory(&EmulatorContext, VideoAddress, &CursorLine,
sizeof(CursorLine));
+ }
+ }
else
{
// TODO: NOT IMPLEMENTED
@@ -186,18 +281,10 @@
static VOID EraseMouseCursor(VOID)
{
- COORD Position = DriverState.Position;
-
- /* Apply the clipping rectangle */
- if (Position.X < DriverState.MinX) Position.X = DriverState.MinX;
- if (Position.X > DriverState.MaxX) Position.X = DriverState.MaxX;
- if (Position.Y < DriverState.MinY) Position.Y = DriverState.MinY;
- if (Position.Y > DriverState.MaxY) Position.Y = DriverState.MaxY;
-
if (Bda->VideoMode <= 3)
{
- WORD CellX = Position.X / 8;
- WORD CellY = Position.Y / 8;
+ WORD CellX = DriverState.Position.X / 8;
+ WORD CellY = DriverState.Position.Y / 8;
DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Bda->VideoPage *
Bda->VideoPageSize);
EmulatorWriteMemory(&EmulatorContext,
@@ -205,6 +292,61 @@
+ (CellY * Bda->ScreenColumns + CellX) * sizeof(WORD),
(LPVOID)&DriverState.Character,
sizeof(WORD));
+ }
+ else if (Bda->VideoMode == 0x12)
+ {
+ INT i, j;
+ BYTE OldMask;
+
+ /* Save the write mask */
+ IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_MASK_REG);
+ OldMask = IOReadB(VGA_SEQ_DATA);
+
+ for (i = 0; i < 16; i++)
+ {
+ WORD CursorLine[4] = {0};
+ DWORD VideoAddress = TO_LINEAR(GRAPHICS_VIDEO_SEG, Bda->VideoPage *
Bda->VideoPageSize)
+ + ((DriverState.Position.Y + i) * 640 +
DriverState.Position.X) / 8;
+
+ /* Restore the data that was below the cursor */
+ for (j = 0; j < 16; j++)
+ {
+ if (DriverState.GraphicsData[i * 16 + j] & (1 << 0))
CursorLine[0] |= 1 << j;
+ if (DriverState.GraphicsData[i * 16 + j] & (1 << 1))
CursorLine[1] |= 1 << j;
+ if (DriverState.GraphicsData[i * 16 + j] & (1 << 2))
CursorLine[2] |= 1 << j;
+ if (DriverState.GraphicsData[i * 16 + j] & (1 << 3))
CursorLine[3] |= 1 << j;
+ }
+
+ for (j = 0; j < 4; j++)
+ {
+ /* Select the writing plane */
+ IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_MASK_REG);
+ IOWriteB(VGA_SEQ_DATA, 1 << j);
+
+ /* Write the original data for this scanline */
+ EmulatorWriteMemory(&EmulatorContext, VideoAddress,
&CursorLine[j], sizeof(CursorLine[j]));
+ }
+ }
+
+ /* Restore the old mask */
+ IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_MASK_REG);
+ IOWriteB(VGA_SEQ_DATA, OldMask);
+ }
+ else if (Bda->VideoMode == 0x13)
+ {
+ INT i;
+
+ for (i = 0; i < 16; i++)
+ {
+ DWORD VideoAddress = TO_LINEAR(GRAPHICS_VIDEO_SEG, Bda->VideoPage *
Bda->VideoPageSize)
+ + (DriverState.Position.Y + i) * 320 +
DriverState.Position.X;
+
+ /* Write the original data for this scanline */
+ EmulatorWriteMemory(&EmulatorContext,
+ VideoAddress,
+ &DriverState.GraphicsData[i * 16],
+ 16 * sizeof(BYTE));
+ }
}
else
{
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/mouse32.h [iso-8859-1] Thu Mar 10 00:59:50
2016
@@ -71,6 +71,8 @@
WORD ScreenMask[16];
WORD CursorMask[16];
} GraphicsCursor;
+
+ BYTE GraphicsData[256];
} MOUSE_DRIVER_STATE, *PMOUSE_DRIVER_STATE;
/* FUNCTIONS ******************************************************************/