From: just nine Date: Sat, 27 Feb 2021 02:45:00 +0000 (+0000) Subject: mouse wheel support X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=0214217d38754a8216ca66d872ad99afeb74e86b;p=pistorm mouse wheel support --- diff --git a/emulator.c b/emulator.c index e5912ce..24be0c2 100644 --- a/emulator.c +++ b/emulator.c @@ -43,8 +43,9 @@ int kb_hook_enabled = 0; int mouse_hook_enabled = 0; int cpu_emulation_running = 1; -char mouse_dx = 0, mouse_dy = 0; -char mouse_buttons = 0; +uint8_t mouse_dx = 0, mouse_dy = 0; +uint8_t mouse_buttons = 0; +uint8_t mouse_extra = 0; extern uint8_t gayle_int; extern uint8_t gayle_ide_enabled; @@ -229,10 +230,26 @@ int main(int argc, char *argv[]) { } if (cfg->mouse_enabled) { - mouse_fd = open(cfg->mouse_file, O_RDONLY | O_NONBLOCK); + mouse_fd = open(cfg->mouse_file, O_RDWR | O_NONBLOCK); if (mouse_fd == -1) { printf("Failed to open %s, can't enable mouse hook.\n", cfg->mouse_file); cfg->mouse_enabled = 0; + } else { + /** + * *-*-*-* magic numbers! *-*-*-* + * great, so waaaay back in the history of the pc, the ps/2 protocol set the standard for mice + * and in the process, the mouse sample rate was defined as a way of putting mice into vendor-specific modes. + * as the ancient gpm command explains, almost everything except incredibly old mice talk the IntelliMouse + * protocol, which reports four bytes. by default, every mouse starts in 3-byte mode (don't report wheel or + * additional buttons) until imps2 magic is sent. so, command $f3 is "set sample rate", followed by a byte. + */ + uint8_t mouse_init[] = { 0xf4, 0xf3, 0x64 }; // enable, then set sample rate 100 + uint8_t imps2_init[] = { 0xf3, 0xc8, 0xf3, 0x64, 0xf3, 0x50 }; // magic sequence; set sample 200, 100, 80 + if (write(mouse_fd, mouse_init, sizeof(mouse_init)) != -1) { + if (write(mouse_fd, imps2_init, sizeof(imps2_init)) == -1) + printf("[MOUSE] Couldn't enable scroll wheel events; is this mouse from the 1980s?\n"); + } else + printf("[MOUSE] Mouse didn't respond to normal PS/2 init; have you plugged a brick in by mistake?\n"); } } @@ -300,7 +317,7 @@ int main(int argc, char *argv[]) { m68k_pulse_reset(); while (42) { if (mouse_hook_enabled) { - get_mouse_status(&mouse_dx, &mouse_dy, &mouse_buttons); + get_mouse_status(&mouse_dx, &mouse_dy, &mouse_buttons, &mouse_extra); } if (realtime_disassembly && (do_disasm || cpu_emulation_running)) { @@ -383,7 +400,7 @@ int main(int argc, char *argv[]) { if (c && c == cfg->mouse_toggle_key) { mouse_hook_enabled ^= 1; printf("Mouse hook %s.\n", mouse_hook_enabled ? "enabled" : "disabled"); - mouse_dx = mouse_dy = mouse_buttons = 0; + mouse_dx = mouse_dy = mouse_buttons = mouse_extra = 0; } if (c == 'r') { cpu_emulation_running ^= 1; @@ -424,6 +441,23 @@ int main(int argc, char *argv[]) { } } } + + if (mouse_hook_enabled && (mouse_extra != 0x00)) { + // mouse wheel events have occurred; unlike l/m/r buttons, these are queued as keypresses, so add to end of buffer + switch (mouse_extra) { + case 0xff: + // wheel up + queue_keypress(0xfe, KEYPRESS_PRESS, PLATFORM_AMIGA); + break; + case 0x01: + // wheel down + queue_keypress(0xff, KEYPRESS_PRESS, PLATFORM_AMIGA); + break; + } + + // dampen the scroll wheel until next while loop iteration + mouse_extra = 0x00; + } } stop_cpu_emulation:; @@ -522,10 +556,11 @@ unsigned int m68k_read_memory_8(unsigned int address) { //mouse_buttons -= 1; return (unsigned int)(result ^ 0x40); } - else - return (unsigned int)result; + + return (unsigned int)result; } } + if (kb_hook_enabled) { if (address == CIAAICR) { if (get_num_kb_queued() && (!send_keypress || send_keypress == 1)) { diff --git a/input/input.c b/input/input.c index e4d995d..cee65e7 100644 --- a/input/input.c +++ b/input/input.c @@ -13,6 +13,7 @@ static int lshift = 0, rshift = 0, lctrl = 0, rctrl = 0, lalt = 0, altgr = 0; extern int mouse_fd; extern int keyboard_fd; +// n.b. $fe and $ff are mapped to newmouse standard wheel up/down keycodes, nonexistant on amiga keyboards char keymap_amiga[256] = { \ /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ \ /*00*/ 0x80, 0x45, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x41, 0x42, \ @@ -30,7 +31,7 @@ char keymap_amiga[256] = { \ /*C0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \ /*D0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \ /*E0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \ -/*F0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE }; \ +/*F0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 0x7A, 0x7B }; \ int handle_modifier(struct input_event *ev) { int *target_modifier = NULL; @@ -136,16 +137,18 @@ int get_key_char(char *c, char *code, char *event_type) return 0; } -uint16_t mouse_x = 0, mouse_y = 0, mouse_b = 0; +uint8_t mouse_x = 0, mouse_y = 0; -int get_mouse_status(char *x, char *y, char *b) { - struct input_event ie; - if (read(mouse_fd, &ie, sizeof(struct input_event)) != -1) { - *b = ((char *)&ie)[0]; - mouse_x += ((char *)&ie)[1]; +int get_mouse_status(uint8_t *x, uint8_t *y, uint8_t *b, uint8_t *e) { + uint8_t mouse_ev[4]; + if (read(mouse_fd, &mouse_ev, 4) != -1) { + *b = ((uint8_t *)&mouse_ev)[0]; + *e = ((uint8_t *)&mouse_ev)[3]; + + mouse_x += ((uint8_t *)&mouse_ev)[1]; *x = mouse_x; - mouse_y += (-((char *)&ie)[2]); - *y = mouse_y; //-((char *)&ie)[2]; + mouse_y += (-((uint8_t *)&mouse_ev)[2]); + *y = mouse_y; return 1; } @@ -177,7 +180,7 @@ int queue_keypress(uint8_t keycode, uint8_t event_type, uint8_t platform) { if (keymap != NULL) { if (keymap[keycode] != NONE) { if (queued_keypresses < 255) { - //printf("Keypress queued, matched %.2X to host key code %.2X\n", keycode, keymap[keycode]); + // printf("Keypress queued, matched %.2X to host key code %.2X\n", keycode, keymap[keycode]); queued_keys[queue_output_pos] = keymap[keycode]; queued_events[queue_output_pos] = event_type; queue_output_pos++; diff --git a/input/input.h b/input/input.h index d4810ec..a785534 100644 --- a/input/input.h +++ b/input/input.h @@ -1,10 +1,12 @@ +#include + enum keypress_type { KEYPRESS_RELEASE, KEYPRESS_PRESS, KEYPRESS_REPEAT, }; -int get_mouse_status(char *x, char *y, char *b); +int get_mouse_status(uint8_t *x, uint8_t *y, uint8_t *b, uint8_t *e); int get_key_char(char *c, char *code, char *event_type); int queue_keypress(uint8_t keycode, uint8_t event_type, uint8_t platform); int get_num_kb_queued();