VIDEO: Avoid losing mouse button state when coalescing motion events

Identified by @shattered in #321

Added better debug output for keyboard events.
This commit is contained in:
Mark Pizzolato 2016-06-11 08:39:25 -07:00
parent b89369e896
commit 3743d3d68a
2 changed files with 37 additions and 11 deletions

View file

@ -58,6 +58,34 @@ char vid_release_key[64] = "Ctrl-Right-Shift";
#include <SDL.h> #include <SDL.h>
#include <SDL_thread.h> #include <SDL_thread.h>
static const char *key_names[] =
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y", "Z",
"BACKQUOTE", "MINUS", "EQUALS", "LEFT_BRACKET", "RIGHT_BRACKET",
"SEMICOLON", "SINGLE_QUOTE", "BACKSLASH", "LEFT_BACKSLASH", "COMMA",
"PERIOD", "SLASH", "PRINT", "SCRL_LOCK", "PAUSE", "ESC", "BACKSPACE",
"TAB", "ENTER", "SPACE", "INSERT", "DELETE", "HOME", "END", "PAGE_UP",
"PAGE_DOWN", "UP", "DOWN", "LEFT", "RIGHT", "CAPS_LOCK", "NUM_LOCK",
"ALT_L", "ALT_R", "CTRL_L", "CTRL_R", "SHIFT_L", "SHIFT_R",
"WIN_L", "WIN_R", "MENU", "KP_ADD", "KP_SUBTRACT", "KP_END", "KP_DOWN",
"KP_PAGE_DOWN", "KP_LEFT", "KP_RIGHT", "KP_HOME", "KP_UP", "KP_PAGE_UP",
"KP_INSERT", "KP_DELETE", "KP_5", "KP_ENTER", "KP_MULTIPLY", "KP_DIVIDE"
};
const char *vid_key_name (int32 key)
{
static char tmp_key_name[40];
if (key < sizeof(key_names)/sizeof(key_names[0]))
sprintf (tmp_key_name, "SIM_KEY_%s", key_names[key]);
else
sprintf (tmp_key_name, "UNKNOWN KEY: %d", key);
return tmp_key_name;
}
#if defined(HAVE_LIBPNG) #if defined(HAVE_LIBPNG)
/* From: https://github.com/driedfruit/SDL_SavePNG */ /* From: https://github.com/driedfruit/SDL_SavePNG */
@ -249,7 +277,7 @@ static int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
#define EVENT_SHOW 6 /* show SDL capabilities */ #define EVENT_SHOW 6 /* show SDL capabilities */
#define EVENT_OPEN 7 /* vid_open request */ #define EVENT_OPEN 7 /* vid_open request */
#define EVENT_EXIT 8 /* program exit */ #define EVENT_EXIT 8 /* program exit */
#define EVENT_SCREENSHOT 9 /* show SDL capabilities */ #define EVENT_SCREENSHOT 9 /* produce screenshot of video window */
#define EVENT_BEEP 10 /* audio beep */ #define EVENT_BEEP 10 /* audio beep */
#define MAX_EVENTS 20 /* max events in queue */ #define MAX_EVENTS 20 /* max events in queue */
@ -1149,31 +1177,28 @@ if (vid_mouse_captured) {
if (!sim_is_running) if (!sim_is_running)
return; return;
if (SDL_SemWait (vid_key_events.sem) == 0) { if (SDL_SemWait (vid_key_events.sem) == 0) {
sim_debug (SIM_VID_DBG_KEY, vid_dev, "Keyboard Event: State: %d, Keysym(scancode,sym): (%d,%d)\n", event->state, event->keysym.scancode, event->keysym.sym);
if (vid_key_events.count < MAX_EVENTS) { if (vid_key_events.count < MAX_EVENTS) {
ev.key = vid_map_key (event->keysym.sym);
sim_debug (SIM_VID_DBG_KEY, vid_dev, "Keyboard Event: State: %s, Keysym(scancode,sym): (%d,%d) - %s\n", (event->state == SDL_PRESSED) ? "PRESSED" : "RELEASED", event->keysym.scancode, event->keysym.sym, vid_key_name(ev.key));
if (event->state == SDL_PRESSED) { if (event->state == SDL_PRESSED) {
#if SDL_MAJOR_VERSION == 1 #if SDL_MAJOR_VERSION == 1
if (!vid_key_state[event->keysym.sym]) { /* Key was not down before */ if (!vid_key_state[event->keysym.sym]) { /* Key was not down before */
vid_key_state[event->keysym.sym] = TRUE; vid_key_state[event->keysym.sym] = TRUE;
#else #else
if (!vid_key_state[event->keysym.scancode]) { /* Key was not down before */ if (!vid_key_state[event->keysym.scancode]) {/* Key was not down before */
vid_key_state[event->keysym.scancode] = TRUE; vid_key_state[event->keysym.scancode] = TRUE;
#endif #endif
ev.key = vid_map_key (event->keysym.sym);
ev.state = SIM_KEYPRESS_DOWN; ev.state = SIM_KEYPRESS_DOWN;
} }
else { else
ev.key = vid_map_key (event->keysym.sym);
ev.state = SIM_KEYPRESS_REPEAT; ev.state = SIM_KEYPRESS_REPEAT;
} }
}
else { else {
#if SDL_MAJOR_VERSION == 1 #if SDL_MAJOR_VERSION == 1
vid_key_state[event->keysym.sym] = FALSE; vid_key_state[event->keysym.sym] = FALSE;
#else #else
vid_key_state[event->keysym.scancode] = FALSE; vid_key_state[event->keysym.scancode] = FALSE;
#endif #endif
ev.key = vid_map_key (event->keysym.sym);
ev.state = SIM_KEYPRESS_UP; ev.state = SIM_KEYPRESS_UP;
} }
vid_key_events.events[vid_key_events.tail++] = ev; vid_key_events.events[vid_key_events.tail++] = ev;
@ -1182,7 +1207,7 @@ if (SDL_SemWait (vid_key_events.sem) == 0) {
vid_key_events.tail = 0; vid_key_events.tail = 0;
} }
else { else {
sim_debug (SIM_VID_DBG_KEY, vid_dev, "Keyboard Event DISCARDED: State: %d, Keysym: Scancode: %d, Keysym: %d\n", event->state, event->keysym.scancode, event->keysym.sym); sim_debug (SIM_VID_DBG_KEY, vid_dev, "Keyboard Event DISCARDED: State: %s, Keysym: Scancode: %d, Keysym: %d\n", (event->state == SDL_PRESSED) ? "PRESSED" : "RELEASED", event->keysym.scancode, event->keysym.sym);
} }
if (SDL_SemPost (vid_key_events.sem)) if (SDL_SemPost (vid_key_events.sem))
sim_printf ("%s: vid_key(): SDL_SemPost error: %s\n", sim_dname(vid_dev), SDL_GetError()); sim_printf ("%s: vid_key(): SDL_SemPost error: %s\n", sim_dname(vid_dev), SDL_GetError());
@ -1214,7 +1239,7 @@ while (SDL_PeepEvents (&dummy_event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSE
event->yrel += dev->yrel; event->yrel += dev->yrel;
event->x = dev->x; event->x = dev->x;
event->y = dev->y; event->y = dev->y;
event->state ^= dev->state; event->state = dev->state;
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: Additional Event Coalesced:pos:(%d,%d) rel:(%d,%d) buttons:(%d,%d,%d)\n", sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: Additional Event Coalesced:pos:(%d,%d) rel:(%d,%d) buttons:(%d,%d,%d)\n",
dev->x, dev->y, dev->xrel, dev->yrel, (dev->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? 1 : 0, (dev->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? 1 : 0, (dev->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? 1 : 0); dev->x, dev->y, dev->xrel, dev->yrel, (dev->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? 1 : 0, (dev->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? 1 : 0, (dev->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? 1 : 0);
}; };

View file

@ -187,6 +187,7 @@ void vid_draw (int32 x, int32 y, int32 w, int32 h, uint32 *buf);
void vid_beep (void); void vid_beep (void);
void vid_refresh (void); void vid_refresh (void);
const char *vid_version (void); const char *vid_version (void);
const char *vid_key_name (int32 key);
t_stat vid_set_cursor (t_bool visible, uint32 width, uint32 height, uint8 *data, uint8 *mask, uint32 hot_x, uint32 hot_y); t_stat vid_set_cursor (t_bool visible, uint32 width, uint32 height, uint8 *data, uint8 *mask, uint32 hot_x, uint32 hot_y);
t_stat vid_set_release_key (FILE* st, UNIT* uptr, int32 val, CONST void* desc); t_stat vid_set_release_key (FILE* st, UNIT* uptr, int32 val, CONST void* desc);
t_stat vid_show_release_key (FILE* st, UNIT* uptr, int32 val, CONST void* desc); t_stat vid_show_release_key (FILE* st, UNIT* uptr, int32 val, CONST void* desc);