From 7f7c11edb2e1723d5b23cf85a25435603e8d99a4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 16 Dec 2016 21:36:46 +0000 Subject: [PATCH] Added Microsoft Intellimouse emulation --- src/amstrad.c | 2 +- src/keyboard_olim24.c | 2 +- src/mouse.c | 5 +-- src/mouse.h | 6 ++-- src/mouse_ps2.c | 84 +++++++++++++++++++++++++++++++++---------- src/mouse_ps2.h | 1 + src/mouse_serial.c | 2 +- src/pc.c | 8 ++--- src/plat-mouse.h | 2 +- src/win-mouse.cc | 12 ++++--- src/win.c | 4 ++- 11 files changed, 92 insertions(+), 36 deletions(-) diff --git a/src/amstrad.c b/src/amstrad.c index bd70f05..0c208ab 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -58,7 +58,7 @@ typedef struct mouse_amstrad_t int oldb; } mouse_amstrad_t; -static void mouse_amstrad_poll(int x, int y, int b, void *p) +static void mouse_amstrad_poll(int x, int y, int z, int b, void *p) { mouse_amstrad_t *mouse = (mouse_amstrad_t *)p; diff --git a/src/keyboard_olim24.c b/src/keyboard_olim24.c index 22ac4d6..3548ad4 100644 --- a/src/keyboard_olim24.c +++ b/src/keyboard_olim24.c @@ -221,7 +221,7 @@ typedef struct mouse_olim24_t int x, y, b; } mouse_olim24_t; -void mouse_olim24_poll(int x, int y, int b, void *p) +void mouse_olim24_poll(int x, int y, int z, int b, void *p) { mouse_olim24_t *mouse = (mouse_olim24_t *)p; diff --git a/src/mouse.c b/src/mouse.c index 75c08ca..3ac9b84 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -9,6 +9,7 @@ static mouse_t *mouse_list[] = { &mouse_serial_microsoft, &mouse_ps2_2_button, + &mouse_intellimouse, &mouse_amstrad, &mouse_olim24, NULL @@ -31,10 +32,10 @@ void mouse_emu_close() cur_mouse = NULL; } -void mouse_poll(int x, int y, int b) +void mouse_poll(int x, int y, int z, int b) { if (cur_mouse) - cur_mouse->poll(x, y, b, mouse_p); + cur_mouse->poll(x, y, z, b, mouse_p); } char *mouse_get_name(int mouse) diff --git a/src/mouse.h b/src/mouse.h index 6975369..53a09eb 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -1,6 +1,6 @@ void mouse_emu_init(); void mouse_emu_close(); -void mouse_poll(int x, int y, int b); +void mouse_poll(int x, int y, int z, int b); char *mouse_get_name(int mouse); int mouse_get_type(int mouse); @@ -10,12 +10,14 @@ int mouse_get_type(int mouse); #define MOUSE_TYPE_AMSTRAD 2 #define MOUSE_TYPE_OLIM24 3 +#define MOUSE_TYPE_3BUTTON (1 << 31) + typedef struct { char name[80]; void *(*init)(); void (*close)(void *p); - uint8_t (*poll)(int x, int y, int b, void *p); + uint8_t (*poll)(int x, int y, int z, int b, void *p); int type; } mouse_t; diff --git a/src/mouse_ps2.c b/src/mouse_ps2.c index 91cd0dc..0783a01 100644 --- a/src/mouse_ps2.c +++ b/src/mouse_ps2.c @@ -28,7 +28,12 @@ typedef struct mouse_ps2_t int cd; - int x, y, b; + int x, y, z, b; + + int is_intellimouse; + int intellimouse_mode; + + uint8_t last_data[6]; } mouse_ps2_t; void mouse_ps2_write(uint8_t val, void *p) @@ -92,7 +97,10 @@ void mouse_ps2_write(uint8_t val, void *p) case 0xf2: /*Read ID*/ keyboard_at_adddata_mouse(0xfa); - keyboard_at_adddata_mouse(0x00); + if (mouse->intellimouse_mode) + keyboard_at_adddata_mouse(0x03); + else + keyboard_at_adddata_mouse(0x00); break; case 0xf3: /*Set sample rate*/ @@ -113,6 +121,7 @@ void mouse_ps2_write(uint8_t val, void *p) case 0xff: /*Reset*/ mouse->mode = MOUSE_STREAM; mouse->flags = 0; + mouse->intellimouse_mode = 0; keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse(0xaa); keyboard_at_adddata_mouse(0x00); @@ -122,52 +131,74 @@ void mouse_ps2_write(uint8_t val, void *p) // fatal("mouse_ps2 : Bad command %02X\n", val, mouse->command); } } + + if (mouse->is_intellimouse) + { + int c; + + for (c = 0; c < 5; c++) + mouse->last_data[c] = mouse->last_data[c+1]; + + mouse->last_data[5] = val; + + if (mouse->last_data[0] == 0xf3 && mouse->last_data[1] == 0xc8 && + mouse->last_data[2] == 0xf3 && mouse->last_data[3] == 0x64 && + mouse->last_data[4] == 0xf3 && mouse->last_data[5] == 0x50) + mouse->intellimouse_mode = 1; + } } -void mouse_ps2_poll(int x, int y, int b, void *p) +void mouse_ps2_poll(int x, int y, int z, int b, void *p) { mouse_ps2_t *mouse = (mouse_ps2_t *)p; uint8_t packet[3] = {0x08, 0, 0}; - if (!x && !y && b == mouse->b) + if (!x && !y && !z && b == mouse->b) return; if (!mouse_scan) return; mouse->x += x; - mouse->y -= y; + mouse->y -= y; + mouse->z -= z; if (mouse->mode == MOUSE_STREAM && (mouse->flags & MOUSE_ENABLE) && ((mouse_queue_end - mouse_queue_start) & 0xf) < 13) { mouse->b = b; // pclog("Send packet : %i %i\n", ps2_x, ps2_y); if (mouse->x > 255) - mouse->x = 255; + mouse->x = 255; if (mouse->x < -256) - mouse->x = -256; + mouse->x = -256; if (mouse->y > 255) - mouse->y = 255; + mouse->y = 255; if (mouse->y < -256) - mouse->y = -256; + mouse->y = -256; + if (mouse->z < -8) + mouse->z = -8; + if (mouse->z > 7) + mouse->z = 7; if (mouse->x < 0) - packet[0] |= 0x10; + packet[0] |= 0x10; if (mouse->y < 0) - packet[0] |= 0x20; + packet[0] |= 0x20; if (mouse_buttons & 1) - packet[0] |= 1; + packet[0] |= 1; if (mouse_buttons & 2) - packet[0] |= 2; - if (mouse_buttons & 4) - packet[0] |= 4; + packet[0] |= 2; + if ((mouse_buttons & 4) && (mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) + packet[0] |= 4; packet[1] = mouse->x & 0xff; packet[2] = mouse->y & 0xff; - - mouse->x = mouse->y = 0; - + keyboard_at_adddata_mouse(packet[0]); keyboard_at_adddata_mouse(packet[1]); keyboard_at_adddata_mouse(packet[2]); + if (mouse->intellimouse_mode) + keyboard_at_adddata_mouse(mouse->z); + + mouse->x = mouse->y = mouse->z = 0; } } @@ -187,6 +218,15 @@ void *mouse_ps2_init() return mouse; } +void *mouse_intellimouse_init() +{ + mouse_ps2_t *mouse = mouse_ps2_init(); + + mouse->is_intellimouse = 1; + + return mouse; +} + void mouse_ps2_close(void *p) { mouse_ps2_t *mouse = (mouse_ps2_t *)p; @@ -202,3 +242,11 @@ mouse_t mouse_ps2_2_button = mouse_ps2_poll, MOUSE_TYPE_PS2 }; +mouse_t mouse_intellimouse = +{ + "Microsoft Intellimouse (PS/2)", + mouse_intellimouse_init, + mouse_ps2_close, + mouse_ps2_poll, + MOUSE_TYPE_PS2 | MOUSE_TYPE_3BUTTON +}; diff --git a/src/mouse_ps2.h b/src/mouse_ps2.h index b74e1eb..49821e3 100644 --- a/src/mouse_ps2.h +++ b/src/mouse_ps2.h @@ -1 +1,2 @@ extern mouse_t mouse_ps2_2_button; +extern mouse_t mouse_intellimouse; diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 2189d4e..f1dfea1 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -11,7 +11,7 @@ typedef struct mouse_serial_t SERIAL *serial; } mouse_serial_t; -void mouse_serial_poll(int x, int y, int b, void *p) +void mouse_serial_poll(int x, int y, int z, int b, void *p) { mouse_serial_t *mouse = (mouse_serial_t *)p; SERIAL *serial = mouse->serial; diff --git a/src/pc.c b/src/pc.c index 5a894b7..9a097de 100644 --- a/src/pc.c +++ b/src/pc.c @@ -106,15 +106,15 @@ uint8_t cgastat; int pollmouse_delay = 2; void pollmouse() { - int x,y; + int x, y, z; // return; pollmouse_delay--; if (pollmouse_delay) return; pollmouse_delay = 2; mouse_poll_host(); - mouse_get_mickeys(&x,&y); + mouse_get_mickeys(&x, &y, &z); if (mouse_poll) - mouse_poll(x, y, mouse_buttons); + mouse_poll(x, y, z, mouse_buttons); // if (mousecapture) position_mouse(64,64); } @@ -500,7 +500,7 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "PCem v11 - %i%% - %s - %s - %s", fps, model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : "Press CTRL-END or middle button to release mouse"); + sprintf(s, "PCem v11 - %i%% - %s - %s - %s", fps, model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? "Press CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); set_window_title(s); } done++; diff --git a/src/plat-mouse.h b/src/plat-mouse.h index 1e8f0e2..b0afe82 100644 --- a/src/plat-mouse.h +++ b/src/plat-mouse.h @@ -6,7 +6,7 @@ extern "C" { void mouse_close(); extern int mouse_buttons; void mouse_poll_host(); - void mouse_get_mickeys(int *x, int *y); + void mouse_get_mickeys(int *x, int *y, int *z); extern int mousecapture; #ifdef __cplusplus } diff --git a/src/win-mouse.cc b/src/win-mouse.cc index 5ec5a6f..7593b64 100644 --- a/src/win-mouse.cc +++ b/src/win-mouse.cc @@ -11,12 +11,12 @@ extern "C" void pclog(const char *format, ...); extern "C" void mouse_init(); extern "C" void mouse_close(); extern "C" void mouse_poll_host(); -extern "C" void mouse_get_mickeys(int *x, int *y); +extern "C" void mouse_get_mickeys(int *x, int *y, int *z); static LPDIRECTINPUT lpdi; static LPDIRECTINPUTDEVICE lpdi_mouse = NULL; static DIMOUSESTATE mousestate; -static int mouse_x = 0, mouse_y = 0; +static int mouse_x = 0, mouse_y = 0, mouse_z = 0; int mouse_buttons = 0; void mouse_init() @@ -58,13 +58,15 @@ void mouse_poll_host() mouse_buttons |= 4; mouse_x += mousestate.lX; mouse_y += mousestate.lY; + mouse_z += mousestate.lZ/120; if (!mousecapture && !video_fullscreen) - mouse_x = mouse_y = mouse_buttons = 0; + mouse_x = mouse_y = mouse_z = mouse_buttons = 0; } -void mouse_get_mickeys(int *x, int *y) +void mouse_get_mickeys(int *x, int *y, int *z) { *x = mouse_x; *y = mouse_y; - mouse_x = mouse_y = 0; + *z = mouse_z; + mouse_x = mouse_y = mouse_z = 0; } diff --git a/src/win.c b/src/win.c index c0ac641..b85a80a 100644 --- a/src/win.c +++ b/src/win.c @@ -22,6 +22,7 @@ #include "cpu.h" #include "ide.h" #include "model.h" +#include "mouse.h" #include "nvr.h" #include "sound.h" #include "thread.h" @@ -1261,7 +1262,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; case WM_MBUTTONUP: - releasemouse(); + if (!(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) + releasemouse(); break; case WM_ENTERMENULOOP: