aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <emulator@emulace.cz>2024-06-13 10:20:58 +0200
committerJaroslav Hensl <emulator@emulace.cz>2024-06-13 10:20:58 +0200
commit4b02bef1a7b00ca8a392b7fa7ef36d6ad8fd4e88 (patch)
treecc0eab7b3d6d49e5faa8d7860c34476137c6d2f7
parent1280980dd1b1ed8c87c29ea3f95c4c58f844c295 (diff)
downloadvmdisp9x-4b02bef1a7b00ca8a392b7fa7ef36d6ad8fd4e88.tar.gz
accelerated mouse on screen target
-rw-r--r--makefile14
-rw-r--r--vxd_mouse.c46
-rw-r--r--vxd_mouse_svga.c2
-rw-r--r--vxd_strings.h4
-rw-r--r--vxd_svga.c2
-rw-r--r--vxd_svga.h9
-rw-r--r--vxd_svga_mouse.c246
-rw-r--r--vxd_svga_st.c1
8 files changed, 319 insertions, 5 deletions
diff --git a/makefile b/makefile
index 520e298..36e6896 100644
--- a/makefile
+++ b/makefile
@@ -7,7 +7,8 @@ OBJS = &
OBJS += &
dbgprint32.obj svga.obj pci.obj vxd_fbhda.obj vxd_lib.obj vxd_main.obj &
vxd_main_qemu.obj vxd_main_svga.obj vxd_svga.obj vxd_vdd.obj vxd_vdd_qemu.obj &
- vxd_vdd_svga.obj vxd_vbe.obj vxd_vbe_qemu.obj vxd_mouse.obj vxd_svga_st.obj
+ vxd_vdd_svga.obj vxd_vbe.obj vxd_vbe_qemu.obj vxd_mouse.obj vxd_svga_st.obj &
+ vxd_mouse_svga.obj vxd_svga_mouse.obj
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
@@ -34,7 +35,7 @@ FIXER_CC = wcl386 -q drvfix.c -fe=$(FIXER_EXE)
#FLAGS += -DHWBLT
# Set DBGPRINT to add debug printf logging.
-#DBGPRINT = 1
+DBGPRINT = 1
!ifdef DBGPRINT
FLAGS += -DDBGPRINT
@@ -157,12 +158,18 @@ vxd_main_svga.obj : vxd_main_svga.c .autodepend
vxd_mouse.obj : vxd_mouse.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+vxd_mouse_svga.obj : vxd_mouse_svga.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
vxd_svga.obj : vxd_svga.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
vxd_svga_st.obj : vxd_svga_st.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+vxd_svga_mouse.obj : vxd_svga_mouse.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
vxd_vbe.obj : vxd_vbe.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
@@ -426,8 +433,9 @@ file vxd_fbhda.obj
file vxd_lib.obj
file vxd_svga.obj
file vxd_svga_st.obj
+file vxd_svga_mouse.obj
file vxd_vdd_svga.obj
-file vxd_mouse.obj
+file vxd_mouse_svga.obj
segment '_LTEXT' PRELOAD NONDISCARDABLE
segment '_TEXT' PRELOAD NONDISCARDABLE
segment '_DATA' PRELOAD NONDISCARDABLE
diff --git a/vxd_mouse.c b/vxd_mouse.c
index 1c6eb76..ea4de37 100644
--- a/vxd_mouse.c
+++ b/vxd_mouse.c
@@ -31,6 +31,10 @@ THE SOFTWARE.
#include "cursor.h"
+#ifdef SVGA
+#include "vxd_svga.h"
+#endif
+
#include "code32.h"
extern FBHDA_t *hda;
@@ -96,6 +100,16 @@ BOOL mouse_load()
DWORD cbw;
if(!mouse_buffer_mem) return FALSE;
+
+#ifdef SVGA
+ if(SVGA_mouse_hw())
+ {
+ BOOL r = SVGA_mouse_load();
+ mouse_valid = FALSE;
+ mouse_notify_accel();
+ return r;
+ }
+#endif
cur = (CURSORSHAPE*)mouse_buffer_mem;
@@ -188,6 +202,14 @@ BOOL mouse_load()
void mouse_move(int x, int y)
{
+#ifdef SVGA
+ if(SVGA_mouse_hw())
+ {
+ SVGA_mouse_move(x, y);
+ return;
+ }
+#endif
+
if(mouse_valid && mouse_visible && !mouse_empty)
{
FBHDA_access_begin(0);
@@ -204,6 +226,14 @@ void mouse_move(int x, int y)
void mouse_show()
{
+#ifdef SVGA
+ if(SVGA_mouse_hw())
+ {
+ SVGA_mouse_show();
+ return;
+ }
+#endif
+
mouse_visible = TRUE;
mouse_notify_accel();
@@ -211,6 +241,14 @@ void mouse_show()
void mouse_hide()
{
+#ifdef SVGA
+ if(SVGA_mouse_hw())
+ {
+ SVGA_mouse_hide();
+ return;
+ }
+#endif
+
FBHDA_access_begin(0);
mouse_visible = FALSE;
FBHDA_access_end(0);
@@ -220,6 +258,14 @@ void mouse_hide()
void mouse_invalidate()
{
+#ifdef SVGA
+ if(SVGA_mouse_hw())
+ {
+ SVGA_mouse_hide();
+ return;
+ }
+#endif
+
mouse_valid = FALSE;
mouse_notify_accel();
diff --git a/vxd_mouse_svga.c b/vxd_mouse_svga.c
new file mode 100644
index 0000000..ebded7a
--- /dev/null
+++ b/vxd_mouse_svga.c
@@ -0,0 +1,2 @@
+#define SVGA
+#include "vxd_mouse.c"
diff --git a/vxd_strings.h b/vxd_strings.h
index 3d48910..b6ebca2 100644
--- a/vxd_strings.h
+++ b/vxd_strings.h
@@ -130,6 +130,10 @@ DSTR(dbg_lock_fb, "Lock FB buffer: %ld (line: %ld)\n");
DSTR(dbg_cpu_lock, "surface cpu lock for SID: %ld\n");
+DSTR(dbg_hw_mouse_move, "hw mouse: moving: %ld x %ld (visible: %d, valid: %d)\n");
+DSTR(dbg_hw_mouse_show, "hw mouse: show (valid: %d)\n");
+DSTR(dbg_hw_mouse_hide, "hw mouse: hide\n");
+
#undef DSTR
#endif
diff --git a/vxd_svga.c b/vxd_svga.c
index ed1e94a..924d072 100644
--- a/vxd_svga.c
+++ b/vxd_svga.c
@@ -509,7 +509,7 @@ void SVGA_region_usage_reset()
svga_db->stat_regions_usage = 0;
}
-SVGA_DB_surface_t *SVGA_GetSurfaceInfo(uint32 sid)
+SVGA_DB_surface_t *SVGA_GetSurfaceInfo(DWORD sid)
{
if(sid > 0 && sid < SVGA3D_MAX_SURFACE_IDS)
return &(svga_db->surfaces[sid-1]);
diff --git a/vxd_svga.h b/vxd_svga.h
index b28e5e5..9443a22 100644
--- a/vxd_svga.h
+++ b/vxd_svga.h
@@ -14,7 +14,7 @@ BOOL st_memory_allocate(DWORD size, DWORD *out);
void st_defineScreen(DWORD w, DWORD h, DWORD bpp);
void st_destroyScreen();
void SVGA_OTable_load();
-SVGA_DB_surface_t *SVGA_GetSurfaceInfo(uint32 sid);
+SVGA_DB_surface_t *SVGA_GetSurfaceInfo(DWORD sid);
#define ST_REGION_ID 1
#define ST_SURFACE_ID 1
@@ -23,4 +23,11 @@ BOOL st_useable(DWORD bpp);
DWORD map_pm16(DWORD vm, DWORD linear, DWORD size);
+/* mouse */
+BOOL SVGA_mouse_hw();
+BOOL SVGA_mouse_load();
+void SVGA_mouse_move(int x, int y);
+void SVGA_mouse_show();
+void SVGA_mouse_hide();
+
#endif /* __VXD_SVGA_H__INCLUDED__ */
diff --git a/vxd_svga_mouse.c b/vxd_svga_mouse.c
new file mode 100644
index 0000000..c3fea85
--- /dev/null
+++ b/vxd_svga_mouse.c
@@ -0,0 +1,246 @@
+/*****************************************************************************
+
+Copyright (c) 2024 Jaroslav Hensl <emulator@emulace.cz>
+
+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.
+
+*****************************************************************************/
+
+/* 32 bit RING-0 code for SVGA-II HW mouse */
+#define SVGA
+
+#include <limits.h>
+
+#include "winhack.h"
+#include "vmm.h"
+#include "vxd.h"
+#include "vxd_lib.h"
+
+#include "svga_all.h"
+
+#include "3d_accel.h"
+
+#include "cursor.h"
+
+#include "code32.h"
+
+#include "vxd_svga.h"
+
+#include "vxd_strings.h"
+
+extern FBHDA_t *hda;
+
+static BOOL hw_cursor_valid = FALSE;
+static BOOL hw_cursor_visible = FALSE;
+static DWORD mouse_last_x = 0;
+static DWORD mouse_last_y = 0;
+
+static DWORD conv_mask16to32(void *in, void *out, int w, int h)
+{
+ WORD *in16 = in;
+ DWORD *out32 = out;
+ int x, y;
+
+ for(y = 0; y < h; y++)
+ {
+ for(x = 0; x < w; x++)
+ {
+ DWORD px16 = *in16;
+ DWORD px32 = ((px16 & 0xF800) << 8) | ((px16 & 0x07E0) << 5) | ((px16 & 0x001F) << 3);
+ *out32 = px32;
+
+ in16++;
+ out32++;
+ }
+ }
+
+ return w * h * sizeof(DWORD);
+}
+
+static DWORD conv_mask1to32(void *in, void *out, int w, int h, int pitch)
+{
+ BYTE *in1 = in;
+ DWORD *out32 = out;
+ int x, y;
+
+ for(y = 0; y < h; y++)
+ {
+ for(x = 0; x < w; x++)
+ {
+ DWORD b = ((in1[x >> 3] << (x & 0x7)) >> 7) & 0x1;
+ out32[x] = b ? 0x00FFFFFF : 0;
+ }
+
+ out32 += w;
+ in1 += pitch;
+ }
+
+ return w * h * sizeof(DWORD);
+}
+
+static DWORD copy_mask1(void *in, void *out, int w, int h, int pitch)
+{
+ BYTE *in8 = in;
+ BYTE *out8 = out;
+ DWORD bw = pitch;
+ DWORD pad = bw % 4;
+ int y;
+
+ for(y = 0; y < h; y++)
+ {
+ memcpy(out8, in8, bw);
+ in8 += bw;
+ out8 += bw + pad;
+ }
+
+ return (bw + pad) * h;
+}
+
+static DWORD conv_mask(void *in, DWORD in_bpp, void *out, DWORD *out_bpp, int w, int h, int pitch, BOOL force32bpp)
+{
+ switch(in_bpp)
+ {
+ case 1:
+ if(force32bpp)
+ {
+ *out_bpp = 32;
+ return conv_mask1to32(in, out, w, h, pitch);
+ }
+ *out_bpp = 1;
+ return copy_mask1(in, out, w, h, pitch);
+ case 16:
+ *out_bpp = 32;
+ return conv_mask16to32(in, out, w, h);
+ case 32:
+ {
+ DWORD s = w * h * sizeof(DWORD);
+
+ *out_bpp = 32;
+ memcpy(out, in, s);
+ return s;
+ }
+ }
+
+ return 0;
+}
+
+BOOL SVGA_mouse_load()
+{
+ SVGAFifoCmdDefineCursor *cursor;
+ DWORD cmdoff = 0;
+ DWORD mask_size;
+ void *mb;
+ CURSORSHAPE *cur;
+
+ SVGA_mouse_hide();
+
+ hw_cursor_valid = FALSE;
+
+ mb = mouse_buffer();
+
+ if(!mb) return FALSE;
+ cur = (CURSORSHAPE*)mb;
+
+ if(cur->cx == 0 || cur->cy == 0)
+ {
+ return FALSE;
+ }
+
+ wait_for_cmdbuf();
+
+ cursor = SVGA_cmd_ptr(cmdbuf, &cmdoff, SVGA_CMD_DEFINE_CURSOR, sizeof(SVGAFifoCmdDefineCursor));
+
+ mask_size = conv_mask(cur+1, 1, ((BYTE*)cmdbuf)+cmdoff, &(cursor->andMaskDepth),
+ cur->cx, cur->cy, cur->cbWidth, FALSE);
+ cmdoff += mask_size;
+ mask_size = conv_mask(((BYTE*)(cur+1)) + cur->cbWidth * cur->cy, cur->BitsPixel, ((BYTE*)cmdbuf)+cmdoff, &(cursor->xorMaskDepth),
+ cur->cx, cur->cy, cur->cbWidth, TRUE);
+
+ cmdoff += mask_size;
+
+ cursor->id = 0;
+ cursor->hotspotX = cur->xHotSpot;
+ cursor->hotspotY = cur->yHotSpot;
+ cursor->width = cur->cx;
+ cursor->height = cur->cx;
+
+ submit_cmdbuf(cmdoff, SVGA_CB_SYNC, 0);
+
+ hw_cursor_valid = TRUE;
+ hw_cursor_visible = TRUE;
+ SVGA_mouse_move(mouse_last_x, mouse_last_y);
+
+ return TRUE;
+}
+
+BOOL SVGA_mouse_hw()
+{
+ if(st_used)
+ {
+ if(SVGA_HasFIFOCap(SVGA_FIFO_CAP_CURSOR_BYPASS_3))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+void SVGA_mouse_move(int x, int y)
+{
+ if(hw_cursor_visible)
+ {
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_SCREEN_ID] = 0;
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_ON] = 1;
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_X] = x;
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_Y] = y;
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_COUNT]++;
+ }
+
+ dbg_printf(dbg_hw_mouse_move, x, y, hw_cursor_visible, hw_cursor_valid);
+
+ mouse_last_x = x;
+ mouse_last_y = y;
+}
+
+void SVGA_mouse_show()
+{
+ dbg_printf(dbg_hw_mouse_show, hw_cursor_valid);
+ if(hw_cursor_valid)
+ {
+ hw_cursor_visible = TRUE;
+ SVGA_mouse_move(mouse_last_x, mouse_last_y);
+ }
+}
+
+void SVGA_mouse_hide()
+{
+ dbg_printf(dbg_hw_mouse_hide);
+ if(hw_cursor_valid)
+ {
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_SCREEN_ID] = 0;
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_ON] = 0;
+ /* vbox bug, move cursor outside screen */
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_X] = hda->width;
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_Y] = hda->height;
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_COUNT]++;
+ }
+
+ hw_cursor_visible = FALSE;
+}
diff --git a/vxd_svga_st.c b/vxd_svga_st.c
index 892f3b0..832cd80 100644
--- a/vxd_svga_st.c
+++ b/vxd_svga_st.c
@@ -117,6 +117,7 @@ void st_defineScreen(DWORD w, DWORD h, DWORD bpp)
stid->height = h;
stid->xRoot = 0;
stid->yRoot = 0;
+ stid->dpi = 96;
submit_cmdbuf(cmdoff, SVGA_CB_SYNC, 0);