mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
[NTVDM]
Implement PaintMouseCursor and EraseMouseCursor for video modes 12h and 13h. svn path=/trunk/; revision=70990
This commit is contained in:
@@ -146,19 +146,11 @@ static VOID DosMouseDisable(VOID);
|
||||
|
||||
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 @@ static VOID PaintMouseCursor(VOID)
|
||||
(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 PaintMouseCursor(VOID)
|
||||
|
||||
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,
|
||||
@@ -206,6 +293,61 @@ static VOID EraseMouseCursor(VOID)
|
||||
(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
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
|
||||
@@ -71,6 +71,8 @@ typedef struct _MOUSE_DRIVER_STATE
|
||||
WORD ScreenMask[16];
|
||||
WORD CursorMask[16];
|
||||
} GraphicsCursor;
|
||||
|
||||
BYTE GraphicsData[256];
|
||||
} MOUSE_DRIVER_STATE, *PMOUSE_DRIVER_STATE;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user