Implement PaintMouseCursor and EraseMouseCursor for video modes 12h and 13h.


svn path=/trunk/; revision=70990
This commit is contained in:
Aleksandar Andrejevic
2016-03-10 00:59:50 +00:00
parent ac22a1149a
commit 2f923086b1
2 changed files with 164 additions and 20 deletions
+162 -20
View File
@@ -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 ******************************************************************/