diff --git a/pcsx2/USB/usb-pad/evdev/evdev.cpp b/pcsx2/USB/usb-pad/evdev/evdev.cpp index 8e455a71da466..f9a40b3d73174 100644 --- a/pcsx2/USB/usb-pad/evdev/evdev.cpp +++ b/pcsx2/USB/usb-pad/evdev/evdev.cpp @@ -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; @@ -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: @@ -320,93 +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 (code >= BTN_TRIGGER && code < BTN_BASE5) // try to guess - { - button = (PS2Buttons)((code - BTN_TRIGGER) & ~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? @@ -476,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 report{0}; @@ -495,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; } @@ -626,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: @@ -639,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; @@ -670,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); } @@ -702,40 +610,16 @@ namespace usb_pad } } - for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i) - { - if (test_bit(i, keybit)) - { - 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) + 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; - 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); diff --git a/pcsx2/USB/usb-pad/evdev/shared.h b/pcsx2/USB/usb-pad/evdev/shared.h index 8ec2ea62d9dc5..993b80b8f53e5 100644 --- a/pcsx2/USB/usb-pad/evdev/shared.h +++ b/pcsx2/USB/usb-pad/evdev/shared.h @@ -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); diff --git a/pcsx2/USB/usb-pad/joydev/joydev-gtk.cpp b/pcsx2/USB/usb-pad/joydev/joydev-gtk.cpp index f4606a508fec6..e917dc3980726 100644 --- a/pcsx2/USB/usb-pad/joydev/joydev-gtk.cpp +++ b/pcsx2/USB/usb-pad/joydev/joydev-gtk.cpp @@ -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; } diff --git a/pcsx2/USB/usb-pad/joydev/joydev.cpp b/pcsx2/USB/usb-pad/joydev/joydev.cpp index 3cfee589ab9eb..5da52db04e951 100644 --- a/pcsx2/USB/usb-pad/joydev/joydev.cpp +++ b/pcsx2/USB/usb-pad/joydev/joydev.cpp @@ -123,37 +123,13 @@ namespace usb_pad switch (device.axis_map[event.number]) { case 0x80 | JOY_STEERING: - case ABS_X: mWheelData.steering = device.cfg.inverted[0] ? range - NORM(event.value, range) : NORM(event.value, range); break; - case ABS_Y: - mWheelData.clutch = NORM(event.value, 0xFF); - break; - //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 (event.value < 0) - mWheelData.throttle = NORM2(event.value, 0xFF); - else - mWheelData.brake = NORM2(-event.value, 0xFF); - break; case 0x80 | JOY_THROTTLE: - case ABS_Z: - if (device.is_gamepad) - mWheelData.brake = 0xFF - NORM(event.value, 0xFF); - else - mWheelData.throttle = device.cfg.inverted[1] ? NORM(event.value, 0xFF) : 0xFF - NORM(event.value, 0xFF); + mWheelData.throttle = device.cfg.inverted[1] ? NORM(event.value, 0xFF) : 0xFF - NORM(event.value, 0xFF); break; case 0x80 | JOY_BRAKE: - case ABS_RZ: - if (device.is_gamepad) - mWheelData.throttle = 0xFF - NORM(event.value, 0xFF); - else if (device.is_dualanalog) - goto treat_me_like_ABS_RY; - else - mWheelData.brake = device.cfg.inverted[2] ? NORM(event.value, 0xFF) : 0xFF - NORM(event.value, 0xFF); + mWheelData.brake = device.cfg.inverted[2] ? NORM(event.value, 0xFF) : 0xFF - NORM(event.value, 0xFF); break; //FIXME hatswitch mapping maybe @@ -185,78 +161,16 @@ namespace usb_pad } else if ((event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON) { - PS2Buttons button = PAD_BUTTON_COUNT; - if (device.btn_map[event.number] >= (0x8000 | JOY_CROSS) && - device.btn_map[event.number] <= (0x8000 | JOY_L3)) - { - button = (PS2Buttons)(device.btn_map[event.number] & ~0x8000); - } + uint16_t button = device.btn_map[event.number]; + if (button == (uint16_t)-1 || !(button & 0x8000)) + break; - else if (device.btn_map[event.number] >= BTN_TRIGGER && - device.btn_map[event.number] < BTN_BASE5) - { - button = (PS2Buttons)(device.btn_map[event.number] - BTN_TRIGGER); - } - else - { - // Map to xbox360ish controller - switch (device.btn_map[event.number]) - { - // Digital hatswitch - case 0x8000 | JOY_LEFT: - mWheelData.hat_horz = PAD_HAT_W; - break; - case 0x8000 | JOY_RIGHT: - mWheelData.hat_horz = PAD_HAT_E; - break; - case 0x8000 | JOY_UP: - mWheelData.hat_vert = PAD_HAT_N; - break; - case 0x8000 | JOY_DOWN: - mWheelData.hat_vert = 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_THUMBR: - button = PAD_R2; - break; - case BTN_THUMBL: - button = PAD_L2; - break; - default: - break; - } - } + 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 } } @@ -342,15 +256,6 @@ namespace usb_pad EnumerateDevices(device_list); - if (!LoadSetting(mDevType, mPort, APINAME, N_GAIN_ENABLED, b_gain)) - b_gain = 1; - if (!LoadSetting(mDevType, mPort, APINAME, N_GAIN, gain)) - gain = 100; - if (!LoadSetting(mDevType, mPort, APINAME, N_AUTOCENTER_MANAGED, b_ac)) - b_ac = 1; - if (!LoadSetting(mDevType, mPort, APINAME, N_AUTOCENTER, ac)) - ac = 100; - for (const auto& it : device_list) { has_steering = false; @@ -380,61 +285,61 @@ namespace usb_pad continue; } - LoadMappings(mDevType, mPort, device.name, 3, 16, device.cfg); + memset(device.axis_map, 0xFF, sizeof(device.axis_map)); + memset(device.btn_map, 0xFF, sizeof(device.btn_map)); - // Axis Mapping - if (ioctl(device.cfg.fd, JSIOCGAXMAP, device.axis_map) < 0) + // 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) { - SysMessage("%s: Axis mapping failed: %s\n", APINAME, strerror(errno)); - continue; + case WT_BUZZ_CONTROLLER: + LoadBuzzMappings(mDevType, mPort, it.id, device.cfg); + max_buttons = 20; + break; + case WT_KEYBOARDMANIA_CONTROLLER: + max_buttons = 31; + LoadMappings(mDevType, mPort, it.id, max_buttons, 0, device.cfg); + 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; + if (!LoadSetting(mDevType, mPort, APINAME, N_GAIN, gain)) + gain = 100; + if (!LoadSetting(mDevType, mPort, APINAME, N_AUTOCENTER_MANAGED, b_ac)) + b_ac = 1; + if (!LoadSetting(mDevType, mPort, APINAME, N_AUTOCENTER, ac)) + ac = 100; + break; } - else + + // Axis Mapping + if (ioctl(device.cfg.fd, JSIOCGAXES, &(count)) >= 0 && count) { - if (ioctl(device.cfg.fd, JSIOCGAXES, &(count)) >= 0) + for (int i = 0; i < max_axes; i++) { - for (int i = 0; i < count; ++i) + int k = device.cfg.controls[i + max_buttons]; + if (k > -1) { - for (int k = 0; k < count; k++) - { - for (int i = JOY_STEERING; i < JOY_MAPS_COUNT; i++) - { - if (k == device.cfg.controls[i]) - { - device.axis_map[k] = 0x80 | i; - if (i == JOY_STEERING) - has_steering = true; - } - } - } + device.axis_map[k] = 0x80 | (i + JOY_STEERING); + if (k == 0) + has_steering = true; } } } // Button Mapping - if (ioctl(device.cfg.fd, JSIOCGBTNMAP, device.btn_map) < 0) + if (ioctl(device.cfg.fd, JSIOCGBUTTONS, &(count)) >= 0 && count) { - SysMessage("%s: Button mapping failed: %s\n", APINAME, strerror(errno)); - continue; - } - else - { - if (ioctl(device.cfg.fd, JSIOCGBUTTONS, &(count)) >= 0) + for (int i = 0; i < max_buttons; i++) { - for (int i = 0; i < count; ++i) - { - if (device.btn_map[i] == BTN_GAMEPAD) - device.is_gamepad = true; - } - - if (!device.is_gamepad) //TODO Don't remap if gamepad? - for (int k = 0; k < count; k++) - { - for (int i = 0; i < JOY_STEERING; i++) - { - if (k == device.cfg.controls[i]) - device.btn_map[k] = 0x8000 | i; - } - } + const auto k = device.cfg.controls[i]; + if (k > -1) + device.btn_map[k] = 0x8000 | i; } } @@ -467,6 +372,7 @@ namespace usb_pad { if ((mHandleFF = open(event.str().c_str(), /*O_WRONLY*/ O_RDWR)) < 0) { + Console.Warning("USB: failed to open '%s'", event.str().c_str()); } else mFFdev = new evdev::EvdevFF(mHandleFF, b_gain, gain, b_ac, ac); diff --git a/pcsx2/USB/usb-pad/usb-pad-ff.cpp b/pcsx2/USB/usb-pad/usb-pad-ff.cpp index b5e31e93db539..89924cbace399 100644 --- a/pcsx2/USB/usb-pad/usb-pad-ff.cpp +++ b/pcsx2/USB/usb-pad/usb-pad-ff.cpp @@ -102,7 +102,7 @@ namespace usb_pad static int warned = 0; int caps = 0; - DevCon.WriteLn("FFB %02X, %02X, %02X, %02X : %02X, %02X, %02X, %02X\n", + DevCon.WriteLn("FFB %02X, %02X, %02X, %02X : %02X, %02X, %02X, %02X", ffdata->cmdslot, ffdata->type, ffdata->u.params[0], ffdata->u.params[1], ffdata->u.params[2], ffdata->u.params[3], ffdata->u.params[4], ffdata->padd0); diff --git a/pcsx2/USB/usb-pad/usb-pad.cpp b/pcsx2/USB/usb-pad/usb-pad.cpp index 4c18957ad3312..cf7b9fbee7e2d 100644 --- a/pcsx2/USB/usb-pad/usb-pad.cpp +++ b/pcsx2/USB/usb-pad/usb-pad.cpp @@ -94,7 +94,7 @@ namespace usb_pad std::list KeyboardmaniaDevice::ListAPIs() { - return {"evdev"}; + return PadDevice::ListAPIs(); } const TCHAR* KeyboardmaniaDevice::LongAPIName(const std::string& name)