Skip to content

Commit

Permalink
USB: Simplify evdev/joydev controller mapping
Browse files Browse the repository at this point in the history
Remove "clever autoconfig" that possibly mapped wrong control to wrong player.
Breaks mapping analog stick's single axis to two axes, for now.
  • Loading branch information
jackun committed Mar 20, 2021
1 parent d58ddee commit 218d666
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 304 deletions.
190 changes: 39 additions & 151 deletions pcsx2/USB/usb-pad/evdev/evdev.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,26 +212,12 @@ namespace usb_pad
switch (code)
{
case 0x80 | JOY_STEERING:
case ABS_X:
mWheelData.steering = device.cfg.inverted[0] ? range - NORM(value, range) : NORM(value, range);
break;
//case ABS_Y: mWheelData.clutch = NORM(value, 0xFF); break; //no wheel on PS2 has one, afaik
//case ABS_RX: mWheelData.axis_rx = NORM(event.value, 0xFF); break;
case ABS_RY:
//treat_me_like_ABS_RY:
mWheelData.throttle = 0xFF;
mWheelData.brake = 0xFF;
if (value < 0)
mWheelData.throttle = NORM2(value, 0xFF);
else
mWheelData.brake = NORM2(-value, 0xFF);
break;
case 0x80 | JOY_THROTTLE:
case ABS_Z:
mWheelData.throttle = device.cfg.inverted[1] ? NORM(value, 0xFF) : 0xFF - NORM(value, 0xFF);
break;
case 0x80 | JOY_BRAKE:
case ABS_RZ:
mWheelData.brake = device.cfg.inverted[2] ? NORM(value, 0xFF) : 0xFF - NORM(value, 0xFF);
break;

Expand Down Expand Up @@ -304,7 +290,8 @@ namespace usb_pad
for (int i = 0; i < len; i++)
{
input_event& event = events[i];
int code, value;
int value;
uint16_t button;
switch (event.type)
{
case EV_ABS:
Expand All @@ -320,89 +307,16 @@ namespace usb_pad
break;
case EV_KEY:
{
code = device.btn_map[event.code] != (uint16_t)-1 ? device.btn_map[event.code] : event.code;

if (mType == WT_BUZZ_CONTROLLER || mType == WT_KEYBOARDMANIA_CONTROLLER)
{
if (device.btn_map[event.code] != (uint16_t)-1)
{
if (event.value)
mWheelData.buttons |= 1 << (code & ~0x8000); //on
else
mWheelData.buttons &= ~(1 << (code & ~0x8000)); //off
}

button = device.btn_map[event.code];
if (button == (uint16_t)-1 || !(button & 0x8000))
break;
}

PS2Buttons button = PAD_BUTTON_COUNT;
if (code >= (0x8000 | JOY_CROSS) && // user mapped
code <= (0x8000 | JOY_L3))
{
button = (PS2Buttons)(code & ~0x8000);
}
else
{
#if 0
// Map to xbox360ish controller
switch (code)
{
// Digital hatswitch
case 0x8000 | JOY_LEFT:
mWheelData.hat_horz = (!event.value ? PAD_HAT_COUNT : PAD_HAT_W);
break;
case 0x8000 | JOY_RIGHT:
mWheelData.hat_horz = (!event.value ? PAD_HAT_COUNT : PAD_HAT_E);
break;
case 0x8000 | JOY_UP:
mWheelData.hat_vert = (!event.value ? PAD_HAT_COUNT : PAD_HAT_N);
break;
case 0x8000 | JOY_DOWN:
mWheelData.hat_vert = (!event.value ? PAD_HAT_COUNT : PAD_HAT_S);
break;
case BTN_WEST:
button = PAD_SQUARE;
break;
case BTN_NORTH:
button = PAD_TRIANGLE;
break;
case BTN_EAST:
button = PAD_CIRCLE;
break;
case BTN_SOUTH:
button = PAD_CROSS;
break;
case BTN_SELECT:
button = PAD_SELECT;
break;
case BTN_START:
button = PAD_START;
break;
case BTN_TR:
button = PAD_R1;
break;
case BTN_TL:
button = PAD_L1;
break;
case BTN_TR2:
button = PAD_R2;
break;
case BTN_TL2:
button = PAD_L2;
break;
default:
break;
}
#endif
}
button = button & ~0x8000;

//if (button != PAD_BUTTON_COUNT)
{
if (event.value)
mWheelData.buttons |= 1 << convert_wt_btn(mType, button); //on
else
mWheelData.buttons &= ~(1 << convert_wt_btn(mType, button)); //off
}
if (event.value)
mWheelData.buttons |= 1 << convert_wt_btn(mType, button); //on
else
mWheelData.buttons &= ~(1 << convert_wt_btn(mType, button)); //off
}
break;
case EV_SYN: //TODO useful?
Expand Down Expand Up @@ -472,13 +386,15 @@ namespace usb_pad
{
if (mUseRawFF)
{

if (data[0] == 0x8 || data[0] == 0xB)
return len;
if (data[0] == 0xF8 &&
/* Allow range changes */
!(data[1] == 0x81 || data[1] == 0x02 || data[1] == 0x03))
return len; //don't send extended commands
if (mType <= WT_GT_FORCE)
{
if (data[0] == 0x8 || data[0] == 0xB)
return len;
if (data[0] == 0xF8 &&
/* Allow range changes */
!(data[1] == 0x81 || data[1] == 0x02 || data[1] == 0x03))
return len; //don't send extended commands
}

std::array<uint8_t, 8> report{0};

Expand All @@ -491,9 +407,12 @@ namespace usb_pad
return len;
}

const ff_data* ffdata = (const ff_data*)data;
bool hires = (mType == WT_DRIVING_FORCE_PRO || mType == WT_DRIVING_FORCE_PRO_1102);
ParseFFData(ffdata, hires);
if (mType <= WT_GT_FORCE)
{
const ff_data* ffdata = (const ff_data*)data;
bool hires = (mType == WT_DRIVING_FORCE_PRO || mType == WT_DRIVING_FORCE_PRO_1102);
ParseFFData(ffdata, hires);
}

return len;
}
Expand Down Expand Up @@ -622,7 +541,10 @@ namespace usb_pad
continue;
}

int max_buttons = JOY_STEERING;
// device.cfg.controls[0..max_buttons] - mapped buttons
// device.cfg.controls[max_buttons..etc] - mapped axes
int max_buttons = 0;
int max_axes = 0;
switch (mType)
{
case WT_BUZZ_CONTROLLER:
Expand All @@ -635,6 +557,7 @@ namespace usb_pad
break;
default:
max_buttons = JOY_STEERING;
max_axes = 3;
LoadMappings(mDevType, mPort, it.id, max_buttons, 3, device.cfg);
if (!LoadSetting(mDevType, mPort, APINAME, N_GAIN_ENABLED, b_gain))
b_gain = 1;
Expand Down Expand Up @@ -666,30 +589,19 @@ namespace usb_pad
continue;
}


//device.axis_map[i] = device.axes;

// convert values into 16 bit range
CalcAxisCorr(device.abs_correct[i], absinfo);

//TODO joystick/gamepad is dual analog?
if (i == ABS_RZ)
{
//absinfo.value = AxisCorrect(mAbsCorrect[i], absinfo.value);
if (std::abs(absinfo.value) < 200) /* 200 is random, allows for some dead zone */
device.is_dualanalog = true;
}

// FIXME axes as buttons
for (int k = max_buttons /*JOY_STEERING*/; k < JOY_MAPS_COUNT; k++)
for (int k = 0; k < max_axes; k++)
{
if (i == device.cfg.controls[k])
if (i == device.cfg.controls[k + max_buttons])
{
has_mappings = true;
device.axis_map[i] = 0x80 | k;
device.axis_map[i] = 0x80 | (k + JOY_STEERING);
// TODO Instead of single FF instance, create for every device with X-axis???
// and then switch between them according to which device was used recently
if (k == JOY_STEERING && !mFFdev && !mUseRawFF)
if (k == 0 && !mFFdev && !mUseRawFF)
{
mFFdev = new EvdevFF(device.cfg.fd, b_gain, gain, b_ac, ac);
}
Expand All @@ -698,40 +610,16 @@ namespace usb_pad
}
}

for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i)
for (int k = 0; k < max_buttons; k++)
{
if (test_bit(i, keybit))
auto i = device.cfg.controls[k];
if (i >= 0 && i <= KEY_MAX)
{
device.btn_map[i] = -1; //device.buttons;
if (i == BTN_GAMEPAD)
{
device.is_gamepad = true;
}
for (int k = 0; k < max_buttons; k++)
{
if (i == device.cfg.controls[k])
{
has_mappings = true;
device.btn_map[i] = 0x8000 | k;
}
}
}
}
for (int i = 0; i < BTN_JOYSTICK; ++i)
{
if (test_bit(i, keybit))
{
device.btn_map[i] = -1; //device.buttons;
for (int k = 0; k < max_buttons; k++)
{
if (i == device.cfg.controls[k])
{
has_mappings = true;
device.btn_map[i] = 0x8000 | k;
}
}
has_mappings = true;
device.btn_map[i] = 0x8000 | k;
}
}

if (!has_mappings)
{
close(device.cfg.fd);
Expand Down
3 changes: 0 additions & 3 deletions pcsx2/USB/usb-pad/evdev/shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,6 @@ namespace usb_pad
uint8_t axis_map[ABS_MAX + 1];
uint16_t btn_map[KEY_MAX + 1];
struct axis_correct abs_correct[ABS_MAX];
bool is_gamepad; //xboxish gamepad
bool is_dualanalog; // tricky, have to read the AXIS_RZ somehow and
// determine if its unpressed value is zero
};

int GtkPadConfigure(int port, const char* dev_type, const char* title, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs);
Expand Down
8 changes: 7 additions & 1 deletion pcsx2/USB/usb-pad/joydev/joydev-gtk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,13 @@ namespace usb_pad
return RESULT_CANCELED;

evdev::ApiCallbacks apicbs{GetEventName, EnumerateDevices, PollInput};
int ret = evdev::GtkPadConfigure(port, dev_type, "Joydev Settings", joydev::APINAME, GTK_WINDOW(data), apicbs);
int ret = 0;
if (!strcmp(dev_type, BuzzDevice::TypeName()))
ret = GtkBuzzConfigure(port, dev_type, "Joydev Settings", joydev::APINAME, GTK_WINDOW(data), apicbs);
else if (!strcmp(dev_type, KeyboardmaniaDevice::TypeName()))
ret = GtkKeyboardmaniaConfigure(port, dev_type, "Joydev Settings", joydev::APINAME, GTK_WINDOW(data), apicbs);
else
ret = evdev::GtkPadConfigure(port, dev_type, "Joydev Settings", joydev::APINAME, GTK_WINDOW(data), apicbs);
return ret;
}

Expand Down
Loading

0 comments on commit 218d666

Please sign in to comment.