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/m... ============================================================================== --- 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/m... ============================================================================== --- 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 ******************************************************************/