diff --git a/input.cpp b/input.cpp index 26a13a3..a626ed3 100644 --- a/input.cpp +++ b/input.cpp @@ -1302,8 +1302,12 @@ static uint32_t autofire[NUMPLAYERS] = {}; static uint32_t autofirecodes[NUMPLAYERS][BTN_NUM] = {}; static int af_delay[NUMPLAYERS] = {}; -static unsigned char mouse_btn = 0; +static unsigned char mouse_btn = 0; //emulated mouse static unsigned char mice_btn = 0; +static int mouse_req = 0; +static int mouse_x = 0; +static int mouse_y = 0; +static int mouse_w = 0; static int mouse_emu = 0; static int kbd_mouse_emu = 0; static int mouse_sniper = 0; @@ -1412,9 +1416,15 @@ static void uinp_check_key() } } -static void mouse_cb(unsigned char b, int16_t x = 0, int16_t y = 0, int16_t w = 0) +static void mouse_cb(int16_t x = 0, int16_t y = 0, int16_t w = 0) { - if (grabbed) user_io_mouse(b, x, y, w); + if (grabbed) + { + mouse_x += x; + mouse_y += y; + mouse_w += w; + mouse_req = 1; + } } static uint32_t osdbtn = 0; @@ -1524,7 +1534,7 @@ static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int mouse_btn = 0; mouse_emu_x = 0; mouse_emu_y = 0; - mouse_cb(mice_btn); + mouse_cb(); mouse_emu ^= 2; if (hasAPI1_5()) Info((mouse_emu & 2) ? "Mouse mode ON" : "Mouse mode OFF"); @@ -1931,7 +1941,13 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int //mouse if (ev->code >= BTN_MOUSE && ev->code < BTN_JOYSTICK) { - //skip it. we use /dev/input/mice + if (ev->value <= 1) + { + int mask = 1 << (ev->code - BTN_MOUSE); + if (input[dev].ds_mouse_emu && mask == 1) mask = 2; + mice_btn = (ev->value) ? (mice_btn | mask) : (mice_btn & ~mask); + mouse_cb(); + } return; } } @@ -2536,7 +2552,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int default: mouse_btn = ev->value ? mouse_btn | 1 << (i - SYS_MS_BTN_L) : mouse_btn & ~(1 << (i - SYS_MS_BTN_L)); - mouse_cb(mouse_btn | mice_btn); + mouse_cb(); break; } return; @@ -2565,7 +2581,6 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int { mouse_emu = ev->value ? mouse_emu | 1 : mouse_emu & ~1; if (input[sub_dev].quirk == QUIRK_DS4) input[dev].ds_mouse_emu = mouse_emu & 1; - printf("mouse_emu = %d\n", mouse_emu); if (mouse_emu & 2) { mouse_sniper = ev->value; @@ -2576,7 +2591,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int mouse_btn = 0; mouse_emu_x = 0; mouse_emu_y = 0; - mouse_cb(mice_btn); + mouse_cb(); } } } @@ -2664,7 +2679,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int default: mouse_btn = ev->value ? mouse_btn | 1 << (i - SYS_MS_BTN_L) : mouse_btn & ~(1 << (i - SYS_MS_BTN_L)); - mouse_cb(mouse_btn | mice_btn); + mouse_cb(); break; } return; @@ -2689,7 +2704,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int mouse_btn = 0; mouse_emu_x = 0; mouse_emu_y = 0; - mouse_cb(mice_btn); + mouse_cb(); } return; } @@ -3081,12 +3096,12 @@ static struct */ }; -static void send_mouse_with_throttle(int dev, int xval, int yval, int btn, int8_t data_3) +static void send_mouse_with_throttle(int dev, int xval, int yval, int8_t wval) { int i = dev; if (input[dev].bind >= 0) dev = input[dev].bind; - if (is_menu() && !video_fb_state()) printf("%s: btn=0x%02X, dx=%d, dy=%d, scroll=%d\n", input[i].devname, btn, xval, yval, data_3); + if (is_menu() && !video_fb_state()) printf("%s: dx=%d, dy=%d, scroll=%d\n", input[i].devname, xval, yval, wval); int throttle = cfg.mouse_throttle ? cfg.mouse_throttle : 1; if (input[dev].ds_mouse_emu) throttle *= 4; @@ -3100,10 +3115,7 @@ static void send_mouse_with_throttle(int dev, int xval, int yval, int btn, int8_ yval = input[i].accy / throttle; input[i].accy -= yval * throttle; - mice_btn = btn & 7; - if (input[dev].ds_mouse_emu) mice_btn = (mice_btn & 4) | ((mice_btn & 1) << 1); - - mouse_cb(mouse_btn | mice_btn, xval, yval, data_3); + mouse_cb(xval, yval, wval); } static uint32_t touch_rel = 0; @@ -3146,14 +3158,14 @@ static void touchscreen_proc(int dev, input_event *ev) } } - mouse_cb(mice_btn); + mouse_cb(); } } else if (ev->type == EV_ABS && ev->code == ABS_MT_SLOT && ev->value == 3 && (input[i].misc_flags & 0x80)) { input[i].misc_flags = 0; mice_btn = 0; - mouse_cb(mice_btn); + mouse_cb(); input[dev].lightgun = !input[dev].lightgun; Info(input[dev].lightgun ? "Light Gun mode is ON" : "Light Gun mode is OFF"); } @@ -3163,7 +3175,7 @@ static void touchscreen_proc(int dev, input_event *ev) if (ev->type == EV_KEY && ev->value == 1) { mice_btn |= 1; - mouse_cb(mice_btn); + mouse_cb(); menu_lightgun_cb(i, EV_KEY, 0x131, 1); } else if (ev->type == EV_ABS) @@ -3193,7 +3205,7 @@ static void touchscreen_proc(int dev, input_event *ev) else if (input[i].misc_flags & 1) mice_btn = 2; else mice_btn = 1; - mouse_cb(mice_btn); + mouse_cb(); } } } @@ -3214,7 +3226,7 @@ static void touchscreen_proc(int dev, input_event *ev) if (input[i].misc_flags & 2) mice_btn = 4; else if (input[i].misc_flags & 1) mice_btn = 2; - mouse_cb(mice_btn); + mouse_cb(); } else if (input[i].misc_flags & 0x40) { @@ -3224,7 +3236,7 @@ static void touchscreen_proc(int dev, input_event *ev) if (dx > 255) dx = 255; if (dx < -256) dx = -256; input[i].lastx = ev->value; - send_mouse_with_throttle(i, dx, 0, mice_btn, 0); + send_mouse_with_throttle(i, dx, 0, 0); } else if (ev->code == ABS_MT_POSITION_Y) { @@ -3232,7 +3244,7 @@ static void touchscreen_proc(int dev, input_event *ev) if (dy > 255) dy = 255; if (dy < -256) dy = -256; input[i].lasty = ev->value; - send_mouse_with_throttle(i, 0, -dy, mice_btn, 0); + send_mouse_with_throttle(i, 0, -dy, 0); } } } @@ -3538,7 +3550,7 @@ int input_test(int getchar) { touch_rel = 0; mice_btn = 0; - mouse_cb(mice_btn); + mouse_cb(); } if (state == 0) @@ -4303,7 +4315,7 @@ int input_test(int getchar) } else { - send_mouse_with_throttle(i, xval, yval, data[0], data[3]); + send_mouse_with_throttle(i, xval, yval, data[3]); } } } @@ -4398,7 +4410,7 @@ int input_poll(int getchar) if (dy < -2) dy = -2; } - mouse_cb(mouse_btn | mice_btn, dx, dy); + mouse_cb(dx, dy); prev_dx = mouse_emu_x; prev_dy = mouse_emu_y; } @@ -4454,6 +4466,15 @@ int input_poll(int getchar) } } + if (mouse_req) + { + user_io_mouse(mouse_btn | mice_btn, mouse_x, mouse_y, mouse_w); + mouse_req = 0; + mouse_x = 0; + mouse_y = 0; + mouse_w = 0; + } + return 0; } @@ -4494,7 +4515,7 @@ void input_notify_mode() mouse_btn = 0; mouse_emu_x = 0; mouse_emu_y = 0; - mouse_cb(mice_btn); + mouse_cb(); } void input_switch(int grab) diff --git a/user_io.cpp b/user_io.cpp index f5ceaf3..1117674 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -63,15 +63,6 @@ static int io_ver = 0; // keep state of caps lock static char caps_lock_toggle = 0; -// mouse position storage for ps2 and minimig rate limitation -#define X 0 -#define Y 1 -#define MOUSE_FREQ 20 // 20 ms -> 50hz -static int16_t mouse_pos[2] = { 0, 0 }; -static int16_t mouse_wheel = 0; -static uint8_t mouse_flags = 0; -static unsigned long mouse_timer; - #define LED_FREQ 100 // 100 ms static unsigned long led_timer; static char keyboard_leds = 0; @@ -2531,83 +2522,6 @@ void user_io_poll() kbd_fifo_poll(); - // frequently check mouse for events - if (CheckTimer(mouse_timer)) - { - mouse_timer = GetTimer(MOUSE_FREQ); - - // has ps2 mouse data been updated in the meantime - if (mouse_flags & 0x80) - { - if (!osd_is_visible) - { - spi_uio_cmd_cont(UIO_MOUSE); - - // ----- X axis ------- - if (mouse_pos[X] < -128) - { - spi8(-128); - mouse_pos[X] += 128; - } - else if (mouse_pos[X] > 127) - { - spi8(127); - mouse_pos[X] -= 127; - } - else - { - spi8(mouse_pos[X]); - mouse_pos[X] = 0; - } - - // ----- Y axis ------- - if (mouse_pos[Y] < -128) - { - spi8(-128); - mouse_pos[Y] += 128; - } - else if (mouse_pos[Y] > 127) - { - spi8(127); - mouse_pos[Y] -= 127; - } - else - { - spi8(mouse_pos[Y]); - mouse_pos[Y] = 0; - } - - // ---- Buttons ------ - spi8(mouse_flags & 0x07); - - // ----- Wheel ------- - if (mouse_wheel < -127) - { - spi8(-127); - } - else if (mouse_wheel > 127) - { - spi8(127); - } - else - { - spi8(mouse_wheel); - } - - mouse_wheel = 0; - DisableIO(); - } - else - { - mouse_pos[X] = 0; - mouse_pos[Y] = 0; - } - - // reset flags - mouse_flags = 0; - } - } - if (!rtc_timer || CheckTimer(rtc_timer)) { // Update once per minute should be enough @@ -2848,87 +2762,6 @@ void user_io_poll() } } - if (core_type == CORE_TYPE_8BIT && !is_minimig() && !is_archie()) - { - // frequently check ps2 mouse for events - if (CheckTimer(mouse_timer)) - { - mouse_timer = GetTimer(MOUSE_FREQ); - - // has ps2 mouse data been updated in the meantime - if (mouse_flags & 0x08) - { - unsigned char ps2_mouse[3]; - - // PS2 format: - // YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn - // dx[7:0] - // dy[7:0] - ps2_mouse[0] = mouse_flags; - - // ------ X axis ----------- - // store sign bit in first byte - ps2_mouse[0] |= (mouse_pos[X] < 0) ? 0x10 : 0x00; - if (mouse_pos[X] < -255) - { - // min possible value + overflow flag - ps2_mouse[0] |= 0x40; - ps2_mouse[1] = 1; // -255 - } - else if (mouse_pos[X] > 255) - { - // max possible value + overflow flag - ps2_mouse[0] |= 0x40; - ps2_mouse[1] = 255; - } - else - { - ps2_mouse[1] = mouse_pos[X]; - } - - // ------ Y axis ----------- - // store sign bit in first byte - ps2_mouse[0] |= (mouse_pos[Y] < 0) ? 0x20 : 0x00; - if (mouse_pos[Y] < -255) - { - // min possible value + overflow flag - ps2_mouse[0] |= 0x80; - ps2_mouse[2] = 1; // -255; - } - else if (mouse_pos[Y] > 255) - { - // max possible value + overflow flag - ps2_mouse[0] |= 0x80; - ps2_mouse[2] = 255; - } - else - { - ps2_mouse[2] = mouse_pos[Y]; - } - - int16_t ps2_wheel = mouse_wheel; - if (ps2_wheel > 63) ps2_wheel = 63; - else if (ps2_wheel < -63) ps2_wheel = -63; - - // collect movement info and send at predefined rate - if (is_menu() && !video_fb_state()) printf("PS2 MOUSE: %x %d %d %d\n", ps2_mouse[0], ps2_mouse[1], ps2_mouse[2], ps2_wheel); - - if (!osd_is_visible) - { - spi_uio_cmd_cont(UIO_MOUSE); - spi_w(ps2_mouse[0] | ((ps2_wheel&127)<<8)); - spi_w(ps2_mouse[1]); - spi_w(ps2_mouse[2]); - DisableIO(); - } - - // reset counters - mouse_flags = 0; - mouse_pos[X] = mouse_pos[Y] = mouse_wheel = 0; - } - } - } - if (is_neogeo() && (!rtc_timer || CheckTimer(rtc_timer))) { // Update once per minute should be enough @@ -3373,15 +3206,19 @@ static void send_keycode(unsigned short key, int press) void user_io_mouse(unsigned char b, int16_t x, int16_t y, int16_t w) { + if (osd_is_visible && !is_menu()) return; + switch (core_type) { case CORE_TYPE_8BIT: if (is_minimig()) { - mouse_pos[X] += x; - mouse_pos[Y] += y; - mouse_wheel += w; - mouse_flags |= 0x80 | (b & 7); + spi_uio_cmd_cont(UIO_MOUSE); + spi8((x < -127) ? -127 : (x > 127) ? 127 : x); + spi8((y < -127) ? -127 : (y > 127) ? 127 : y); + spi8(b & 0x07); + spi8((w < -127) ? -127 : (w > 127) ? 127 : w); + DisableIO(); } else if (is_archie()) { @@ -3389,10 +3226,69 @@ void user_io_mouse(unsigned char b, int16_t x, int16_t y, int16_t w) } else { - mouse_pos[X] += x; - mouse_pos[Y] -= y; // ps2 y axis is reversed over usb - mouse_wheel += w; - mouse_flags |= 0x08 | (b & 7); + unsigned char ps2_mouse[3]; + + // PS2 format: + // YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn + // dx[7:0] + // dy[7:0] + ps2_mouse[0] = (b & 7) | 8; + + // ------ X axis ----------- + // store sign bit in first byte + ps2_mouse[0] |= (x < 0) ? 0x10 : 0x00; + if (x < -255) + { + // min possible value + overflow flag + ps2_mouse[0] |= 0x40; + ps2_mouse[1] = 1; // -255 + } + else if (x > 255) + { + // max possible value + overflow flag + ps2_mouse[0] |= 0x40; + ps2_mouse[1] = 255; + } + else + { + ps2_mouse[1] = (char)x; + } + + // ------ Y axis ----------- + // store sign bit in first byte + y = -y; + ps2_mouse[0] |= (y < 0) ? 0x20 : 0x00; + if (y < -255) + { + // min possible value + overflow flag + ps2_mouse[0] |= 0x80; + ps2_mouse[2] = 1; // -255; + } + else if (y > 255) + { + // max possible value + overflow flag + ps2_mouse[0] |= 0x80; + ps2_mouse[2] = 255; + } + else + { + ps2_mouse[2] = (char)y; + } + + if (w > 63) w = 63; + else if (w < -63) w = -63; + + // collect movement info and send at predefined rate + if (is_menu() && !video_fb_state()) printf("PS2 MOUSE: %x %d %d %d\n", ps2_mouse[0], ps2_mouse[1], ps2_mouse[2], w); + + if (!osd_is_visible) + { + spi_uio_cmd_cont(UIO_MOUSE); + spi_w(ps2_mouse[0] | (w << 8)); + spi_w(ps2_mouse[1] | ((((uint16_t)b) << 5) & 0xF00)); + spi_w(ps2_mouse[2] | ((((uint16_t)b) << 1) & 0x100)); + DisableIO(); + } } return; }