input: support up to 8 mouse buttons, don't defer mouse events.
This commit is contained in:
75
input.cpp
75
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)
|
||||
|
||||
246
user_io.cpp
246
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user