input: initial support for wheels.

This commit is contained in:
Sorgelig
2022-04-21 04:22:39 +08:00
parent d7d88ac40a
commit 5a6ecd790b
4 changed files with 186 additions and 30 deletions

204
input.cpp
View File

@@ -1119,7 +1119,8 @@ enum QUIRK
QUIRK_VCS,
QUIRK_JOYCON,
QUIRK_LIGHTGUN_CRT,
QUIRK_LIGHTGUN
QUIRK_LIGHTGUN,
QUIRK_WHEEL,
};
typedef struct
@@ -1172,6 +1173,12 @@ typedef struct
uint16_t last_rumble;
ff_effect rumble_effect;
int8_t wh_steer;
int8_t wh_accel;
int8_t wh_break;
int8_t wh_clutch;
int8_t wh_combo;
int timeout;
char mac[64];
@@ -2280,25 +2287,39 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
}
if (!input[dev].mmap[SYS_BTN_OSD_KTGL + 2]) input[dev].mmap[SYS_BTN_OSD_KTGL + 2] = input[dev].mmap[SYS_BTN_OSD_KTGL + 1];
if (input[dev].mmap[SYS_AXIS_X] == input[dev].mmap[SYS_AXIS1_X])
if (input[dev].quirk == QUIRK_WHEEL)
{
input[dev].stick_l[0] = SYS_AXIS1_X;
if((input[dev].mmap[SYS_AXIS2_X] >> 16) == 2) input[dev].stick_r[0] = SYS_AXIS2_X;
input[dev].mmap[SYS_AXIS_MX] = -1;
input[dev].mmap[SYS_AXIS_MY] = -1;
input[dev].mmap[SYS_AXIS_X] = -1;
input[dev].mmap[SYS_AXIS_Y] = -1;
input[dev].mmap[SYS_AXIS1_X] = -1;
input[dev].mmap[SYS_AXIS1_Y] = -1;
input[dev].mmap[SYS_AXIS2_X] = -1;
input[dev].mmap[SYS_AXIS2_Y] = -1;
}
if (input[dev].mmap[SYS_AXIS_Y] == input[dev].mmap[SYS_AXIS1_Y])
else
{
input[dev].stick_l[1] = SYS_AXIS1_Y;
if ((input[dev].mmap[SYS_AXIS2_Y] >> 16) == 2) input[dev].stick_r[1] = SYS_AXIS2_Y;
}
if (input[dev].mmap[SYS_AXIS_X] == input[dev].mmap[SYS_AXIS2_X])
{
input[dev].stick_l[0] = SYS_AXIS2_X;
if ((input[dev].mmap[SYS_AXIS1_X] >> 16) == 2) input[dev].stick_r[0] = SYS_AXIS1_X;
}
if (input[dev].mmap[SYS_AXIS_Y] == input[dev].mmap[SYS_AXIS2_Y])
{
input[dev].stick_l[1] = SYS_AXIS2_Y;
if ((input[dev].mmap[SYS_AXIS1_Y] >> 16) == 2) input[dev].stick_r[1] = SYS_AXIS1_Y;
if (input[dev].mmap[SYS_AXIS_X] == input[dev].mmap[SYS_AXIS1_X])
{
input[dev].stick_l[0] = SYS_AXIS1_X;
if ((input[dev].mmap[SYS_AXIS2_X] >> 16) == 2) input[dev].stick_r[0] = SYS_AXIS2_X;
}
if (input[dev].mmap[SYS_AXIS_Y] == input[dev].mmap[SYS_AXIS1_Y])
{
input[dev].stick_l[1] = SYS_AXIS1_Y;
if ((input[dev].mmap[SYS_AXIS2_Y] >> 16) == 2) input[dev].stick_r[1] = SYS_AXIS2_Y;
}
if (input[dev].mmap[SYS_AXIS_X] == input[dev].mmap[SYS_AXIS2_X])
{
input[dev].stick_l[0] = SYS_AXIS2_X;
if ((input[dev].mmap[SYS_AXIS1_X] >> 16) == 2) input[dev].stick_r[0] = SYS_AXIS1_X;
}
if (input[dev].mmap[SYS_AXIS_Y] == input[dev].mmap[SYS_AXIS2_Y])
{
input[dev].stick_l[1] = SYS_AXIS2_Y;
if ((input[dev].mmap[SYS_AXIS1_Y] >> 16) == 2) input[dev].stick_r[1] = SYS_AXIS1_Y;
}
}
}
input[dev].has_mmap++;
@@ -2827,18 +2848,21 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
}
}
if (input[dev].mmap[SYS_AXIS_X])
if (input[dev].quirk != QUIRK_WHEEL)
{
uint16_t key = KEY_EMU + ((uint16_t)input[dev].mmap[SYS_AXIS_X]*2);
if (ev->code == (key + 1)) joy_digital(0, 1 << 0, 0, ev->value, 0);
if (ev->code == key) joy_digital(0, 1 << 1, 0, ev->value, 1);
}
if (input[dev].mmap[SYS_AXIS_X])
{
uint16_t key = KEY_EMU + ((uint16_t)input[dev].mmap[SYS_AXIS_X] * 2);
if (ev->code == (key + 1)) joy_digital(0, 1 << 0, 0, ev->value, 0);
if (ev->code == key) joy_digital(0, 1 << 1, 0, ev->value, 1);
}
if (input[dev].mmap[SYS_AXIS_Y])
{
uint16_t key = KEY_EMU + ((uint16_t)input[dev].mmap[SYS_AXIS_Y]*2);
if (ev->code == (key + 1)) joy_digital(0, 1 << 2, 0, ev->value, 2);
if (ev->code == key) joy_digital(0, 1 << 3, 0, ev->value, 3);
if (input[dev].mmap[SYS_AXIS_Y])
{
uint16_t key = KEY_EMU + ((uint16_t)input[dev].mmap[SYS_AXIS_Y] * 2);
if (ev->code == (key + 1)) joy_digital(0, 1 << 2, 0, ev->value, 2);
if (ev->code == key) joy_digital(0, 1 << 3, 0, ev->value, 3);
}
}
}
}
@@ -3065,7 +3089,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
// normalize to -range/2...+range/2
value = value - (absinfo->minimum + absinfo->maximum) / 2;
if (ev->code > 1 || !input[dev].lightgun) //lightgun has no dead zone
if (ev->code > 1 || (!input[dev].lightgun && input[dev].quirk != QUIRK_WHEEL)) //lightgun/wheel has no dead zone
{
// check the dead-zone and remove it from the range
hrange -= dead;
@@ -3103,7 +3127,38 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
// skip if joystick is undefined.
if (!input[dev].num) break;
if (ev->code == 0 && input[dev].lightgun)
if (input[dev].quirk == QUIRK_WHEEL)
{
int wh_value = ((127 * (ev->value - absinfo->minimum)) / (absinfo->maximum - absinfo->minimum)) - 127;
if (ev->code == input[dev].wh_steer)
{
joy_analog(input[dev].num, 0, value, 0);
}
else if (ev->code == input[dev].wh_accel)
{
joy_analog(input[dev].num, 1, wh_value, 0);
}
else if (ev->code == input[dev].wh_break)
{
joy_analog(input[dev].num, 1, wh_value, 1);
}
else if (ev->code == input[dev].wh_clutch)
{
joy_analog(input[dev].num, 0, wh_value, 1);
}
else if (ev->code == input[dev].wh_combo)
{
if (value < -1) joy_analog(input[dev].num, 1, value, 0);
else if (value > 1) joy_analog(input[dev].num, 1, -value, 1);
else
{
joy_analog(input[dev].num, 1, 0, 0);
joy_analog(input[dev].num, 1, 0, 0);
}
}
}
else if (ev->code == 0 && input[dev].lightgun)
{
joy_analog(input[dev].num, 0, value);
}
@@ -3948,6 +4003,75 @@ static void set_rumble(int dev, uint16_t rumble_val)
}
}
static void setup_wheels()
{
static char path[1024];
if (cfg.wheel_force > 100) cfg.wheel_force = 100;
for (int i = 0; i < NUMDEV; i++)
{
if (pool[i].fd != -1 && input[i].quirk == QUIRK_WHEEL)
{
input[i].wh_steer = -1;
input[i].wh_accel = -1;
input[i].wh_break = -1;
input[i].wh_clutch = -1;
input[i].wh_combo = -1;
if (input[i].vid == 0x046d) // logitech
{
struct input_event ie;
ie.type = EV_FF;
ie.code = FF_AUTOCENTER;
ie.value = 0xFFFFUL * cfg.wheel_force / 100;
write(pool[i].fd, &ie, sizeof(ie));
if (cfg.wheel_range && input[i].sysfs[0])
{
sprintf(path, "/sys%s", input[i].sysfs);
char *p = strstr(path, "/input/");
if (p)
{
strcpy(p, "/range");
FILE* f = fopen(path, "w");
if (f)
{
fprintf(f, "%d", cfg.wheel_range);
fclose(f);
}
}
}
input[i].wh_steer = 0;
switch (input[i].pid)
{
case 0xc299: // LOGITECH_G25_WHEEL
case 0xc29b: // LOGITECH_G27_WHEEL
case 0xc24f: // LOGITECH_G29_WHEEL
input[i].wh_accel = 2;
input[i].wh_break = 5;
input[i].wh_clutch = 1;
break;
case 0xc294: // LOGITECH_WHEEL
input[i].wh_combo = 1;
break;
case 0xc298: // LOGITECH_DFP_WHEEL
input[i].wh_accel = 1;
input[i].wh_break = 5;
break;
case 0xc29a: // LOGITECH_DFGT_WHEEL
input[i].wh_accel = 1;
input[i].wh_break = 2;
break;
}
}
}
}
}
int input_test(int getchar)
{
static char cur_leds = 0;
@@ -4059,6 +4183,25 @@ int input_test(int getchar)
}
}
// Logitech Wheels
if (input[n].vid == 0x046d)
{
switch (input[n].pid)
{
case 0xc24f: // LOGITECH_G29_WHEEL
//case 0xc262: // LOGITECH_G920_WHEEL
case 0xc294: // LOGITECH_WHEEL
//case 0xc295: // LOGITECH_MOMO_WHEEL
case 0xc298: // LOGITECH_DFP_WHEEL
case 0xc299: // LOGITECH_G25_WHEEL
case 0xc29a: // LOGITECH_DFGT_WHEEL
case 0xc29b: // LOGITECH_G27_WHEEL
{
input[n].quirk = QUIRK_WHEEL;
}
}
}
// enable scroll wheel reading
if (input[n].mouse)
{
@@ -4170,7 +4313,7 @@ int input_test(int getchar)
{
input[n].lightgun = 1;
}
//Namco Guncon via RetroZord adapter
if (input[n].vid == 0x2341 && input[n].pid == 0x8036 && (strstr(uniq, "RZordPsGun") || strstr(input[n].name, "RZordPsGun")))
{
@@ -4276,6 +4419,7 @@ int input_test(int getchar)
mergedevs();
check_joycon();
setup_wheels();
for (int i = 0; i < n; i++)
{
printf("opened %d(%2d): %s (%04x:%04x) %d \"%s\" \"%s\"\n", i, input[i].bind, input[i].devname, input[i].vid, input[i].pid, input[i].quirk, input[i].id, input[i].name);