aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <jara@hensl.cz>2023-11-06 00:14:41 +0100
committerJaroslav Hensl <jara@hensl.cz>2023-11-06 00:14:41 +0100
commite7212fbc01c4c3263738e5e37899621e295af701 (patch)
tree22d0d44f4b5ce15e6dc0f184a7d42bf9f05e0746
parentafcbef900e37e3d50d7fbd0a1af7b1de39140471 (diff)
downloadvmdisp9x-e7212fbc01c4c3263738e5e37899621e295af701.tar.gz
sw cursors, fb accesing, ddraw
-rw-r--r--boxv.c14
-rw-r--r--boxv.h1
-rw-r--r--control.c117
-rw-r--r--dddrv.c70
-rw-r--r--ddk/ddrawi.h189
-rw-r--r--dibcall.c329
-rw-r--r--enable.c62
-rw-r--r--hwcursor.c332
-rw-r--r--hwcursor.h10
-rw-r--r--makefile12
-rw-r--r--minidrv.h19
-rw-r--r--modes.c98
-rw-r--r--swcursor.c648
-rw-r--r--swcursor.h38
-rw-r--r--vmdahal.h8
15 files changed, 1578 insertions, 369 deletions
diff --git a/boxv.c b/boxv.c
index 01dbb80..2d81e42 100644
--- a/boxv.c
+++ b/boxv.c
@@ -188,3 +188,17 @@ unsigned long BOXV_get_lfb_base( void *cx )
return( fb_base );
}
+
+unsigned long BOXV_set_offset(void *cx, unsigned long bytes, unsigned int bpp, unsigned int pitch)
+{
+ unsigned int ps = ((bpp+7)/8);
+ unsigned int offset_y = bytes/pitch;
+ unsigned int offset_x = (bytes % pitch)/ps;
+
+ vid_outw( cx, VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_Y_OFFSET );
+ vid_outw( cx, VBE_DISPI_IOPORT_DATA, offset_y );
+ vid_outw( cx, VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_X_OFFSET );
+ vid_outw( cx, VBE_DISPI_IOPORT_DATA, offset_x );
+
+ return (unsigned long)offset_y*pitch + offset_x*ps;
+}
diff --git a/boxv.h b/boxv.h
index 99ba836..7d197bf 100644
--- a/boxv.h
+++ b/boxv.h
@@ -47,6 +47,7 @@ extern int BOXV_mode_set( void *cx, int mode_no );
extern int BOXV_dac_set( void *cx, unsigned start, unsigned count, void *pal );
extern int BOXV_ext_disable( void *cx );
extern unsigned long BOXV_get_lfb_base( void *cx );
+extern unsigned long BOXV_set_offset(void *cx, unsigned long bytes, unsigned int bpp, unsigned int pitch);
#define PCI_VENDOR_ID_VMWARE 0x15AD
#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
diff --git a/control.c b/control.c
index cdac8f2..6b95137 100644
--- a/control.c
+++ b/control.c
@@ -34,10 +34,13 @@ THE SOFTWARE.
#include <string.h> /* _fmemset */
#include "version.h"
+#include "swcursor.h"
#ifdef SVGA
# include "svga_all.h"
# include "vxdcall.h"
+#else
+# include "boxv.h"
#endif
#ifdef QEMU
@@ -80,6 +83,15 @@ THE SOFTWARE.
/* update buffer if 'need_call_update' is set */
#define FBHDA_UPDATE 0x110C
+/* move framebuffer */
+#define FBHDA_FLIP 0x110D
+
+/* cursor swap */
+#define FBHDA_CTRL 0x110E
+
+#define FBHDA_CTRL_CUR_SHOW 1UL
+#define FBHDA_CTRL_CUR_HIDE 2UL
+
/* check for drv <-> vxd <-> dll match */
#define SVGA_API 0x110F
@@ -95,13 +107,6 @@ THE SOFTWARE.
#define SVGA_HWINFO_FIFO 0x1122
#define SVGA_HWINFO_CAPS 0x1123
-typedef struct _longRECT {
- LONG left;
- LONG top;
- LONG right;
- LONG bottom;
-} longRECT;
-
/**
* OpenGL ICD driver name (0x1101):
* -------------------------------------
@@ -205,6 +210,10 @@ static svga_hda_t SVGAHDA;
#endif /* SVGA only */
+/* from dibcall.c */
+extern LONG cursorX;
+extern LONG cursorY;
+
#pragma code_seg( _INIT )
#ifdef SVGA
@@ -517,6 +526,50 @@ void SVGAHDA_update(DWORD width, DWORD height, DWORD bpp, DWORD pitch)
}
}
+BOOL SVGA_hasAccelScreen();
+
+/* working only in VB and only on 32 bit,
+ * ...
+ */
+uint32 SVGA_Flip(uint32 offset)
+{
+ if(SVGA_hasAccelScreen)
+ {
+ SVGAFifoCmdDefineScreen __far *screen;
+
+ dbg_printf("SVGA_Flip\n");
+
+ screen = SVGA_FIFOReserveCmd(SVGA_CMD_DEFINE_SCREEN, sizeof(SVGAFifoCmdDefineScreen));
+
+ if(screen)
+ {
+ _fmemset(screen, 0, sizeof(SVGAFifoCmdDefineScreen));
+ screen->screen.structSize = sizeof(SVGAScreenObject);
+ screen->screen.id = 0;
+ screen->screen.flags = SVGA_SCREEN_MUST_BE_SET | SVGA_SCREEN_IS_PRIMARY;
+ screen->screen.size.width = wScrX;
+ screen->screen.size.height = wScrY;
+ screen->screen.root.x = 0;
+ screen->screen.root.y = offset/wScreenPitchBytes;
+ screen->screen.cloneCount = 0;
+
+ screen->screen.backingStore.pitch = wScreenPitchBytes;
+ screen->screen.backingStore.ptr.offset = offset;
+ screen->screen.backingStore.ptr.gmrId = SVGA_GMR_FRAMEBUFFER;
+
+ SVGA_FIFOCommitAll();
+ }
+
+ SVGA_WriteReg(SVGA_SYNC, 1);
+
+ dbg_printf("SVGA_Flip done\n");
+
+ return offset;
+ }
+
+ return 0;
+}
+
#endif /* SVGA only */
/**
@@ -559,6 +612,9 @@ LONG WINAPI __loadds Control(LPVOID lpDevice, UINT function,
case OPENGL_GETINFO:
case FBHDA_REQ:
case FBHDA_UPDATE:
+ case FBHDA_FLIP:
+ case FBHDA_CTRL:
+ case MOUSETRAILS:
#ifdef SVGA
case SVGA_API:
/*
@@ -697,10 +753,13 @@ LONG WINAPI __loadds Control(LPVOID lpDevice, UINT function,
}
else if(function == MOUSETRAILS)
{
- if(lpOutput)
+ if(lpInput)
{
- //...
+ int trails = *((int __far *)lpInput);
+ dbg_printf("MOUSETRAILS: %d\n", trails);
}
+ //JH: mouse trails are disabled!
+ //DIB_Control(lpDevice, MOUSETRAILS, lpInput, lpOutput);
rc = 1;
}
else if(function == FBHDA_REQ) /* input: NULL, output: uint32 */
@@ -717,6 +776,46 @@ LONG WINAPI __loadds Control(LPVOID lpDevice, UINT function,
longRECT __far *lpRECT = lpInput;
SVGA_UpdateRect(lpRECT->left, lpRECT->top, lpRECT->right - lpRECT->left, lpRECT->bottom - lpRECT->top);
#endif
+ rc = 1;
+ }
+ else if(function == FBHDA_FLIP) /* input - offset from vram begin */
+ {
+ uint32_t __far *lpOffset = lpInput;
+ uint32_t realOffset = 0;
+#ifdef SVGA
+#if 0
+ realOffset = SVGA_Flip(*lpOffset);
+ SVGA_UpdateRect(0, 0, wScrX, wScrY);
+#else
+ (void)lpOffset;
+#endif
+#else
+ realOffset = BOXV_set_offset(0, *lpOffset, wBpp, wScreenPitchBytes);
+#endif
+
+ FBHDA_ptr->fb_pm32 = dwScreenFlatAddr + realOffset;
+
+ rc = 1;
+ }
+ else if(function == FBHDA_CTRL)
+ {
+ uint32_t code = *((uint32_t __far *)lpInput);
+
+ switch(code)
+ {
+ case FBHDA_CTRL_CUR_SHOW:
+ cursor_unlock();
+ cursor_blit(NULL);
+ dbg_printf("FBHDA_CTRL_CUR_SHOW\n");
+ break;
+ case FBHDA_CTRL_CUR_HIDE:
+ cursor_erase(NULL);
+ cursor_lock();
+ dbg_printf("FBHDA_CTRL_CUR_HIDE\n");
+ break;
+ }
+
+ rc = 1;
}
#ifdef SVGA
else if(function == SVGA_READ_REG) /* input: uint32_t, output: uint32_t */
diff --git a/dddrv.c b/dddrv.c
index 9ef4c8f..1d72122 100644
--- a/dddrv.c
+++ b/dddrv.c
@@ -32,6 +32,7 @@ THE SOFTWARE.
#include "ddrawi.h"
#include <wchar.h> /* wchar_t */
#include <string.h> /* _fmemset */
+#include <stddef.h>
#include "vmdahal.h"
@@ -290,7 +291,7 @@ static void buildDDHALInfo(VMDAHAL_t __far *hal, int modeidx)
*/
hal->ddHALInfo.vmiData.dwNumHeaps = 0;
heap = 0;
- can_flip = FALSE;
+ can_flip = TRUE;
screenSize = hal->ddHALInfo.vmiData.lDisplayPitch * hal->ddHALInfo.vmiData.dwDisplayHeight;
@@ -305,7 +306,7 @@ static void buildDDHALInfo(VMDAHAL_t __far *hal, int modeidx)
* capabilities supported
*/
- hal->ddHALInfo.ddCaps.dwCaps = DDCAPS_GDI;
+ //! hal->ddHALInfo.ddCaps.dwCaps = DDCAPS_GDI;
/*
hal->ddHALInfo.ddCaps.dwCaps = DDCAPS_GDI |
DDCAPS_BLT |
@@ -366,6 +367,31 @@ static void buildDDHALInfo(VMDAHAL_t __far *hal, int modeidx)
DDFXCAPS_OVERLAYSTRETCHX |
DDFXCAPS_OVERLAYSTRETCHY;
}*/
+ hal->ddHALInfo.ddCaps.dwCaps = DDCAPS_GDI | /* HW is shared with GDI */
+ DDCAPS_BLT | /* BLT is supported */
+ DDCAPS_BLTDEPTHFILL | /* depth fill */
+ DDCAPS_BLTCOLORFILL | /* color fill */
+ DDCAPS_COLORKEY; /* transparentBlt */
+
+ hal->ddHALInfo.ddCaps.dwCKeyCaps = DDCKEYCAPS_SRCBLT;
+ hal->ddHALInfo.ddCaps.dwFXCaps = DDFXCAPS_BLTARITHSTRETCHY |
+ DDFXCAPS_BLTARITHSTRETCHYN |
+ DDFXCAPS_BLTMIRRORLEFTRIGHT |
+ DDFXCAPS_BLTMIRRORUPDOWN |
+ DDFXCAPS_BLTSHRINKX |
+ DDFXCAPS_BLTSHRINKXN |
+ DDFXCAPS_BLTSHRINKY |
+ DDFXCAPS_BLTSHRINKYN |
+ DDFXCAPS_BLTSTRETCHX |
+ DDFXCAPS_BLTSTRETCHXN |
+ DDFXCAPS_BLTSTRETCHY |
+ DDFXCAPS_BLTSTRETCHYN;
+ // DDFXCAPS_BLTROTATION
+ // DDFXCAPS_BLTROTATION90
+
+ hal->ddHALInfo.ddCaps.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |
+ DDSCAPS_PRIMARYSURFACE |
+ DDSCAPS_ALPHA;
if(can_flip)
{
@@ -381,7 +407,7 @@ static void buildDDHALInfo(VMDAHAL_t __far *hal, int modeidx)
*/
for(ii=0; ii<DD_ROP_SPACE; ii++)
{
- hal->ddHALInfo.ddCaps.dwRops[ii] = 0;//ropsSupported[ii];
+ hal->ddHALInfo.ddCaps.dwRops[ii] = 0xFFFFFFFFUL;// JH: we have all ROP3s :-)
}
/*
@@ -473,7 +499,6 @@ BOOL DDCreateDriverObject(int bReset)
/*
* get addresses of 32-bit routines
*/
- //dbg_printf("CanCreateSurface: %lX\n", hal->cb32.CanCreateSurface);
cbDDCallbacks.CanCreateSurface = hal->cb32.CanCreateSurface;
if(cbDDCallbacks.CanCreateSurface) cbDDCallbacks.dwFlags |= DDHAL_CB32_CANCREATESURFACE;
@@ -484,7 +509,7 @@ BOOL DDCreateDriverObject(int bReset)
if(cbDDSurfaceCallbacks.Blt) cbDDSurfaceCallbacks.dwFlags |= DDHAL_SURFCB32_BLT;
cbDDSurfaceCallbacks.Flip = hal->cb32.Flip;
- if(cbDDSurfaceCallbacks.Flip) cbDDSurfaceCallbacks.dwFlags |= DDHAL_SURFCB32_FLIP;
+ if(cbDDSurfaceCallbacks.Flip) cbDDSurfaceCallbacks.dwFlags |= DDHAL_SURFCB32_FLIP;
cbDDSurfaceCallbacks.Lock = hal->cb32.Lock;
if(cbDDSurfaceCallbacks.Lock) cbDDSurfaceCallbacks.dwFlags |= DDHAL_SURFCB32_LOCK;
@@ -503,8 +528,33 @@ BOOL DDCreateDriverObject(int bReset)
hal->ddHALInfo.GetDriverInfo = hal->cb32.GetDriverInfo;
if(hal->ddHALInfo.GetDriverInfo) hal->ddHALInfo.dwFlags |= DDHALINFO_GETDRIVERINFOSET;
-
+
+ cbDDCallbacks.WaitForVerticalBlank = hal->cb32.WaitForVerticalBlank;
+ if(cbDDCallbacks.WaitForVerticalBlank) cbDDCallbacks.dwFlags |= DDHAL_CB32_WAITFORVERTICALBLANK;
+
+ cbDDCallbacks.SetMode = hal->cb32.SetMode;
+ if(cbDDCallbacks.SetMode) cbDDCallbacks.dwFlags |= DDHAL_CB32_SETMODE;
+
+ cbDDCallbacks.SetExclusiveMode = hal->cb32.SetExclusiveMode;
+ if(cbDDCallbacks.SetExclusiveMode) cbDDCallbacks.dwFlags |= DDHAL_CB32_SETEXCLUSIVEMODE;
+ dbg_printf("Dup DD32 calls\n");
+ dbg_printf(" CanCreateSurface = %lX\n", cbDDCallbacks.CanCreateSurface);
+ dbg_printf(" CreateSurface = %lX\n", cbDDCallbacks.CreateSurface);
+ dbg_printf(" Blt = %lX\n", cbDDSurfaceCallbacks.Blt);
+ dbg_printf(" Flip = %lX\n", cbDDSurfaceCallbacks.Flip);
+ dbg_printf(" Lock = %lX\n", cbDDSurfaceCallbacks.Lock);
+ dbg_printf(" Unlock = %lX\n", cbDDSurfaceCallbacks.Unlock);
+ dbg_printf(" GetBltStatus = %lX\n", cbDDSurfaceCallbacks.GetBltStatus);
+ dbg_printf(" GetFlipStatus = %lX\n", cbDDSurfaceCallbacks.GetFlipStatus);
+ dbg_printf(" DestroySurface = %lX\n", cbDDSurfaceCallbacks.DestroySurface);
+ dbg_printf(" GetDriverInfo = %lX\n", hal->ddHALInfo.GetDriverInfo);
+ dbg_printf(" WaitForVerticalBlank = %lX\n\n", cbDDCallbacks.WaitForVerticalBlank);
+
+ hal->pFBHDA32 = FBHDA_linear;
+ hal->pFBHDA16 = FBHDA_ptr;
+ hal->FBHDA_version = 2;
+
return lpDDHAL_SetInfo(&(hal->ddHALInfo), bReset);
}
@@ -544,7 +594,13 @@ void DDGetVersion(DDVERSIONDATA_t __far *lpVer)
_fmemset(lpVer, 0, sizeof(DDVERSIONDATA_t));
lpVer->dwHALVersion = DD_RUNTIME_VERSION;
- dbg_printf("struct size: %d\n", sizeof(VMDAHAL_t));
+ dbg_printf("struct size: %d (%d %d %d %d)\n",
+ sizeof(VMDAHAL_t),
+ offsetof(VMDAHAL_t, ddpf),
+ offsetof(VMDAHAL_t, ddHALInfo),
+ offsetof(VMDAHAL_t, cb32),
+ offsetof(VMDAHAL_t, FBHDA_version)
+ );
}
DWORD DDHinstance(void)
diff --git a/ddk/ddrawi.h b/ddk/ddrawi.h
index 971e2ca..b80091d 100644
--- a/ddk/ddrawi.h
+++ b/ddk/ddrawi.h
@@ -15,6 +15,8 @@
#define HRESULT DWORD
#endif
+#define DDUNSUPPORTEDMODE ((DWORD) -1)
+
/*
* maximum size of a driver name
*/
@@ -861,6 +863,165 @@ typedef struct DDSCAPS __far* LPDDSCAPS;
*/
#define DDPF_ZPIXELS 0x00002000l
+/****************************************************************************
+ *
+ * DIRECTDRAW FX CAPABILITY FLAGS
+ *
+ ****************************************************************************/
+
+/*
+ * Uses arithmetic operations to stretch and shrink surfaces during blt
+ * rather than pixel doubling techniques. Along the Y axis.
+ */
+#define DDFXCAPS_BLTARITHSTRETCHY 0x00000020l
+
+/*
+ * Uses arithmetic operations to stretch during blt
+ * rather than pixel doubling techniques. Along the Y axis. Only
+ * works for x1, x2, etc.
+ */
+#define DDFXCAPS_BLTARITHSTRETCHYN 0x00000010l
+
+/*
+ * Supports mirroring left to right in blt.
+ */
+#define DDFXCAPS_BLTMIRRORLEFTRIGHT 0x00000040l
+
+/*
+ * Supports mirroring top to bottom in blt.
+ */
+#define DDFXCAPS_BLTMIRRORUPDOWN 0x00000080l
+
+/*
+ * Supports arbitrary rotation for blts.
+ */
+#define DDFXCAPS_BLTROTATION 0x00000100l
+
+/*
+ * Supports 90 degree rotations for blts.
+ */
+#define DDFXCAPS_BLTROTATION90 0x00000200l
+
+/*
+ * DirectDraw supports arbitrary shrinking of a surface along the
+ * x axis (horizontal direction) for blts.
+ */
+#define DDFXCAPS_BLTSHRINKX 0x00000400l
+
+/*
+ * DirectDraw supports integer shrinking (1x,2x,) of a surface
+ * along the x axis (horizontal direction) for blts.
+ */
+#define DDFXCAPS_BLTSHRINKXN 0x00000800l
+
+/*
+ * DirectDraw supports arbitrary shrinking of a surface along the
+ * y axis (horizontal direction) for blts.
+ */
+#define DDFXCAPS_BLTSHRINKY 0x00001000l
+
+/*
+ * DirectDraw supports integer shrinking (1x,2x,) of a surface
+ * along the y axis (vertical direction) for blts.
+ */
+#define DDFXCAPS_BLTSHRINKYN 0x00002000l
+
+/*
+ * DirectDraw supports arbitrary stretching of a surface along the
+ * x axis (horizontal direction) for blts.
+ */
+#define DDFXCAPS_BLTSTRETCHX 0x00004000l
+
+/*
+ * DirectDraw supports integer stretching (1x,2x,) of a surface
+ * along the x axis (horizontal direction) for blts.
+ */
+#define DDFXCAPS_BLTSTRETCHXN 0x00008000l
+
+/*
+ * DirectDraw supports arbitrary stretching of a surface along the
+ * y axis (horizontal direction) for blts.
+ */
+#define DDFXCAPS_BLTSTRETCHY 0x00010000l
+
+/*
+ * DirectDraw supports integer stretching (1x,2x,) of a surface
+ * along the y axis (vertical direction) for blts.
+ */
+#define DDFXCAPS_BLTSTRETCHYN 0x00020000l
+
+/*
+ * Uses arithmetic operations to stretch and shrink surfaces during
+ * overlay rather than pixel doubling techniques. Along the Y axis
+ * for overlays.
+ */
+#define DDFXCAPS_OVERLAYARITHSTRETCHY 0x00040000l
+
+/*
+ * Uses arithmetic operations to stretch surfaces during
+ * overlay rather than pixel doubling techniques. Along the Y axis
+ * for overlays. Only works for x1, x2, etc.
+ */
+#define DDFXCAPS_OVERLAYARITHSTRETCHYN 0x00000008l
+
+/*
+ * DirectDraw supports arbitrary shrinking of a surface along the
+ * x axis (horizontal direction) for overlays.
+ */
+#define DDFXCAPS_OVERLAYSHRINKX 0x00080000l
+
+/*
+ * DirectDraw supports integer shrinking (1x,2x,) of a surface
+ * along the x axis (horizontal direction) for overlays.
+ */
+#define DDFXCAPS_OVERLAYSHRINKXN 0x00100000l
+
+/*
+ * DirectDraw supports arbitrary shrinking of a surface along the
+ * y axis (horizontal direction) for overlays.
+ */
+#define DDFXCAPS_OVERLAYSHRINKY 0x00200000l
+
+/*
+ * DirectDraw supports integer shrinking (1x,2x,) of a surface
+ * along the y axis (vertical direction) for overlays.
+ */
+#define DDFXCAPS_OVERLAYSHRINKYN 0x00400000l
+
+/*
+ * DirectDraw supports arbitrary stretching of a surface along the
+ * x axis (horizontal direction) for overlays.
+ */
+#define DDFXCAPS_OVERLAYSTRETCHX 0x00800000l
+
+/*
+ * DirectDraw supports integer stretching (1x,2x,) of a surface
+ * along the x axis (horizontal direction) for overlays.
+ */
+#define DDFXCAPS_OVERLAYSTRETCHXN 0x01000000l
+
+/*
+ * DirectDraw supports arbitrary stretching of a surface along the
+ * y axis (horizontal direction) for overlays.
+ */
+#define DDFXCAPS_OVERLAYSTRETCHY 0x02000000l
+
+/*
+ * DirectDraw supports integer stretching (1x,2x,) of a surface
+ * along the y axis (vertical direction) for overlays.
+ */
+#define DDFXCAPS_OVERLAYSTRETCHYN 0x04000000l
+
+/*
+ * DirectDraw supports mirroring of overlays across the vertical axis
+ */
+#define DDFXCAPS_OVERLAYMIRRORLEFTRIGHT 0x08000000l
+
+/*
+ * DirectDraw supports mirroring of overlays across the horizontal axis
+ */
+#define DDFXCAPS_OVERLAYMIRRORUPDOWN 0x10000000l
+
/*
* DDPIXELFORMAT
*/
@@ -1226,20 +1387,20 @@ typedef DDHAL_DDSURFACECALLBACKS_t __far *LPDDHAL_DDSURFACECALLBACKS;
#define DDSURFACECALLBACKSSIZE sizeof( DDHAL_DDSURFACECALLBACKS_t )
-#define DDHAL_SURFCB32_DESTROYSURFACE 0x00000001l
-#define DDHAL_SURFCB32_FLIP 0x00000002l
-#define DDHAL_SURFCB32_SETCLIPLIST 0x00000004l
-#define DDHAL_SURFCB32_LOCK 0x00000008l
-#define DDHAL_SURFCB32_UNLOCK 0x00000010l
-#define DDHAL_SURFCB32_BLT 0x00000020l
-#define DDHAL_SURFCB32_SETCOLORKEY 0x00000040l
-#define DDHAL_SURFCB32_ADDATTACHEDSURFACE 0x00000080l
-#define DDHAL_SURFCB32_GETBLTSTATUS 0x00000100l
-#define DDHAL_SURFCB32_GETFLIPSTATUS 0x00000200l
-#define DDHAL_SURFCB32_UPDATEOVERLAY 0x00000400l
-#define DDHAL_SURFCB32_SETOVERLAYPOSITION 0x00000800l
-#define DDHAL_SURFCB32_RESERVED4 0x00001000l
-#define DDHAL_SURFCB32_SETPALETTE 0x00002000l
+#define DDHAL_SURFCB32_DESTROYSURFACE 0x00000001UL
+#define DDHAL_SURFCB32_FLIP 0x00000002UL
+#define DDHAL_SURFCB32_SETCLIPLIST 0x00000004UL
+#define DDHAL_SURFCB32_LOCK 0x00000008UL
+#define DDHAL_SURFCB32_UNLOCK 0x00000010UL
+#define DDHAL_SURFCB32_BLT 0x00000020UL
+#define DDHAL_SURFCB32_SETCOLORKEY 0x00000040UL
+#define DDHAL_SURFCB32_ADDATTACHEDSURFACE 0x00000080UL
+#define DDHAL_SURFCB32_GETBLTSTATUS 0x00000100UL
+#define DDHAL_SURFCB32_GETFLIPSTATUS 0x00000200UL
+#define DDHAL_SURFCB32_UPDATEOVERLAY 0x00000400UL
+#define DDHAL_SURFCB32_SETOVERLAYPOSITION 0x00000800UL
+#define DDHAL_SURFCB32_RESERVED4 0x00001000UL
+#define DDHAL_SURFCB32_SETPALETTE 0x00002000UL
// This structure can be queried from the driver from DX5 onward
// using GetDriverInfo with GUID_MiscellaneousCallbacks
diff --git a/dibcall.c b/dibcall.c
index 1ad2cfd..9b47da2 100644
--- a/dibcall.c
+++ b/dibcall.c
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2022 Michal Necasek
+ 2023 Jaroslav Hensl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -26,19 +27,12 @@ THE SOFTWARE.
#include <gdidefs.h>
#include <dibeng.h>
#include <minivdd.h>
+#include <string.h>
#include "minidrv.h"
+#include "swcursor.h"
+#include "hwcursor.h"
-#ifdef SVGA
-# include "svga_all.h"
-# include <string.h>
-# include "vxdcall.h"
-
-/* from control.c */
-# define LOCK_FIFO 6
-BOOL SVGAHDA_trylock(DWORD lockid);
-void SVGAHDA_unlock(DWORD lockid);
-#endif
/*
* What's this all about? Most of the required exported driver functions can
@@ -55,290 +49,60 @@ void SVGAHDA_unlock(DWORD lockid);
* are not hardware specific.
*/
-/* from DDK98 */
-#pragma pack(push)
-#pragma pack(1)
-typedef struct
-{
- int xHotSpot, yHotSpot;
- int cx, cy;
- int cbWidth;
- BYTE Planes;
- BYTE BitsPixel;
-} CURSORSHAPE;
-#pragma pack(pop)
-
-#ifdef SVGA
-BOOL cursorVisible = FALSE;
-#endif
+LONG cursorX = 0;
+LONG cursorY = 0;
#pragma code_seg( _TEXT )
-#ifdef SVGA
-static LONG cursorX = 0;
-static LONG cursorY = 0;
-static LONG cursorW = 0;
-static LONG cursorH = 0;
-static LONG cursorHX = 0;
-static LONG cursorHY = 0;
-
-
-/*
- https://learn.microsoft.com/en-us/windows-hardware/drivers/display/drawing-monochrome-pointers
-*/
-static void CursorMonoToAlpha(CURSORSHAPE __far *lpCursor, void __far *data)
-{
- LONG __far *px = data;
- BYTE __far *andmask = (BYTE __far *)(lpCursor + 1);
- BYTE __far *xormask = andmask + lpCursor->cbWidth*lpCursor->cy;
- int xi, xj, y;
-
- for(y = 0; y < lpCursor->cy; y++)
- {
- for(xj = 0; xj < (lpCursor->cbWidth); xj++)
- {
- BYTE a = andmask[lpCursor->cbWidth*y + xj];
- BYTE x = xormask[lpCursor->cbWidth*y + xj];
- for(xi = 7; xi >= 0; xi--)
- {
- BYTE mx = (((a >> xi) & 0x1) << 1) | ((x >> xi) & 0x1);
-
- switch(mx)
- {
- case 0:
- *px = 0xFF000000; // full black
- break;
- case 1:
- *px = 0xFFFFFFFF; // full white
- break;
- case 2:
- *px = 0x00000000; // transparent
- break;
- case 3:
- *px = 0xFF000000; // inverse = set black (used for example with type cursor)
- break;
- }
-
- px++;
- }
- }
- }
-}
-
-static void CursorColor32ToAlpha(CURSORSHAPE __far *lpCursor, void __far *data)
-{
- LONG __far *px = data;
- BYTE __far *andmask = (BYTE __far *)(lpCursor + 1);
- DWORD __far *xormask = (DWORD __far *)(andmask + lpCursor->cbWidth*lpCursor->cy);
- int xi, xj, y;
-
- for(y = 0; y < lpCursor->cy; y++)
- {
- for(xj = 0; xj < (lpCursor->cbWidth); xj++)
- {
- BYTE a = andmask[lpCursor->cbWidth*y + xj];
-
- for(xi = 7; xi >= 0; xi--)
- {
- DWORD x = xormask[lpCursor->cx*y + xj*8 + (7-xi)] & 0x00FFFFFFUL;
- BYTE ab = ((a >> xi) & 0x1);
-
- switch(ab)
- {
- case 0:
- *px = 0xFF000000UL | x;
- break;
- case 1:
- *px = 0x00000000UL | x;
- break;
- }
-
- px++;
- }
- }
- }
-}
-
-void update_cursor()
-{
- if(wBpp == 32)
- {
- LONG x = cursorX - cursorHX;
- LONG y = cursorY - cursorHY;
- LONG w = cursorW;
- LONG h = cursorH;
-
- SVGA_UpdateRect(x, y, w, h);
- }
-}
-#endif
-
void WINAPI __loadds MoveCursor(WORD absX, WORD absY)
-{
+{
if(wEnabled)
{
#ifdef SVGA
- if(wBpp == 32)
+ if(!hwcursor_move(absX, absY))
{
- if(gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR)
- {
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- SVGA_MoveCursor(cursorVisible, absX, absY, 0);
- SVGAHDA_unlock(LOCK_FIFO);
- }
-
- /* save last position */
- cursorX = absX;
- cursorY = absY;
- }
- else
- {
- DIB_MoveCursorExt(absX, absY, lpDriverPDevice);
- update_cursor();
- cursorX = absX;
- cursorY = absY;
- update_cursor();
- }
- return;
+#endif // SVGA
+ longRECT changes = {0,0,0,0};
+ cursorX = absX;
+ cursorY = absY;
+ cursor_move(&changes);
+#ifdef SVGA
+ SVGA_UpdateLongRect(&changes);
}
#endif // SVGA
- DIB_MoveCursorExt(absX, absY, lpDriverPDevice);
}
+
+ //DIB_MoveCursorExt(absX, absY, lpDriverPDevice);
}
WORD WINAPI __loadds SetCursor_driver(CURSORSHAPE __far *lpCursor)
{
+ if(!sw_cursor)
+ {
+ cursor_init();
+ }
+
if(wEnabled)
{
#ifdef SVGA
- if(wBpp == 32)
+ if(!hwcursor_load(lpCursor))
{
- if(gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR)
+#endif // SVGA
+ longRECT changes = {0,0,0,0};
+
+ if(lpCursor)
{
- void __far* ANDMask = NULL;
- void __far* XORMask = NULL;
- void __far* AData = NULL;
- SVGAFifoCmdDefineCursor cur;
- SVGAFifoCmdDefineAlphaCursor acur;
-
- if(lpCursor != NULL)
- {
- dbg_printf("cx: %d, cy: %d, colors: %d\n", lpCursor->cx, lpCursor->cy, lpCursor->BitsPixel);
-
- if(gSVGA.userFlags & SVGA_USER_FLAGS_ALPHA_CUR)
- {
- acur.id = 0;
- acur.hotspotX = lpCursor->xHotSpot;
- acur.hotspotY = lpCursor->yHotSpot;
- acur.width = lpCursor->cx;
- acur.height = lpCursor->cy;
-
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- SVGA_BeginDefineAlphaCursor(&acur, &AData);
- if(AData)
- {
- switch(lpCursor->BitsPixel)
- {
- case 1:
- CursorMonoToAlpha(lpCursor, AData);
- break;
- case 32:
- CursorColor32ToAlpha(lpCursor, AData);
- break;
- }
- }
- VXD_FIFOCommitAll();
- SVGAHDA_unlock(LOCK_FIFO);
- }
- }
- else
- {
- cur.id = 0;
- cur.hotspotX = lpCursor->xHotSpot;
- cur.hotspotY = lpCursor->yHotSpot;
- cur.width = lpCursor->cx;
- cur.height = lpCursor->cy;
- cur.andMaskDepth = 1;
- cur.xorMaskDepth = lpCursor->BitsPixel;
-
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- SVGA_BeginDefineCursor(&cur, &ANDMask, &XORMask);
-
- if(ANDMask)
- {
- _fmemcpy(ANDMask, lpCursor+1, lpCursor->cbWidth*lpCursor->cy);
- }
-
- if(XORMask)
- {
- BYTE __far *ptr = (BYTE __far *)(lpCursor+1);
- ptr += lpCursor->cbWidth*lpCursor->cy;
-
- _fmemcpy(XORMask, ptr, lpCursor->cx*lpCursor->cy*((lpCursor->BitsPixel+7)/8));
- }
-
- VXD_FIFOCommitAll();
- SVGAHDA_unlock(LOCK_FIFO);
- }
- }
-
- /* move cursor to last known position */
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- SVGA_MoveCursor(cursorVisible, cursorX, cursorY, 0);
- SVGAHDA_unlock(LOCK_FIFO);
- }
-
- cursorVisible = TRUE;
- }
- else
- {
- /* virtual box bug on SVGA_MoveCursor(FALSE, ...)
- * so if is cursor NULL, create empty
- */
- cur.id = 0;
- cur.hotspotX = 0;
- cur.hotspotY = 0;
- cur.width = 32;
- cur.height = 32;
- cur.andMaskDepth = 1;
- cur.xorMaskDepth = 1;
-
- if(SVGAHDA_trylock(LOCK_FIFO))
- {
- SVGA_BeginDefineCursor(&cur, &ANDMask, &XORMask);
-
- if(ANDMask) _fmemset(ANDMask, 0xFF, 4*32);
- if(XORMask) _fmemset(XORMask, 0, 4*32);
-
- //SVGA_FIFOCommitAll();
- VXD_FIFOCommitAll();
-
- SVGA_MoveCursor(FALSE, 0, 0, 0);
-
- SVGAHDA_unlock(LOCK_FIFO);
- }
- cursorVisible = FALSE;
- }
-
- return 1; /* SUCCESS */
+ cursor_load(lpCursor, &changes);
}
else
{
- if(lpCursor != NULL)
- {
- cursorW = lpCursor->cx;
- cursorH = lpCursor->cy;
- cursorHX = lpCursor->xHotSpot;
- cursorHY = lpCursor->yHotSpot;
- }
+ cursor_unload(&changes);
}
- } // 32bpp
-#endif
- DIB_SetCursorExt(lpCursor, lpDriverPDevice);
+#ifdef SVGA
+ SVGA_UpdateLongRect(&changes);
+ }
+#endif // SVGA
+
return 1;
}
return 0;
@@ -347,27 +111,14 @@ WORD WINAPI __loadds SetCursor_driver(CURSORSHAPE __far *lpCursor)
/* Exported as DISPLAY.104 */
void WINAPI __loadds CheckCursor( void )
{
- if( wEnabled ) {
-#ifdef SVGA
- if((gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR) == 0)
- {
- DIB_CheckCursorExt( lpDriverPDevice );
- if(wBpp == 32)
- {
- update_cursor();
- }
- }
- else
+ if( wEnabled )
{
- if(wBpp != 32)
- {
- DIB_CheckCursorExt( lpDriverPDevice );
- }
- }
-#else
- DIB_CheckCursorExt( lpDriverPDevice );
-#endif
+#ifdef SVGA
+ hwcursor_update();
+#endif // SVGA
}
+
+ //DIB_CheckCursorExt( lpDriverPDevice );
}
/* If there is no hardware screen-to-screen BitBlt, there's no point in
diff --git a/enable.c b/enable.c
index c6fc3ff..775da9a 100644
--- a/enable.c
+++ b/enable.c
@@ -30,6 +30,9 @@ THE SOFTWARE.
#include <minivdd.h>
#include "minidrv.h"
+#include "swcursor.h"
+#include "hwcursor.h"
+
#include <string.h>
#ifdef SVGA
@@ -143,32 +146,52 @@ DWORD PASCAL CreateDIBPDeviceX( LPBITMAPINFO lpInfo, LPPDEVICE lpDevice, LPVOID
"shr eax, 16" \
"xchg ax, dx"
-#ifdef SVGA
-static uint32 updateX = 0;
-static uint32 updateY = 0;
-static uint32 updateW = 0;
-static uint32 updateH = 0;
-#endif
+
+static longRECT updateRect = {0, 0, 0, 0};
#pragma code_seg( _INIT )
-#ifdef SVGA
-VOID WINAPI __loadds SVGA_DIB_BeginAccess( LPPDEVICE lpDevice, WORD wLeft, WORD wTop, WORD wRight, WORD wBottom, WORD wFlags )
+VOID WINAPI __loadds BeginAccess_DIB( LPPDEVICE lpDevice, WORD wLeft, WORD wTop, WORD wRight, WORD wBottom, WORD wFlags )
{
- updateX = wLeft;
- updateY = wTop;
- updateW = wRight - wLeft;
- updateH = wBottom - wTop;
+ longRECT r;
+
+#ifdef SVGA
+ if(!hwcursor_available())
+ {
+#endif
+ updateRect.left = wLeft;
+ updateRect.top = wTop;
+ updateRect.right = wRight;
+ updateRect.bottom = wBottom;
+
+ cursor_erase(&r);
+ cursor_lock();
+ cursor_merge_rect(&updateRect, &r);
+#ifdef SVGA
+ }
+#endif
DIB_BeginAccess(lpDevice, wLeft, wTop, wRight, wBottom, wFlags);
}
-VOID WINAPI __loadds SVGA_DIB_EndAccess( LPPDEVICE lpDevice, WORD wFlags )
+VOID WINAPI __loadds EndAccess_DIB( LPPDEVICE lpDevice, WORD wFlags )
{
+ longRECT r;
DIB_EndAccess(lpDevice, wFlags);
- SVGA_UpdateRect(updateX, updateY, updateW, updateH);
-}
+
+#ifdef SVGA
+ if(!hwcursor_available())
+ {
+#endif
+ cursor_unlock();
+ cursor_blit(&r);
+ cursor_merge_rect(&updateRect, &r);
+#ifdef SVGA
+ }
+ SVGA_UpdateRect(updateRect.left, updateRect.top,
+ updateRect.right-updateRect.left, updateRect.bottom-updateRect.top);
#endif
+}
/* GDI calls Enable twice at startup, first to query the GDIINFO structure
@@ -267,13 +290,8 @@ UINT WINAPI __loadds Enable( LPVOID lpDevice, UINT style, LPSTR lpDeviceType,
dbg_printf( "Enable: CreateDIBPDevice returned %lX\n", dwRet );
/* Now fill out the begin/end access callbacks. */
-#ifdef SVGA
- lpEng->deBeginAccess = SVGA_DIB_BeginAccess;
- lpEng->deEndAccess = SVGA_DIB_EndAccess;
-#else
- lpEng->deBeginAccess = DIB_BeginAccess;
- lpEng->deEndAccess = DIB_EndAccess;
-#endif
+ lpEng->deBeginAccess = BeginAccess_DIB;
+ lpEng->deEndAccess = EndAccess_DIB;
/* Program the DAC in non-direct color modes. */
if( wBpp <= 8 ) {
diff --git a/hwcursor.c b/hwcursor.c
new file mode 100644
index 0000000..7da8191
--- /dev/null
+++ b/hwcursor.c
@@ -0,0 +1,332 @@
+/*****************************************************************************
+
+Copyright (c) 2023 Jaroslav Hensl
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*****************************************************************************/
+
+#define SVGA
+
+#include "winhack.h"
+#include <gdidefs.h>
+#include <dibeng.h>
+#include <minivdd.h>
+#include <string.h>
+
+#include "minidrv.h"
+#include "swcursor.h"
+#include "hwcursor.h"
+
+#include "svga_all.h"
+#include "vxdcall.h"
+
+/* from control.c */
+#define LOCK_FIFO 6
+BOOL SVGAHDA_trylock(DWORD lockid);
+void SVGAHDA_unlock(DWORD lockid);
+
+static BOOL cursorVisible = FALSE;
+
+static LONG cursorW = 0;
+static LONG cursorH = 0;
+static LONG cursorHX = 0;
+static LONG cursorHY = 0;
+
+#pragma code_seg( _TEXT )
+
+/*
+ https://learn.microsoft.com/en-us/windows-hardware/drivers/display/drawing-monochrome-pointers
+*/
+static void CursorMonoToAlpha(CURSORSHAPE __far *lpCursor, void __far *data)
+{
+ LONG __far *px = data;
+ BYTE __far *andmask = (BYTE __far *)(lpCursor + 1);
+ BYTE __far *xormask = andmask + lpCursor->cbWidth*lpCursor->cy;
+ int xi, xj, y;
+
+ dbg_printf("CursorMonoToAlpha\n");
+
+ for(y = 0; y < lpCursor->cy; y++)
+ {
+ for(xj = 0; xj < (lpCursor->cbWidth); xj++)
+ {
+ BYTE a = andmask[lpCursor->cbWidth*y + xj];
+ BYTE x = xormask[lpCursor->cbWidth*y + xj];
+ for(xi = 7; xi >= 0; xi--)
+ {
+ BYTE mx = (((a >> xi) & 0x1) << 1) | ((x >> xi) & 0x1);
+
+ switch(mx)
+ {
+ case 0:
+ *px = 0xFF000000; // full black
+ break;
+ case 1:
+ *px = 0xFFFFFFFF; // full white
+ break;
+ case 2:
+ *px = 0x00000000; // transparent
+ break;
+ case 3:
+ *px = 0xFF000000; // inverse = set black (used for example with type cursor)
+ break;
+ }
+
+ px++;
+ }
+ }
+ }
+}
+
+static void CursorColor32ToAlpha(CURSORSHAPE __far *lpCursor, void __far *data)
+{
+ LONG __far *px = data;
+ BYTE __far *andmask = (BYTE __far *)(lpCursor + 1);
+ DWORD __far *xormask = (DWORD __far *)(andmask + lpCursor->cbWidth*lpCursor->cy);
+ int xi, xj, y;
+
+ dbg_printf("CursorColor32ToAlpha\n");
+
+ for(y = 0; y < lpCursor->cy; y++)
+ {
+ for(xj = 0; xj < (lpCursor->cbWidth); xj++)
+ {
+ BYTE a = andmask[lpCursor->cbWidth*y + xj];
+
+ for(xi = 7; xi >= 0; xi--)
+ {
+ DWORD x = xormask[lpCursor->cx*y + xj*8 + (7-xi)] & 0x00FFFFFFUL;
+ BYTE ab = ((a >> xi) & 0x1);
+
+ switch(ab)
+ {
+ case 0:
+ *px = 0xFF000000UL | x;
+ break;
+ case 1:
+ *px = 0x00000000UL | x;
+ break;
+ }
+
+ px++;
+ }
+ }
+ }
+}
+
+void SVGA_UpdateLongRect(longRECT __far *rect)
+{
+ if(wBpp == 32)
+ {
+ long w = rect->right - rect->left;
+ long h = rect->bottom - rect->top;
+ if(w > 0)
+ {
+ SVGA_UpdateRect(rect->left, rect->top, w, h);
+ }
+ }
+}
+
+BOOL hwcursor_move(WORD absX, WORD absY)
+{
+ if(wBpp != 32)
+ {
+ return FALSE;
+ }
+
+ if((gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR) == 0)
+ {
+ return FALSE;
+ }
+
+ if(SVGAHDA_trylock(LOCK_FIFO))
+ {
+ SVGA_MoveCursor(cursorVisible, absX, absY, 0);
+ SVGAHDA_unlock(LOCK_FIFO);
+ }
+
+ cursorX = absX;
+ cursorY = absY;
+
+ return TRUE;
+}
+
+BOOL hwcursor_load(CURSORSHAPE __far *lpCursor)
+{
+ void __far* ANDMask = NULL;
+ void __far* XORMask = NULL;
+ void __far* AData = NULL;
+ SVGAFifoCmdDefineCursor cur;
+ SVGAFifoCmdDefineAlphaCursor acur;
+
+ if(wBpp != 32)
+ {
+ return FALSE;
+ }
+
+ if((gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR) == 0)
+ {
+ return FALSE;
+ }
+
+ if(lpCursor != NULL)
+ {
+ dbg_printf("cx: %d, cy: %d, colors: %d\n", lpCursor->cx, lpCursor->cy, lpCursor->BitsPixel);
+
+ dbg_printf("flags %lx\n", gSVGA.userFlags);
+
+ if(gSVGA.userFlags & SVGA_USER_FLAGS_ALPHA_CUR)
+ {
+ acur.id = 0;
+ acur.hotspotX = lpCursor->xHotSpot;
+ acur.hotspotY = lpCursor->yHotSpot;
+ acur.width = lpCursor->cx;
+ acur.height = lpCursor->cy;
+
+ if(SVGAHDA_trylock(LOCK_FIFO))
+ {
+ SVGA_BeginDefineAlphaCursor(&acur, &AData);
+ if(AData)
+ {
+ switch(lpCursor->BitsPixel)
+ {
+ case 1:
+ CursorMonoToAlpha(lpCursor, AData);
+ break;
+ case 32:
+ CursorColor32ToAlpha(lpCursor, AData);
+ break;
+ }
+ }
+ VXD_FIFOCommitAll();
+ SVGAHDA_unlock(LOCK_FIFO);
+ }
+ }
+ else
+ {
+ cur.id = 0;
+ cur.hotspotX = lpCursor->xHotSpot;
+ cur.hotspotY = lpCursor->yHotSpot;
+ cur.width = lpCursor->cx;
+ cur.height = lpCursor->cy;
+ cur.andMaskDepth = 1;
+ cur.xorMaskDepth = lpCursor->BitsPixel;
+
+ if(SVGAHDA_trylock(LOCK_FIFO))
+ {
+ SVGA_BeginDefineCursor(&cur, &ANDMask, &XORMask);
+
+ if(ANDMask)
+ {
+ _fmemcpy(ANDMask, lpCursor+1, lpCursor->cbWidth*lpCursor->cy);
+ }
+
+ if(XORMask)
+ {
+ BYTE __far *ptr = (BYTE __far *)(lpCursor+1);
+ ptr += lpCursor->cbWidth*lpCursor->cy;
+
+ _fmemcpy(XORMask, ptr, lpCursor->cx*lpCursor->cy*((lpCursor->BitsPixel+7)/8));
+ }
+
+ VXD_FIFOCommitAll();
+ SVGAHDA_unlock(LOCK_FIFO);
+ }
+ }
+
+ /* move cursor to last known position */
+ if(SVGAHDA_trylock(LOCK_FIFO))
+ {
+ SVGA_MoveCursor(cursorVisible, cursorX, cursorY, 0);
+ SVGAHDA_unlock(LOCK_FIFO);
+ }
+
+ cursorVisible = TRUE;
+
+ cursorW = lpCursor->cx;
+ cursorH = lpCursor->cy;
+ cursorHX = lpCursor->xHotSpot;
+ cursorHY = lpCursor->yHotSpot;
+ }
+ else
+ {
+ /* virtual box bug on SVGA_MoveCursor(FALSE, ...)
+ * so if is cursor NULL, create empty
+ */
+ cur.id = 0;
+ cur.hotspotX = 0;
+ cur.hotspotY = 0;
+ cur.width = 32;
+ cur.height = 32;
+ cur.andMaskDepth = 1;
+ cur.xorMaskDepth = 1;
+
+ if(SVGAHDA_trylock(LOCK_FIFO))
+ {
+ SVGA_BeginDefineCursor(&cur, &ANDMask, &XORMask);
+
+ if(ANDMask) _fmemset(ANDMask, 0xFF, 4*32);
+ if(XORMask) _fmemset(XORMask, 0, 4*32);
+
+ //SVGA_FIFOCommitAll();
+ VXD_FIFOCommitAll();
+
+ SVGA_MoveCursor(FALSE, 0, 0, 0);
+
+ SVGAHDA_unlock(LOCK_FIFO);
+ }
+ cursorVisible = FALSE;
+ }
+
+ dbg_printf("hwcursor_load\n");
+
+ return TRUE;
+}
+
+void hwcursor_update()
+{
+ if(wBpp == 32)
+ {
+ if((gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR) != 0)
+ {
+ LONG x = cursorX - cursorHX;
+ LONG y = cursorY - cursorHY;
+ LONG w = cursorW;
+ LONG h = cursorH;
+
+ SVGA_UpdateRect(x, y, w, h);
+ }
+ }
+}
+
+BOOL hwcursor_available()
+{
+ if(wBpp != 32)
+ {
+ return FALSE;
+ }
+
+ if((gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR) == 0)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/hwcursor.h b/hwcursor.h
new file mode 100644
index 0000000..557c7d3
--- /dev/null
+++ b/hwcursor.h
@@ -0,0 +1,10 @@
+#ifndef __HWCURSOR_INCLUDED__
+#define __HWCURSOR_INCLUDED__
+
+void SVGA_UpdateLongRect(longRECT __far *rect);
+BOOL hwcursor_move(WORD absX, WORD absY);
+BOOL hwcursor_load(CURSORSHAPE __far *lpCursor);
+void hwcursor_update();
+BOOL hwcursor_available();
+
+#endif
diff --git a/makefile b/makefile
index 77c552a..9297caa 100644
--- a/makefile
+++ b/makefile
@@ -5,7 +5,7 @@ OBJS = dibthunk.obj dibcall.obj enable.obj init.obj palette.obj &
pci.obj svga.obj svga3d.obj svga32.obj pci32.obj dddrv.obj &
enable_svga.obj dibcall_svga.obj boxv_qemu.obj modes_qemu.obj &
init_qemu.obj init_svga.obj qemuvxd.obj minivdd_qemu.obj &
- vxdcall_qemu.obj control_qemu.obj
+ vxdcall_qemu.obj control_qemu.obj swcursor.obj hwcursor.obj
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
@@ -152,6 +152,12 @@ minivdd_qemu.obj : minivdd_qemu.c .autodepend
dddrv.obj : dddrv.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+swcursor.obj: swcursor.c .autodepend
+ $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+
+hwcursor.obj: hwcursor.c .autodepend
+ $(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
+
# Resources
boxvmini.res : res/boxvmini.rc res/colortab.bin res/config.bin res/fonts.bin res/fonts120.bin .autodepend
wrc -q -r -ad -bt=windows -fo=$@ -Ires -I$(%WATCOM)/h/win $(FLAGS) res/boxvmini.rc
@@ -200,6 +206,7 @@ file modes.obj
file boxv.obj
file control.obj
file dddrv.obj
+file swcursor.obj
name boxvmini.drv
option map=boxvmini.map
library dibeng.lib
@@ -270,6 +277,8 @@ file pci.obj
file control_svga.obj
file vxdcall_svga.obj
file dddrv.obj
+file swcursor.obj
+file hwcursor.obj
name vmwsmini.drv
option map=vmwsmini.map
library dibeng.lib
@@ -338,6 +347,7 @@ file boxv_qemu.obj
file control_qemu.obj
file vxdcall_qemu.obj
file dddrv.obj
+file swcursor.obj
name qemumini.drv
option map=qemumini.map
library dibeng.lib
diff --git a/minidrv.h b/minidrv.h
index 9946718..6ada593 100644
--- a/minidrv.h
+++ b/minidrv.h
@@ -82,6 +82,7 @@ extern RGBQUAD FAR *lpColorTable; /* Current color table. */
extern DWORD dwScreenFlatAddr; /* Linear address of frame buffer */
extern DWORD dwVideoMemorySize; /* Installed VRAM in bytes. */
+extern WORD wScreenPitchBytes; /* screen pitch */
extern DWORD VDDEntryPoint;
extern WORD OurVMHandle;
@@ -96,6 +97,13 @@ WORD CalcPitch(WORD x, WORD bpp);
typedef void (__far * FastBitBlt_t) (unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h);
extern FastBitBlt_t FastBitBlt;
+typedef struct _longRECT {
+ LONG left;
+ LONG top;
+ LONG right;
+ LONG bottom;
+} longRECT;
+
/*
* frame buffer direct hadrware access, allow user space programs/drivers write
* to device frame buffer directly
@@ -111,10 +119,21 @@ typedef struct _FBHDA
DWORD fb_pm32; /* eq. linear address, mapped to shared or kernel space*/
void __far * fb_pm16; /* usable in this driver */
DWORD flags;
+ volatile DWORD lock; /* lock for framebuffer operations */
+ DWORD vram_pm32;
+ void __far * vram_pm16;
+ DWORD vram_size;
} FBHDA;
+
#pragma pack(pop)
+#define FBHDA_SIZE 4096 /* alloc whole page */
+
#define FBHDA_NEED_UPDATE 1
+#define FBHDA_LOCKING 2
+#define FBHDA_FLIPING 4
+#define FBHDA_SW_CURSOR 8
+//#define FBHDA_NO_CURSOR 16
extern FBHDA __far * FBHDA_ptr;
extern DWORD FBHDA_linear;
diff --git a/modes.c b/modes.c
index a0d2e4a..42b3e45 100644
--- a/modes.c
+++ b/modes.c
@@ -73,11 +73,12 @@ WORD wMesa3DEnabled = 0; /* 3D is enabled (by hypervisor) */
/* FBHDA structure pointers */
FBHDA __far * FBHDA_ptr = NULL;
+
DWORD FBHDA_linear = 0;
DWORD dwScreenFlatAddr = 0; /* 32-bit flat address of VRAM. */
DWORD dwVideoMemorySize = 0; /* Installed VRAM in bytes. */
-static WORD wScreenPitchBytes = 0; /* Current scanline pitch. */
+ WORD wScreenPitchBytes = 0; /* Current scanline pitch. */
#ifndef SVGA
static DWORD dwPhysVRAM = 0; /* Physical LFB base address. */
#endif
@@ -319,28 +320,36 @@ static void SVGA_defineScreen(unsigned wXRes, unsigned wYRes, unsigned wBpp)
SVGAFifoCmdDefineScreen __far *screen;
SVGAFifoCmdDefineGMRFB __far *fbgmr;
- /* create screen 0 */
+ /* create screen 0 */
screen = SVGA_FIFOReserveCmd(SVGA_CMD_DEFINE_SCREEN, sizeof(SVGAFifoCmdDefineScreen));
- if(screen)
- {
- _fmemset(screen, 0, sizeof(SVGAFifoCmdDefineScreen));
- screen->screen.structSize = sizeof(SVGAScreenObject);
- screen->screen.id = 0;
- screen->screen.flags = SVGA_SCREEN_MUST_BE_SET | SVGA_SCREEN_IS_PRIMARY;
- screen->screen.size.width = wXRes;
- screen->screen.size.height = wYRes;
- screen->screen.root.x = 0;
- screen->screen.root.y = 0;
- screen->screen.cloneCount = 0;
-
- screen->screen.backingStore.pitch = CalcPitch(wXRes, wBpp);
-
- VXD_FIFOCommitAll();
- }
-
+ if(screen)
+ {
+ _fmemset(screen, 0, sizeof(SVGAFifoCmdDefineScreen));
+ screen->screen.structSize = sizeof(SVGAScreenObject);
+ screen->screen.id = 0;
+ screen->screen.flags = SVGA_SCREEN_MUST_BE_SET | SVGA_SCREEN_IS_PRIMARY;
+ screen->screen.size.width = wXRes;
+ screen->screen.size.height = wYRes;
+ screen->screen.root.x = 0;
+ screen->screen.root.y = 0;
+ screen->screen.cloneCount = 0;
+
+ if(wBpp < 32)
+ {
+ screen->screen.backingStore.pitch = CalcPitch(wXRes, wBpp);
+ }
+
+ screen->screen.backingStore.ptr.offset = 0;
+ screen->screen.backingStore.ptr.gmrId = SVGA_GMR_FRAMEBUFFER;
+
+ //screen->screen.backingStore.pitch = CalcPitch(wXRes, wBpp);
+
+ VXD_FIFOCommitAll();
+ }
+
/* set GMR to same location as screen */
- if(wBpp >= 15)
+ if(wBpp >= 15/* || wBpp < 32*/)
{
fbgmr = SVGA_FIFOReserveCmd(SVGA_CMD_DEFINE_GMRFB, sizeof(SVGAFifoCmdDefineGMRFB));
@@ -353,18 +362,23 @@ static void SVGA_defineScreen(unsigned wXRes, unsigned wYRes, unsigned wBpp)
if(wBpp >= 24)
{
fbgmr->format.bitsPerPixel = 32;
+ fbgmr->format.colorDepth = 24;
+ fbgmr->format.reserved = 0;
}
else
{
fbgmr->format.bitsPerPixel = 16;
+ fbgmr->format.colorDepth = 16;
+ fbgmr->format.reserved = 0;
}
+
+ VXD_FIFOCommitAll();
}
- VXD_FIFOCommitAll();
}
}
/* Check if screen acceleration is available */
-static BOOL SVGA_hasAccelScreen()
+BOOL SVGA_hasAccelScreen()
{
if(SVGA_HasFIFOCap(SVGA_FIFO_CAP_SCREEN_OBJECT | SVGA_FIFO_CAP_SCREEN_OBJECT_2))
{
@@ -440,7 +454,7 @@ void SVGA_MapIO()
DWORD rmmio_sel = 0;
/* get system linear addresses from PM32 RING-0 driver */
- if(SVGA_IsSvga3())
+ if(SVGA_IsSVGA3())
{
VXD_get_addr(&gSVGA.fbLinear, &gSVGA.rmmio_linear, &gSVGA.fifo.bounceLinear);
@@ -543,7 +557,7 @@ static int SetDisplayMode( WORD wXRes, WORD wYRes, int bFullSet )
/* stop command buffer context 0 */
CB_stop();
-
+
SVGA_SetMode(wXRes, wYRes, wBpp); /* setup by legacy registry */
SVGA_Flush(); /* make sure, that is really set */
wMesa3DEnabled = 0;
@@ -599,12 +613,22 @@ static int SetDisplayMode( WORD wXRes, WORD wYRes, int bFullSet )
FBHDA_ptr->width = wScrX;
FBHDA_ptr->height = wScrY;
FBHDA_ptr->bpp = wBpp;
+ FBHDA_ptr->flags = FBHDA_LOCKING | FBHDA_SW_CURSOR;
+ FBHDA_ptr->fb_pm32 = dwScreenFlatAddr; /* change mode reset FB offset */
#ifdef SVGA
FBHDA_ptr->pitch = SVGA_ReadReg(SVGA_REG_BYTES_PER_LINE);
- FBHDA_ptr->flags = FBHDA_NEED_UPDATE;
+ if(wBpp == 32)
+ {
+ FBHDA_ptr->flags |= FBHDA_NEED_UPDATE;
+
+ if(gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR)
+ {
+ FBHDA_ptr->flags ^= FBHDA_SW_CURSOR;
+ }
+ }
#else
FBHDA_ptr->pitch = CalcPitch( wScrX, wBpp );
- FBHDA_ptr->flags = 0;
+ FBHDA_ptr->flags |= FBHDA_FLIPING;
#endif
}
@@ -738,16 +762,36 @@ int PhysicalEnable( void )
/* allocate and fill FBHDA */
if(FBHDA_ptr == NULL)
{
- FBHDA_ptr = drv_malloc(sizeof(FBHDA), &FBHDA_linear);
+ FBHDA_ptr = drv_malloc(FBHDA_SIZE, &FBHDA_linear);
if(FBHDA_ptr)
{
FBHDA_ptr->width = wScrX;
FBHDA_ptr->height = wScrY;
FBHDA_ptr->bpp = wBpp;
FBHDA_ptr->pitch = wScreenPitchBytes;
+ FBHDA_ptr->flags = FBHDA_LOCKING | FBHDA_SW_CURSOR;
FBHDA_ptr->fb_pm32 = dwScreenFlatAddr;
FBHDA_ptr->fb_pm16 = ScreenSelector :> 0;
+
+ FBHDA_ptr->lock = 0;
+
+ FBHDA_ptr->vram_pm32 = dwScreenFlatAddr;
+ FBHDA_ptr->vram_pm16 = ScreenSelector :> 0;
+ FBHDA_ptr->vram_size = dwVideoMemorySize;
+
+#ifdef SVGA
+ if(wBpp == 32)
+ {
+ FBHDA_ptr->flags |= FBHDA_NEED_UPDATE;
+ if(gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR)
+ {
+ FBHDA_ptr->flags ^= FBHDA_SW_CURSOR;
+ }
+ }
+#else
+ FBHDA_ptr->flags |= FBHDA_FLIPING;
+#endif
}
else
{
diff --git a/swcursor.c b/swcursor.c
new file mode 100644
index 0000000..508ed1c
--- /dev/null
+++ b/swcursor.c
@@ -0,0 +1,648 @@
+/*****************************************************************************
+
+Copyright (c) 2023 Jaroslav Hensl
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*****************************************************************************/
+
+#include "winhack.h"
+#include <gdidefs.h>
+#include <dibeng.h>
+#include <minivdd.h>
+#include <string.h>
+
+#include "minidrv.h"
+#include "dpmi.h"
+#include "drvlib.h"
+#include "swcursor.h"
+
+struct _SWCURSOR
+{
+ long x; /* pointer X */
+ long y; /* pointer Y */
+ long offx;
+ long offy;
+ long w;
+ long h;
+ long hotx;
+ long hoty;
+ long lastx; /* blitted offx */
+ long lasty; /* blitted offy */
+ long lastw;
+ long lasth;
+ DWORD ps;
+ DWORD state;
+ long blitlock;
+ BYTE data[1];
+};
+
+#define STATE_EMPTY 0
+#define STATE_BLITED 1
+#define STATE_ERASED 2
+
+BOOL sw_cursor_enabled = FALSE;
+SWCURSOR __far *sw_cursor = NULL;
+static BYTE __far *cursor_andmask = NULL;
+static BYTE __far *cursor_xormask = NULL;
+static BYTE __far *cursor_backdata = NULL;
+
+#define CURSOR_MAX_SIZE 65536
+
+static DWORD sw_cursor_lin = 0;
+static WORD fb_desc = 0;
+static DWORD fb_desc_base = 0;
+
+#pragma code_seg( _TEXT )
+
+static void __far *GetLinePtr(long y)
+{
+ DWORD y_lin = dwScreenFlatAddr + (DWORD)wScreenPitchBytes*y;
+ DWORD y_lin_max = y_lin + wScreenPitchBytes;
+
+ if(fb_desc_base > y_lin ||
+ y_lin-fb_desc_base > 65536 ||
+ y_lin_max-fb_desc_base > 65536
+ )
+ {
+ DPMI_SetSegBase(fb_desc, y_lin);
+ fb_desc_base = y_lin;
+ }
+
+ return fb_desc :> (WORD)(y_lin - fb_desc_base);
+}
+
+void cursor_merge_rect(longRECT __far *r1, longRECT __far *r2)
+{
+ if(r1->left == r1->right)
+ {
+ if(r2->left == r2->right)
+ {
+ return;
+ }
+
+ *r1 = *r2;
+ return;
+ }
+
+ if(r2->left == r2->right)
+ {
+ return;
+ }
+
+ if(r2->left < r1->left)
+ r1->left = r2->left;
+
+ if(r2->top < r1->top)
+ r1->top = r2->top;
+
+ if(r2->right > r1->right)
+ r1->right = r2->right;
+
+ if(r2->bottom > r1->bottom)
+ r1->bottom = r2->bottom;
+}
+
+static void cursor_cs_enter()
+{
+ _asm
+ {
+ mov ax, 1681h
+ int 2Fh
+ };
+}
+
+static void cursor_cs_leave()
+{
+ _asm
+ {
+ mov ax, 1682h
+ int 2Fh
+ };
+}
+
+
+BOOL cursor_init()
+{
+ cursor_cs_enter();
+
+ fb_desc = DPMI_AllocLDTDesc(1);
+
+ if(fb_desc)
+ {
+ SWCURSOR __far *cur = drv_malloc(CURSOR_MAX_SIZE, &sw_cursor_lin);
+ if(cur)
+ {
+ fb_desc_base = dwScreenFlatAddr;
+ DPMI_SetSegBase(fb_desc, fb_desc_base);
+ DPMI_SetSegLimit(fb_desc, CURSOR_MAX_SIZE-1);
+ _fmemset(cur, 0, sizeof(SWCURSOR));
+ cur->state = STATE_EMPTY;
+
+ sw_cursor = cur;
+ sw_cursor_enabled = TRUE;
+
+ cursor_cs_leave();
+ return TRUE;
+ }
+ }
+
+ cursor_cs_leave();
+ return FALSE;
+}
+
+#define EXPAND_BIT(_dsttype, _bit) (~(((_dsttype)(_bit))-1))
+//#define EXPAND_BIT(_dsttype, _bit) ((_bit) > 0 ? 0xFFFFFFFF : 0)
+
+/*
+ * load cursor from CURSHAPE and convert it to display BPP
+ */
+BOOL cursor_load(CURSORSHAPE __far *lpCursor, longRECT __far *changes)
+{
+ //dbg_printf("cursor_load: %d\n", wBpp);
+
+ if(sw_cursor)
+ {
+ unsigned int ps = (wBpp + 7)/8;
+ const DWORD data_size = lpCursor->cx * lpCursor->cy * ps;
+
+ BYTE __far *DstAndMask = &sw_cursor->data[0];
+ BYTE __far *DstXorMask = &sw_cursor->data[data_size];
+
+ BYTE __far *andmask = (BYTE __far *)(lpCursor + 1);
+ BYTE __far *xormask = (BYTE __far *)(andmask + lpCursor->cbWidth*lpCursor->cy);
+
+ longRECT r1 = {0, 0, 0, 0};
+ longRECT r2 = {0, 0, 0, 0};
+ BOOL is_blitted = FALSE;
+
+ /* maximum cursor size in 32bit mode is 64x64 px */
+ if(data_size * 3 + sizeof(SWCURSOR) > CURSOR_MAX_SIZE)
+ {
+ return FALSE;
+ }
+
+ if(sw_cursor->state == STATE_BLITED)
+ {
+ is_blitted = TRUE;
+ cursor_erase(&r1);
+ }
+
+ cursor_cs_enter();
+
+ if(lpCursor->BitsPixel == 1)
+ {
+ int xi, xj, y;
+
+ for(y = 0; y < lpCursor->cy; y++)
+ {
+ for(xj = 0; xj < lpCursor->cbWidth; xj++)
+ {
+ BYTE a = andmask[lpCursor->cbWidth*y + xj];
+ BYTE x = xormask[lpCursor->cbWidth*y + xj];
+
+ for(xi = 7; xi >= 0; xi--)
+ {
+ switch(wBpp)
+ {
+ case 8:
+ {
+ DstAndMask[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(BYTE, ((a >> xi) & 0x1));
+ DstXorMask[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(BYTE, ((x >> xi) & 0x1));
+ break;
+ }
+ case 16:
+ {
+ ((WORD __far*)DstAndMask)[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(WORD, ((a >> xi) & 0x1));
+ ((WORD __far*)DstXorMask)[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(WORD, ((x >> xi) & 0x1));
+ break;
+ }
+ case 24:
+ {
+ DWORD am = EXPAND_BIT(DWORD, ((a >> xi) & 0x1));
+ DWORD xm = EXPAND_BIT(DWORD, ((x >> xi) & 0x1));
+ WORD pos = (lpCursor->cx * y + xj*8 + (7-xi))*3;
+
+ DstAndMask[pos] = am & 0xFF;
+ DstAndMask[pos+1] = (am >> 8) & 0xFF;
+ DstAndMask[pos+2] = (am >> 16) & 0xFF;
+
+ DstXorMask[pos] = xm & 0xFF;
+ DstXorMask[pos+1] = (xm >> 8) & 0xFF;
+ DstXorMask[pos+2] = (xm >> 16) & 0xFF;
+
+ break;
+ }
+ case 32:
+ {
+ ((DWORD __far*)DstAndMask)[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(DWORD, ((a >> xi) & 0x1));
+ ((DWORD __far*)DstXorMask)[lpCursor->cx * y + xj*8 + (7-xi)] = EXPAND_BIT(DWORD, ((x >> xi) & 0x1));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if(lpCursor->BitsPixel == wBpp)
+ {
+ _fmemcpy(DstAndMask, andmask, ps * lpCursor->cx * lpCursor->cy);
+ _fmemcpy(DstXorMask, xormask, ps * lpCursor->cx * lpCursor->cy);
+ }
+ else
+ {
+ cursor_cs_leave();
+ return FALSE;
+ }
+
+ sw_cursor->x = cursorX;
+ sw_cursor->y = cursorY;
+
+ sw_cursor->w = lpCursor->cx;
+ sw_cursor->h = lpCursor->cy;
+
+ sw_cursor->hotx = lpCursor->xHotSpot;
+ sw_cursor->hoty = lpCursor->yHotSpot;
+
+ sw_cursor->ps = ps;
+ if(sw_cursor->state != STATE_BLITED)
+ {
+ sw_cursor->state = STATE_ERASED;
+ }
+
+ cursor_andmask = DstAndMask;
+ cursor_xormask = DstXorMask;
+ cursor_backdata = (BYTE __far *)sw_cursor + (CURSOR_MAX_SIZE - 64*64*4);//DstXorMask + data_size;
+
+ cursor_cs_leave();
+
+ if(is_blitted)
+ {
+ cursor_coordinates(cursorX, cursorY);
+ cursor_blit(&r2);
+ cursor_merge_rect(&r1, &r2);
+ }
+
+ if(changes)
+ {
+ *changes = r1;
+ }
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void cursor_unload(longRECT __far *changes)
+{
+ //dbg_printf("cursor_unload\n");
+
+ if(sw_cursor)
+ {
+ longRECT r1 = {0,0,0,0};
+
+ if(sw_cursor->state == STATE_BLITED)
+ {
+ cursor_erase(&r1);
+ }
+
+ sw_cursor->state = STATE_EMPTY;
+
+ if(changes)
+ {
+ *changes = r1;
+ }
+ }
+}
+
+void cursor_coordinates(long curx, long cury)
+{
+ if(sw_cursor)
+ {
+ cursor_cs_enter();
+ if(sw_cursor->state != STATE_BLITED)
+ {
+ sw_cursor->x = curx;
+ sw_cursor->y = cury;
+ sw_cursor->offx = curx - sw_cursor->hotx;
+ sw_cursor->offy = cury - sw_cursor->hoty;
+ }
+ cursor_cs_leave();
+ }
+}
+
+void cursor_move(longRECT __far *changes)
+{
+ if(sw_cursor)
+ {
+ if(sw_cursor->blitlock == 0)
+ {
+ longRECT r1 = {0, 0, 0, 0}, r2 = {0, 0, 0, 0};
+ BOOL blitted = FALSE;
+
+ if(sw_cursor->state == STATE_EMPTY)
+ {
+ return;
+ }
+
+ if(sw_cursor->state == STATE_BLITED)
+ {
+ cursor_erase(&r1);
+ blitted = TRUE;
+ }
+
+ cursor_coordinates(cursorX, cursorY);
+
+ if(blitted)
+ {
+ cursor_blit(&r2);
+ }
+
+ if(changes)
+ {
+ cursor_merge_rect(&r1, &r2);
+ *changes = r1;
+ }
+ }
+ }
+}
+
+void cursor_erase(longRECT __far *changes)
+{
+ //dbg_printf("cursor_erase\n");
+
+ if(sw_cursor)
+ {
+ long x, y;
+
+ if(sw_cursor->ps != (wBpp + 7)/8)
+ {
+ return;
+ }
+
+ cursor_cs_enter();
+ if(sw_cursor->state == STATE_BLITED && sw_cursor->blitlock == 0)
+ {
+ sw_cursor->blitlock++;
+ switch(sw_cursor->ps)
+ {
+ case 1:
+ {
+ for(y = sw_cursor->lasty; y < sw_cursor->lasty + sw_cursor->lasth; y++){
+ if(y >= 0 && y < wScrY){
+ BYTE __far *dst = GetLinePtr(y);
+ BYTE __far *src = cursor_backdata + ((y - sw_cursor->lasty)*sw_cursor->w);
+ for(x = sw_cursor->lastx; x < sw_cursor->lastx + sw_cursor->lastw; x++){
+ if(x >= 0 && x < wScrX){
+ dst[x] = *src;
+ }
+ src++;
+ } } }
+ break;
+ }
+ case 2:
+ {
+ for(y = sw_cursor->lasty; y < sw_cursor->lasty + sw_cursor->lasth; y++){
+ if(y >= 0 && y < wScrY){
+ WORD __far *dst = GetLinePtr(y);
+ WORD __far *src = (WORD __far *)cursor_backdata + ((y - sw_cursor->lasty)*sw_cursor->w);
+ for(x = sw_cursor->lastx; x < sw_cursor->lastx + sw_cursor->lastw; x++){
+ if(x >= 0 && x < wScrX){
+ dst[x] = *src;
+ }
+ src++;
+ } } }
+ break;
+ }
+ case 3:
+ {
+ for(y = sw_cursor->lasty; y < sw_cursor->lasty + sw_cursor->lasth; y++){
+ if(y >= 0 && y < wScrY){
+ BYTE __far *dst = GetLinePtr(y);
+ BYTE __far *src = cursor_backdata + ((y - sw_cursor->lasty)*sw_cursor->w)*3;
+ for(x = sw_cursor->lastx; x < sw_cursor->lastx + sw_cursor->lastw; x++){
+ if(x >= 0 && x < wScrX){
+ dst[x*3 ] = *src;
+ dst[x*3+1] = *(src+1);
+ dst[x*3+2] = *(src+2);
+ }
+ src += 3;
+ } } }
+ break;
+ }
+ case 4:
+ {
+ for(y = sw_cursor->lasty; y < sw_cursor->lasty + sw_cursor->lasth; y++){
+ if(y >= 0 && y < wScrY){
+ DWORD __far *dst = GetLinePtr(y);
+ DWORD __far *src = (DWORD __far *)cursor_backdata + ((y - sw_cursor->lasty)*sw_cursor->w);
+ for(x = sw_cursor->lastx; x < sw_cursor->lastx + sw_cursor->lastw; x++){
+ if(x >= 0 && x < wScrX){
+ dst[x] = *src;
+ }
+ src++;
+ } } }
+ break;
+ }
+ } // switch bpp
+
+ sw_cursor->state = STATE_ERASED;
+
+ if(changes)
+ {
+ changes->left = sw_cursor->lastx;
+ changes->right = sw_cursor->lastx + sw_cursor->lastw;
+
+ changes->top = sw_cursor->lasty;
+ changes->bottom = sw_cursor->lasty + sw_cursor->lasth;
+ }
+
+ sw_cursor->blitlock--;
+ }
+ else
+ {
+ if(changes)
+ {
+ changes->left = 0;
+ changes->right = 0;
+ changes->top = 0;
+ changes->bottom = 0;
+ }
+ }
+ cursor_cs_leave();
+ }
+}
+
+void cursor_lock()
+{
+ if(sw_cursor)
+ {
+ cursor_cs_enter();
+ sw_cursor->blitlock++;
+ cursor_cs_leave();
+ }
+}
+
+void cursor_unlock()
+{
+ if(sw_cursor)
+ {
+ cursor_cs_enter();
+ sw_cursor->blitlock--;
+ if(sw_cursor->blitlock < 0)
+ {
+ sw_cursor->blitlock = 0;
+ }
+ cursor_cs_leave();
+ }
+}
+
+void cursor_blit(longRECT __far *changes)
+{
+ //dbg_printf("cursor_blit\n");
+
+ if(sw_cursor)
+ {
+ long x, y;
+
+ if(sw_cursor->ps != (wBpp + 7)/8)
+ {
+ return;
+ }
+
+ cursor_cs_enter();
+ if(sw_cursor->state == STATE_ERASED && sw_cursor->blitlock == 0)
+ {
+ //dbg_printf("blit: state - %ld\n", sw_cursor->state);
+ sw_cursor->blitlock++;
+
+ switch(sw_cursor->ps)
+ {
+ case 1:
+ {
+ for(y = sw_cursor->offy; y < sw_cursor->offy + sw_cursor->h; y++){
+ if(y >= 0 && y < wScrY){
+ const long ptx = (y - sw_cursor->offy)*sw_cursor->w;
+ BYTE __far *dst = GetLinePtr(y);
+ BYTE __far *bd = cursor_backdata + ptx;
+ BYTE __far *am = cursor_andmask + ptx;
+ BYTE __far *xm = cursor_xormask + ptx;
+ for(x = sw_cursor->offx; x < sw_cursor->offx + sw_cursor->w; x++){
+ if(x >= 0 && x < wScrX){
+ *bd = dst[x];
+ dst[x] &= *am;
+ dst[x] ^= *xm;
+ }
+ bd++; am++; xm++;
+ } } }
+ break;
+ }
+ case 2:
+ {
+ for(y = sw_cursor->offy; y < sw_cursor->offy + sw_cursor->h; y++){
+ if(y >= 0 && y < wScrY){
+ const long ptx = (y - sw_cursor->offy)*sw_cursor->w;
+ WORD __far *dst = GetLinePtr(y);
+ WORD __far *bd = (WORD __far *)(cursor_backdata) + ptx;
+ WORD __far *am = (WORD __far *)(cursor_andmask) + ptx;
+ WORD __far *xm = (WORD __far *)(cursor_xormask) + ptx;
+ for(x = sw_cursor->offx; x < sw_cursor->offx + sw_cursor->w; x++){
+ if(x >= 0 && x < wScrX){
+ *bd = dst[x];
+ dst[x] &= *am;
+ dst[x] ^= *xm;
+ }
+ bd++; am++; xm++;
+ } } }
+ break;
+ }
+ case 3:
+ {
+ for(y = sw_cursor->offy; y < sw_cursor->offy + sw_cursor->h; y++){
+ if(y >= 0 && y < wScrY){
+ const long ptx = (y - sw_cursor->offy)*sw_cursor->w*3;
+ BYTE __far *dst = GetLinePtr(y);
+ BYTE __far *bd = cursor_backdata + ptx;
+ BYTE __far *am = cursor_andmask + ptx;
+ BYTE __far *xm = cursor_xormask + ptx;
+ for(x = sw_cursor->offx; x < sw_cursor->offx + sw_cursor->w; x++){
+ if(x >= 0 && x < wScrX){
+ *bd = dst[x*3 ]; dst[x*3 ] &= *am; dst[x*3 ] ^= *xm;
+ *(bd+1) = dst[x*3+1]; dst[x*3+1] &= *(am+1); dst[x*3+1] ^= *(xm+1);
+ *(bd+2) = dst[x*3+2]; dst[x*3+2] &= *(am+2); dst[x*3+2] ^= *(xm+2);
+ }
+ bd += 3;
+ am += 3;
+ xm += 3;
+ } } }
+ break;
+ }
+ case 4:
+ {
+ for(y = sw_cursor->offy; y < sw_cursor->offy + sw_cursor->h; y++){
+ if(y >= 0 && y < wScrY){
+ const long ptx = (y - sw_cursor->offy)*sw_cursor->w;
+ DWORD __far *dst = GetLinePtr(y);
+ DWORD __far *bd = (DWORD __far *)(cursor_backdata) + ptx;
+ DWORD __far *am = (DWORD __far *)(cursor_andmask) + ptx;
+ DWORD __far *xm = (DWORD __far *)(cursor_xormask) + ptx;
+ for(x = sw_cursor->offx; x < sw_cursor->offx + sw_cursor->w; x++){
+ if(x >= 0 && x < wScrX){
+ *bd = dst[x];
+ dst[x] &= *am;
+ dst[x] ^= *xm;
+ }
+ bd++; am++; xm++;
+ } } }
+ break;
+ }
+ } // switch bpp
+
+ sw_cursor->state = STATE_BLITED;
+ sw_cursor->lastx = sw_cursor->offx;
+ sw_cursor->lasty = sw_cursor->offy;
+ sw_cursor->lastw = sw_cursor->w;
+ sw_cursor->lasth = sw_cursor->h;
+
+ if(changes)
+ {
+ changes->left = sw_cursor->offx;
+ changes->right = sw_cursor->offx + sw_cursor->w;
+
+ changes->top = sw_cursor->offy;
+ changes->bottom = sw_cursor->offy + sw_cursor->h;
+ }
+ sw_cursor->blitlock--;
+ } /* !empty */
+ else
+ {
+ //dbg_printf("cursor_blit: state %ld, lock: %ld\n", sw_cursor->state, sw_cursor->blitlock);
+
+ if(changes)
+ {
+ changes->left = 0;
+ changes->right = 0;
+ changes->top = 0;
+ changes->bottom = 0;
+ }
+ }
+ cursor_cs_leave();
+ }
+}
+
diff --git a/swcursor.h b/swcursor.h
new file mode 100644
index 0000000..d8d5af8
--- /dev/null
+++ b/swcursor.h
@@ -0,0 +1,38 @@
+#ifndef __SWCURSOR_H__INCLUDED__
+#define __SWCURSOR_H__INCLUDED__
+
+/* from dibcall.c */
+extern LONG cursorX;
+extern LONG cursorY;
+
+/* from DDK98 */
+#pragma pack(push)
+#pragma pack(1)
+typedef struct
+{
+ int xHotSpot, yHotSpot;
+ int cx, cy;
+ int cbWidth;
+ BYTE Planes;
+ BYTE BitsPixel;
+} CURSORSHAPE;
+#pragma pack(pop)
+
+typedef struct _SWCURSOR SWCURSOR;
+
+BOOL cursor_init();
+BOOL cursor_load(CURSORSHAPE __far *lpCursor, longRECT __far *changes);
+void cursor_unload(longRECT __far *changes);
+void cursor_coordinates(long curx, long cury);
+void cursor_erase(longRECT __far *changes);
+void cursor_blit(longRECT __far *changes);
+void cursor_move(longRECT __far *changes);
+void cursor_merge_rect(longRECT __far *r1, longRECT __far *r2);
+
+void cursor_lock();
+void cursor_unlock();
+
+extern BOOL sw_cursor_enabled;
+extern SWCURSOR __far *sw_cursor;
+
+#endif /* __SWCURSOR_H__INCLUDED__ */
diff --git a/vmdahal.h b/vmdahal.h
index 519f1fe..9fe8bea 100644
--- a/vmdahal.h
+++ b/vmdahal.h
@@ -21,6 +21,9 @@ typedef struct VMDAHALCB32
LPDDHALSURFCB_UPDATEOVERLAY UpdateOverlay;
LPDDHALSURFCB_SETOVERLAYPOSITION SetOverlayPosition;
LPDDHAL_GETDRIVERINFO GetDriverInfo;
+ LPDDHAL_WAITFORVERTICALBLANK WaitForVerticalBlank;
+ LPDDHAL_SETMODE SetMode;
+ LPDDHAL_SETEXCLUSIVEMODE SetExclusiveMode;
} VMDAHALCB32_t;
typedef struct VMDAHAL
@@ -41,6 +44,11 @@ typedef struct VMDAHAL
DWORD hInstance;
+ DWORD pFBHDA32;
+ void __far *pFBHDA16;
+ DWORD FBHDA_version;
+
+ DWORD hDC;
} VMDAHAL_t;
#pragma pack(pop)