QVSS/VIDEO: Fix for mouse tracking on Ultrix from Mike Burke for issue #88

This commit is contained in:
Mark Pizzolato 2013-11-08 17:15:02 -08:00
parent 30cd103a14
commit b57201b88b
3 changed files with 93 additions and 47 deletions

View file

@ -25,6 +25,7 @@
vc Qbus video subsystem vc Qbus video subsystem
08-Nov-2013 MB Implemented mouse position register
06-Nov-2013 MB Increased the speed of v-sync interrupts, which 06-Nov-2013 MB Increased the speed of v-sync interrupts, which
was too slow for some O/S drivers. was too slow for some O/S drivers.
11-Jun-2013 MB First version 11-Jun-2013 MB First version
@ -169,11 +170,12 @@ BITFIELD vc_ic_mode_bits[] = {
#define IRQ_MBC 6 /* Mouse button C */ #define IRQ_MBC 6 /* Mouse button C */
#define IRQ_SPARE 7 /* (spare) */ #define IRQ_SPARE 7 /* (spare) */
#define VC_XSIZE 1024 #define VC_XSIZE 1024 /* screen size */
#define VC_YSIZE 864 #define VC_YSIZE 864
#define VC_MEMSIZE (1u << 16) /* video memory size */ #define VC_MEMSIZE (1u << 16) /* video memory size */
#define VC_MOVE_MAX 49 /* mouse movement max (per update) */
#define VCMAP_VLD 0x80000000 /* valid */ #define VCMAP_VLD 0x80000000 /* valid */
#define VCMAP_LN 0x00000FFF /* buffer line */ #define VCMAP_LN 0x00000FFF /* buffer line */
@ -735,6 +737,7 @@ t_stat vc_svc (UNIT *uptr)
t_bool updated = FALSE; /* flag for refresh */ t_bool updated = FALSE; /* flag for refresh */
uint32 line[1024]; uint32 line[1024];
uint32 ln, col, off; uint32 ln, col, off;
int32 xpos, ypos, dx, dy;
uint8 *cur; uint8 *cur;
vc_crtc_p = vc_crtc_p ^ CRTCP_VB; /* Toggle VBI */ vc_crtc_p = vc_crtc_p ^ CRTCP_VB; /* Toggle VBI */
@ -759,6 +762,32 @@ vc_cur_y = CUR_Y;
vc_cur_v = CUR_V; vc_cur_v = CUR_V;
vc_cur_f = CUR_F; vc_cur_f = CUR_F;
xpos = vc_mpos & 0xFF; /* get current mouse position */
ypos = (vc_mpos >> 8) & 0xFF;
dx = vid_mouse_xrel; /* get relative movement */
dy = vid_mouse_yrel;
if (dx > VC_MOVE_MAX) /* limit movement */
dx = VC_MOVE_MAX;
else if (dx < -VC_MOVE_MAX)
dx = -VC_MOVE_MAX;
if (dy > VC_MOVE_MAX)
dy = VC_MOVE_MAX;
else if (dy < -VC_MOVE_MAX)
dy = -VC_MOVE_MAX;
xpos += dx; /* add to counters */
ypos += dy;
vc_mpos = ((ypos & 0xFF) << 8) | (xpos & 0xFF); /* update register */
vid_mouse_xrel = 0; /* reset counters for next poll */
vid_mouse_yrel = 0;
vc_csr |= (CSR_MSA | CSR_MSB | CSR_MSC); /* reset button states */
if (vid_mouse_b3) /* set new button states */
vc_csr &= ~CSR_MSA;
if (vid_mouse_b2)
vc_csr &= ~CSR_MSB;
if (vid_mouse_b1)
vc_csr &= ~CSR_MSC;
for (ln = 0; ln < VC_YSIZE; ln++) { for (ln = 0; ln < VC_YSIZE; ln++) {
if ((vc_map[ln] & VCMAP_VLD) == 0) { /* line invalid? */ if ((vc_map[ln] & VCMAP_VLD) == 0) { /* line invalid? */
off = vc_map[ln] * 32; /* get video buf offet */ off = vc_map[ln] * 32; /* get video buf offet */

View file

@ -23,12 +23,18 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author. in this Software without prior written authorization from the author.
08-Nov-2013 MB Added globals for current mouse status
11-Jun-2013 MB First version 11-Jun-2013 MB First version
*/ */
#include "sim_video.h" #include "sim_video.h"
t_bool vid_active = FALSE; t_bool vid_active = FALSE;
int32 vid_mouse_xrel = 0;
int32 vid_mouse_yrel = 0;
t_bool vid_mouse_b1 = FALSE;
t_bool vid_mouse_b2 = FALSE;
t_bool vid_mouse_b3 = FALSE;
#if HAVE_LIBSDL #if HAVE_LIBSDL
#include <SDL.h> #include <SDL.h>
@ -54,9 +60,6 @@ typedef struct {
int32 head; int32 head;
int32 tail; int32 tail;
int32 count; int32 count;
t_bool b1_state;
t_bool b2_state;
t_bool b3_state;
} MOUSE_EVENT_QUEUE; } MOUSE_EVENT_QUEUE;
int vid_thread (void* arg); int vid_thread (void* arg);
@ -93,6 +96,8 @@ if (!vid_active) {
vid_width = width; vid_width = width;
vid_height = height; vid_height = height;
vid_mouse_captured = FALSE; vid_mouse_captured = FALSE;
vid_mouse_xrel = 0;
vid_mouse_yrel = 0;
vid_key_events.head = 0; vid_key_events.head = 0;
vid_key_events.tail = 0; vid_key_events.tail = 0;
@ -605,17 +610,19 @@ if ((event->x == 0) ||
} }
if (!sim_is_running) if (!sim_is_running)
return; return;
vid_mouse_xrel += event->xrel; /* update cumulative x rel */
vid_mouse_yrel -= event->yrel; /* update cumulative y rel */
vid_mouse_b1 = (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? TRUE : FALSE;
vid_mouse_b2 = (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? TRUE : FALSE;
vid_mouse_b3 = (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? TRUE : FALSE;
if (SDL_SemWait (vid_mouse_events.sem) == 0) { if (SDL_SemWait (vid_mouse_events.sem) == 0) {
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: (%d,%d)\n", event->xrel, event->yrel); sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: (%d,%d)\n", event->xrel, event->yrel);
if (vid_mouse_events.count < MAX_EVENTS) { if (vid_mouse_events.count < MAX_EVENTS) {
ev.x_rel = event->xrel; ev.x_rel = event->xrel;
ev.y_rel = (-event->yrel); ev.y_rel = (-event->yrel);
ev.b1_state = (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? TRUE : FALSE; ev.b1_state = vid_mouse_b1;
ev.b2_state = (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? TRUE : FALSE; ev.b2_state = vid_mouse_b2;
ev.b3_state = (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? TRUE : FALSE; ev.b3_state = vid_mouse_b3;
vid_mouse_events.b1_state = ev.b1_state;
vid_mouse_events.b2_state = ev.b2_state;
vid_mouse_events.b3_state = ev.b3_state;
vid_mouse_events.events[vid_mouse_events.tail++] = ev; vid_mouse_events.events[vid_mouse_events.tail++] = ev;
vid_mouse_events.count++; vid_mouse_events.count++;
if (vid_mouse_events.tail == MAX_EVENTS) if (vid_mouse_events.tail == MAX_EVENTS)
@ -650,26 +657,26 @@ if (!vid_mouse_captured) {
} }
if (!sim_is_running) if (!sim_is_running)
return; return;
state = (event->state == SDL_PRESSED) ? TRUE : FALSE;
switch (event->button) {
case SDL_BUTTON_LEFT:
vid_mouse_b1 = state;
break;
case SDL_BUTTON_MIDDLE:
vid_mouse_b2 = state;
break;
case SDL_BUTTON_RIGHT:
vid_mouse_b3 = state;
break;
}
if (SDL_SemWait (vid_mouse_events.sem) == 0) { if (SDL_SemWait (vid_mouse_events.sem) == 0) {
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Button Event: State: %d, Button: %d, (%d,%d)\n", event->state, event->button, event->x, event->y); sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Button Event: State: %d, Button: %d, (%d,%d)\n", event->state, event->button, event->x, event->y);
if (vid_mouse_events.count < MAX_EVENTS) { if (vid_mouse_events.count < MAX_EVENTS) {
state = (event->state == SDL_PRESSED) ? TRUE : FALSE;
ev.x_rel = 0; ev.x_rel = 0;
ev.y_rel = 0; ev.y_rel = 0;
switch (event->button) { ev.b1_state = vid_mouse_b1;
case SDL_BUTTON_LEFT: ev.b2_state = vid_mouse_b2;
vid_mouse_events.b1_state = state; ev.b3_state = vid_mouse_b3;
break;
case SDL_BUTTON_MIDDLE:
vid_mouse_events.b2_state = state;
break;
case SDL_BUTTON_RIGHT:
vid_mouse_events.b3_state = state;
break;
}
ev.b1_state = vid_mouse_events.b1_state;
ev.b2_state = vid_mouse_events.b2_state;
ev.b3_state = vid_mouse_events.b3_state;
vid_mouse_events.events[vid_mouse_events.tail++] = ev; vid_mouse_events.events[vid_mouse_events.tail++] = ev;
vid_mouse_events.count++; vid_mouse_events.count++;
if (vid_mouse_events.tail == MAX_EVENTS) if (vid_mouse_events.tail == MAX_EVENTS)
@ -811,6 +818,8 @@ if (!vid_active) {
vid_width = width; vid_width = width;
vid_height = height; vid_height = height;
vid_mouse_captured = FALSE; vid_mouse_captured = FALSE;
vid_mouse_xrel = 0;
vid_mouse_yrel = 0;
vid_key_events.head = 0; vid_key_events.head = 0;
vid_key_events.tail = 0; vid_key_events.tail = 0;
@ -1318,17 +1327,19 @@ if ((event->x == 0) ||
} }
if (!sim_is_running) if (!sim_is_running)
return; return;
vid_mouse_xrel += event->xrel; /* update cumulative x rel */
vid_mouse_yrel -= event->yrel; /* update cumulative y rel */
vid_mouse_b1 = (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? TRUE : FALSE;
vid_mouse_b2 = (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? TRUE : FALSE;
vid_mouse_b3 = (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? TRUE : FALSE;
if (SDL_SemWait (vid_mouse_events.sem) == 0) { if (SDL_SemWait (vid_mouse_events.sem) == 0) {
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: (%d,%d)\n", event->xrel, event->yrel); sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: (%d,%d)\n", event->xrel, event->yrel);
if (vid_mouse_events.count < MAX_EVENTS) { if (vid_mouse_events.count < MAX_EVENTS) {
ev.x_rel = event->xrel; ev.x_rel = event->xrel;
ev.y_rel = (-event->yrel); ev.y_rel = (-event->yrel);
ev.b1_state = (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? TRUE : FALSE; ev.b1_state = vid_mouse_b1;
ev.b2_state = (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? TRUE : FALSE; ev.b2_state = vid_mouse_b2;
ev.b3_state = (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? TRUE : FALSE; ev.b3_state = vid_mouse_b3;
vid_mouse_events.b1_state = ev.b1_state;
vid_mouse_events.b2_state = ev.b2_state;
vid_mouse_events.b3_state = ev.b3_state;
vid_mouse_events.events[vid_mouse_events.tail++] = ev; vid_mouse_events.events[vid_mouse_events.tail++] = ev;
vid_mouse_events.count++; vid_mouse_events.count++;
if (vid_mouse_events.tail == MAX_EVENTS) if (vid_mouse_events.tail == MAX_EVENTS)
@ -1362,26 +1373,26 @@ if (!vid_mouse_captured) {
} }
if (!sim_is_running) if (!sim_is_running)
return; return;
state = (event->state == SDL_PRESSED) ? TRUE : FALSE;
switch (event->button) {
case SDL_BUTTON_LEFT:
vid_mouse_b1 = state;
break;
case SDL_BUTTON_MIDDLE:
vid_mouse_b2 = state;
break;
case SDL_BUTTON_RIGHT:
vid_mouse_b3 = state;
break;
}
if (SDL_SemWait (vid_mouse_events.sem) == 0) { if (SDL_SemWait (vid_mouse_events.sem) == 0) {
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Button Event: State: %d, Button: %d, (%d,%d)\n", event->state, event->button, event->x, event->y); sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Button Event: State: %d, Button: %d, (%d,%d)\n", event->state, event->button, event->x, event->y);
if (vid_mouse_events.count < MAX_EVENTS) { if (vid_mouse_events.count < MAX_EVENTS) {
state = (event->state == SDL_PRESSED) ? TRUE : FALSE;
ev.x_rel = 0; ev.x_rel = 0;
ev.y_rel = 0; ev.y_rel = 0;
switch (event->button) { ev.b1_state = vid_mouse_b1;
case SDL_BUTTON_LEFT: ev.b2_state = vid_mouse_b2;
vid_mouse_events.b1_state = state; ev.b3_state = vid_mouse_b3;
break;
case SDL_BUTTON_MIDDLE:
vid_mouse_events.b2_state = state;
break;
case SDL_BUTTON_RIGHT:
vid_mouse_events.b3_state = state;
break;
}
ev.b1_state = vid_mouse_events.b1_state;
ev.b2_state = vid_mouse_events.b2_state;
ev.b3_state = vid_mouse_events.b3_state;
vid_mouse_events.events[vid_mouse_events.tail++] = ev; vid_mouse_events.events[vid_mouse_events.tail++] = ev;
vid_mouse_events.count++; vid_mouse_events.count++;
if (vid_mouse_events.tail == MAX_EVENTS) if (vid_mouse_events.tail == MAX_EVENTS)

View file

@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author. in this Software without prior written authorization from the author.
08-Nov-2013 MB Added globals for current mouse status
11-Jun-2013 MB First version 11-Jun-2013 MB First version
*/ */
@ -180,6 +181,11 @@ t_stat vid_show_release_key (FILE* st, UNIT* uptr, int32 val, void* desc);
extern t_bool vid_active; extern t_bool vid_active;
extern uint32 vid_mono_palette[2]; extern uint32 vid_mono_palette[2];
extern int32 vid_mouse_xrel; /* mouse cumulative x rel */
extern int32 vid_mouse_yrel; /* mouse cumulative y rel */
extern t_bool vid_mouse_b1; /* mouse button 1 state */
extern t_bool vid_mouse_b2; /* mouse button 2 state */
extern t_bool vid_mouse_b3; /* mouse button 3 state */
#define SIM_VID_DBG_MOUSE 0x01000000 #define SIM_VID_DBG_MOUSE 0x01000000
#define SIM_VID_DBG_KEY 0x02000000 #define SIM_VID_DBG_KEY 0x02000000