From 0b59b930a331532e7ee3fc19ba42caf010aca1c4 Mon Sep 17 00:00:00 2001 From: Florin9doi Date: Mon, 22 Jul 2024 00:47:46 +0300 Subject: [PATCH] USB: Move Buzz device to dedicated files and create custom UI --- pcsx2-qt/Settings/ControllerBindingWidget.cpp | 6 + pcsx2-qt/Settings/USBBindingWidget_Buzz.ui | 918 ++++++++++++++++++ pcsx2-qt/pcsx2-qt.vcxproj | 3 + pcsx2-qt/pcsx2-qt.vcxproj.filters | 3 + pcsx2/CMakeLists.txt | 2 + pcsx2/USB/deviceproxy.cpp | 1 + pcsx2/USB/usb-pad/usb-buzz.cpp | 327 +++++++ pcsx2/USB/usb-pad/usb-buzz.h | 94 ++ pcsx2/USB/usb-pad/usb-pad.cpp | 97 -- pcsx2/USB/usb-pad/usb-pad.h | 111 --- pcsx2/pcsx2.vcxproj | 2 + pcsx2/pcsx2.vcxproj.filters | 6 + 12 files changed, 1362 insertions(+), 208 deletions(-) create mode 100644 pcsx2-qt/Settings/USBBindingWidget_Buzz.ui create mode 100644 pcsx2/USB/usb-pad/usb-buzz.cpp create mode 100644 pcsx2/USB/usb-pad/usb-buzz.h diff --git a/pcsx2-qt/Settings/ControllerBindingWidget.cpp b/pcsx2-qt/Settings/ControllerBindingWidget.cpp index 1c13e11015..a1be4020f0 100644 --- a/pcsx2-qt/Settings/ControllerBindingWidget.cpp +++ b/pcsx2-qt/Settings/ControllerBindingWidget.cpp @@ -23,6 +23,7 @@ #include "QtUtils.h" #include "SettingWidgetBinder.h" +#include "ui_USBBindingWidget_Buzz.h" #include "ui_USBBindingWidget_DrivingForce.h" #include "ui_USBBindingWidget_Gametrak.h" #include "ui_USBBindingWidget_GTForce.h" @@ -1333,6 +1334,11 @@ USBBindingWidget* USBBindingWidget::createInstance( has_template = true; } } + else if (type == "BuzzDevice") + { + Ui::USBBindingWidget_Buzz().setupUi(widget); + has_template = true; + } else if (type == "Gametrak") { Ui::USBBindingWidget_Gametrak().setupUi(widget); diff --git a/pcsx2-qt/Settings/USBBindingWidget_Buzz.ui b/pcsx2-qt/Settings/USBBindingWidget_Buzz.ui new file mode 100644 index 0000000000..e8e53dbecc --- /dev/null +++ b/pcsx2-qt/Settings/USBBindingWidget_Buzz.ui @@ -0,0 +1,918 @@ + + + USBBindingWidget_Buzz + + + + 0 + 0 + 1100 + 500 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + + + + + + Player 1 + + + + + + Red + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Blue + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Orange + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Green + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Yellow + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + + + + + + + + Player 2 + + + + + + Red + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Blue + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Orange + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Green + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Yellow + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + + + + + + + + Player 3 + + + + + + Red + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Blue + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Orange + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Green + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Yellow + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + + + + + + + + Player 4 + + + + + + Red + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Blue + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Orange + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Green + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + Yellow + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + PushButton + + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + + + + + + InputBindingWidget + QPushButton +
Settings/InputBindingWidget.h
+
+
+ + + + +
diff --git a/pcsx2-qt/pcsx2-qt.vcxproj b/pcsx2-qt/pcsx2-qt.vcxproj index e8e3d4006c..0eeebb84b0 100644 --- a/pcsx2-qt/pcsx2-qt.vcxproj +++ b/pcsx2-qt/pcsx2-qt.vcxproj @@ -416,6 +416,9 @@ Document + + Document + Document diff --git a/pcsx2-qt/pcsx2-qt.vcxproj.filters b/pcsx2-qt/pcsx2-qt.vcxproj.filters index 36eeae6e02..bd33d2fcce 100644 --- a/pcsx2-qt/pcsx2-qt.vcxproj.filters +++ b/pcsx2-qt/pcsx2-qt.vcxproj.filters @@ -657,6 +657,9 @@ Settings + + Settings + Settings diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index 552efda4fc..6177f31ed9 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -383,6 +383,7 @@ set(pcsx2USBSources USB/usb-mic/usb-mic-singstar.cpp USB/usb-msd/usb-msd.cpp USB/usb-pad/lg/lg_ff.cpp + USB/usb-pad/usb-buzz.cpp USB/usb-pad/usb-gametrak.cpp USB/usb-pad/usb-realplay.cpp USB/usb-pad/usb-pad-ff.cpp @@ -420,6 +421,7 @@ set(pcsx2USBHeaders USB/usb-mic/usb-mic-singstar.h USB/usb-msd/usb-msd.h USB/usb-pad/lg/lg_ff.h + USB/usb-pad/usb-buzz.h USB/usb-pad/usb-gametrak.h USB/usb-pad/usb-realplay.h USB/usb-pad/usb-pad-sdl-ff.h diff --git a/pcsx2/USB/deviceproxy.cpp b/pcsx2/USB/deviceproxy.cpp index 78b26a5a3f..91890d5b89 100644 --- a/pcsx2/USB/deviceproxy.cpp +++ b/pcsx2/USB/deviceproxy.cpp @@ -3,6 +3,7 @@ #include "deviceproxy.h" #include "usb-eyetoy/usb-eyetoy-webcam.h" +#include "usb-pad/usb-buzz.h" #include "usb-pad/usb-gametrak.h" #include "usb-pad/usb-realplay.h" #include "usb-hid/usb-hid.h" diff --git a/pcsx2/USB/usb-pad/usb-buzz.cpp b/pcsx2/USB/usb-pad/usb-buzz.cpp new file mode 100644 index 0000000000..0b33da8c48 --- /dev/null +++ b/pcsx2/USB/usb-pad/usb-buzz.cpp @@ -0,0 +1,327 @@ +// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team +// SPDX-License-Identifier: LGPL-3.0+ + +#include "Host.h" +#include "Input/InputManager.h" +#include "StateWrapper.h" +#include "USB/USB.h" +#include "USB/deviceproxy.h" +#include "USB/qemu-usb/USBinternal.h" +#include "USB/qemu-usb/desc.h" +#include "USB/usb-pad/usb-buzz.h" +#include "USB/usb-pad/usb-pad.h" +#include + +namespace usb_pad +{ + static const USBDescStrings desc_strings = { + "", + "Logitech Buzz(tm) Controller V1", + "", + "Logitech"}; + + static uint8_t dev_descriptor[] = { + 0x12, // bLength + 0x01, // bDescriptorType (Device) + 0x00, 0x02, // bcdUSB 2.00 + 0x00, // bDeviceClass (Use class information in the Interface Descriptors) + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + 0x08, // bMaxPacketSize0 8 + 0x4C, 0x05, // idVendor 0x054C + 0x02, 0x00, // idProduct 0x0002 + 0xA1, 0x05, // bcdDevice 11.01 + 0x03, // iManufacturer (String Index) + 0x01, // iProduct (String Index) + 0x00, // iSerialNumber (String Index) + 0x01, // bNumConfigurations 1 + }; + + static const uint8_t config_descriptor[] = { + 0x09, // bLength + 0x02, // bDescriptorType (Configuration) + 0x22, 0x00, // wTotalLength 34 + 0x01, // bNumInterfaces 1 + 0x01, // bConfigurationValue + 0x00, // iConfiguration (String Index) + 0x80, // bmAttributes + 0x32, // bMaxPower 100mA + + 0x09, // bLength + 0x04, // bDescriptorType (Interface) + 0x00, // bInterfaceNumber 0 + 0x00, // bAlternateSetting + 0x01, // bNumEndpoints 1 + 0x03, // bInterfaceClass + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0x00, // iInterface (String Index) + + 0x09, // bLength + 0x21, // bDescriptorType (HID) + 0x11, 0x01, // bcdHID 1.11 + 0x33, // bCountryCode + 0x01, // bNumDescriptors + 0x22, // bDescriptorType[0] (HID) + 0x4E, 0x00, // wDescriptorLength[0] 78 + + 0x07, // bLength + 0x05, // bDescriptorType (Endpoint) + 0x81, // bEndpointAddress (IN/D2H) + 0x03, // bmAttributes (Interrupt) + 0x08, 0x00, // wMaxPacketSize 8 + 0x0A, // bInterval 10 (unit depends on device speed) + }; + + static const uint8_t hid_report_descriptor[] = { + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x04, // Usage (Joystick) + 0xA1, 0x01, // Collection (Application) + 0xA1, 0x02, // Collection (Logical) + 0x75, 0x08, // Report Size (8) + 0x95, 0x02, // Report Count (2) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x35, 0x00, // Physical Minimum (0) + 0x46, 0xFF, 0x00, // Physical Maximum (255) + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x75, 0x01, // Report Size (1) + 0x95, 0x14, // Report Count (20) + 0x25, 0x01, // Logical Maximum (1) + 0x45, 0x01, // Physical Maximum (1) + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (0x01) + 0x29, 0x14, // Usage Maximum (0x14) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) + 0x75, 0x01, // Report Size (1) + 0x95, 0x04, // Report Count (4) + 0x25, 0x01, // Logical Maximum (1) + 0x45, 0x01, // Physical Maximum (1) + 0x09, 0x01, // Usage (0x01) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, // End Collection + 0xA1, 0x02, // Collection (Logical) + 0x75, 0x08, // Report Size (8) + 0x95, 0x07, // Report Count (7) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x46, 0xFF, 0x00, // Physical Maximum (255) + 0x09, 0x02, // Usage (0x02) + 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) + 0xC0, // End Collection + 0xC0, // End Collection + }; + + BuzzState::BuzzState(u32 port_) + : port(port_) + { + } + + BuzzState::~BuzzState() = default; + + static void buzz_handle_control(USBDevice* dev, USBPacket* p, + int request, int value, int index, int length, uint8_t* data) + { + int ret = 0; + + switch (request) + { + case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: + switch (value >> 8) + { + case USB_DT_REPORT: + ret = sizeof(hid_report_descriptor); + memcpy(data, hid_report_descriptor, ret); + break; + } + break; + case SET_IDLE: + break; + default: + ret = usb_desc_handle_control(dev, p, request, value, index, length, data); + if (ret >= 0) + { + return; + } + p->status = USB_RET_STALL; + break; + } + } + + static void buzz_handle_data(USBDevice* dev, USBPacket* p) + { + BuzzState* s = USB_CONTAINER_OF(dev, BuzzState, dev); + + switch (p->pid) + { + case USB_TOKEN_IN: + if (p->ep->nr == 1) + { + pxAssert(p->buffer_size >= sizeof(s->data)); + + s->data.head1 = s->data.head2 = 0x7f; + s->data.tail = 0xf; + + std::memcpy(p->buffer_ptr, &s->data, sizeof(s->data)); + + p->actual_length += sizeof(s->data); + } + else + { + goto fail; + } + break; + case USB_TOKEN_OUT: + break; + default: + fail: + p->status = USB_RET_STALL; + break; + } + } + + static void buzz_unrealize(USBDevice* dev) + { + BuzzState* s = USB_CONTAINER_OF(dev, BuzzState, dev); + delete s; + } + + const char* BuzzDevice::Name() const + { + return TRANSLATE_NOOP("USB", "Buzz Controller"); + } + + const char* BuzzDevice::TypeName() const + { + return "BuzzDevice"; + } + + USBDevice* BuzzDevice::CreateDevice(SettingsInterface& si, u32 port, u32 subtype) const + { + BuzzState* s = new BuzzState(port); + + s->desc.full = &s->desc_dev; + s->desc.str = desc_strings; + + if (usb_desc_parse_dev(dev_descriptor, sizeof(dev_descriptor), s->desc, s->desc_dev) < 0) + goto fail; + if (usb_desc_parse_config(config_descriptor, sizeof(config_descriptor), s->desc_dev) < 0) + goto fail; + + s->dev.speed = USB_SPEED_FULL; + s->dev.klass.handle_attach = usb_desc_attach; + s->dev.klass.handle_reset = nullptr; + s->dev.klass.handle_control = buzz_handle_control; + s->dev.klass.handle_data = buzz_handle_data; + s->dev.klass.unrealize = buzz_unrealize; + s->dev.klass.usb_desc = &s->desc; + s->dev.klass.product_desc = nullptr; + + usb_desc_init(&s->dev); + usb_ep_init(&s->dev); + + return &s->dev; + + fail: + buzz_unrealize(&s->dev); + return nullptr; + } + + float BuzzDevice::GetBindingValue(const USBDevice* dev, u32 bind_index) const + { + BuzzState* s = USB_CONTAINER_OF(dev, BuzzState, dev); + switch (bind_index) + { + case CID_BUZZ_PLAYER1_RED: return s->data.player1_red; + case CID_BUZZ_PLAYER1_BLUE: return s->data.player1_blue; + case CID_BUZZ_PLAYER1_ORANGE: return s->data.player1_orange; + case CID_BUZZ_PLAYER1_GREEN: return s->data.player1_green; + case CID_BUZZ_PLAYER1_YELLOW: return s->data.player1_yellow; + case CID_BUZZ_PLAYER2_RED: return s->data.player2_red; + case CID_BUZZ_PLAYER2_BLUE: return s->data.player2_blue; + case CID_BUZZ_PLAYER2_ORANGE: return s->data.player2_orange; + case CID_BUZZ_PLAYER2_GREEN: return s->data.player2_green; + case CID_BUZZ_PLAYER2_YELLOW: return s->data.player2_yellow; + case CID_BUZZ_PLAYER3_RED: return s->data.player3_red; + case CID_BUZZ_PLAYER3_BLUE: return s->data.player3_blue; + case CID_BUZZ_PLAYER3_ORANGE: return s->data.player3_orange; + case CID_BUZZ_PLAYER3_GREEN: return s->data.player3_green; + case CID_BUZZ_PLAYER3_YELLOW: return s->data.player3_yellow; + case CID_BUZZ_PLAYER4_RED: return s->data.player4_red; + case CID_BUZZ_PLAYER4_BLUE: return s->data.player4_blue; + case CID_BUZZ_PLAYER4_ORANGE: return s->data.player4_orange; + case CID_BUZZ_PLAYER4_GREEN: return s->data.player4_green; + case CID_BUZZ_PLAYER4_YELLOW: return s->data.player4_yellow; + default: + return 0.0f; + } + } + + void BuzzDevice::SetBindingValue(USBDevice* dev, u32 bind_index, float value) const + { + BuzzState* s = USB_CONTAINER_OF(dev, BuzzState, dev); + switch (bind_index) + { + case CID_BUZZ_PLAYER1_RED: s->data.player1_red = (value >= 0.5f); break; + case CID_BUZZ_PLAYER1_BLUE: s->data.player1_blue = (value >= 0.5f); break; + case CID_BUZZ_PLAYER1_ORANGE: s->data.player1_orange = (value >= 0.5f); break; + case CID_BUZZ_PLAYER1_GREEN: s->data.player1_green = (value >= 0.5f); break; + case CID_BUZZ_PLAYER1_YELLOW: s->data.player1_yellow = (value >= 0.5f); break; + case CID_BUZZ_PLAYER2_RED: s->data.player2_red = (value >= 0.5f); break; + case CID_BUZZ_PLAYER2_BLUE: s->data.player2_blue = (value >= 0.5f); break; + case CID_BUZZ_PLAYER2_ORANGE: s->data.player2_orange = (value >= 0.5f); break; + case CID_BUZZ_PLAYER2_GREEN: s->data.player2_green = (value >= 0.5f); break; + case CID_BUZZ_PLAYER2_YELLOW: s->data.player2_yellow = (value >= 0.5f); break; + case CID_BUZZ_PLAYER3_RED: s->data.player3_red = (value >= 0.5f); break; + case CID_BUZZ_PLAYER3_BLUE: s->data.player3_blue = (value >= 0.5f); break; + case CID_BUZZ_PLAYER3_ORANGE: s->data.player3_orange = (value >= 0.5f); break; + case CID_BUZZ_PLAYER3_GREEN: s->data.player3_green = (value >= 0.5f); break; + case CID_BUZZ_PLAYER3_YELLOW: s->data.player3_yellow = (value >= 0.5f); break; + case CID_BUZZ_PLAYER4_RED: s->data.player4_red = (value >= 0.5f); break; + case CID_BUZZ_PLAYER4_BLUE: s->data.player4_blue = (value >= 0.5f); break; + case CID_BUZZ_PLAYER4_ORANGE: s->data.player4_orange = (value >= 0.5f); break; + case CID_BUZZ_PLAYER4_GREEN: s->data.player4_green = (value >= 0.5f); break; + case CID_BUZZ_PLAYER4_YELLOW: s->data.player4_yellow = (value >= 0.5f); break; + default: + break; + } + } + + std::span BuzzDevice::Bindings(u32 subtype) const + { + static constexpr const InputBindingInfo bindings[] = { + {"Red1", TRANSLATE_NOOP("USB", "Player 1 Red"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER1_RED, GenericInputBinding::Circle}, + {"Blue1", TRANSLATE_NOOP("USB", "Player 1 Blue"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER1_BLUE, GenericInputBinding::R1}, + {"Orange1", TRANSLATE_NOOP("USB", "Player 1 Orange"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER1_ORANGE, GenericInputBinding::Cross}, + {"Green1", TRANSLATE_NOOP("USB", "Player 1 Green"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER1_GREEN, GenericInputBinding::Triangle}, + {"Yellow1", TRANSLATE_NOOP("USB", "Player 1 Yellow"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER1_YELLOW, GenericInputBinding::Square}, + + {"Red2", TRANSLATE_NOOP("USB", "Player 2 Red"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER2_RED, GenericInputBinding::Unknown}, + {"Blue2", TRANSLATE_NOOP("USB", "Player 2 Blue"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER2_BLUE, GenericInputBinding::Unknown}, + {"Orange2", TRANSLATE_NOOP("USB", "Player 2 Orange"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER2_ORANGE, GenericInputBinding::Unknown}, + {"Green2", TRANSLATE_NOOP("USB", "Player 2 Green"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER2_GREEN, GenericInputBinding::Unknown}, + {"Yellow2", TRANSLATE_NOOP("USB", "Player 2 Yellow"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER2_YELLOW, GenericInputBinding::Unknown}, + + {"Red3", TRANSLATE_NOOP("USB", "Player 3 Red"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER3_RED, GenericInputBinding::Unknown}, + {"Blue3", TRANSLATE_NOOP("USB", "Player 3 Blue"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER3_BLUE, GenericInputBinding::Unknown}, + {"Orange3", TRANSLATE_NOOP("USB", "Player 3 Orange"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER3_ORANGE, GenericInputBinding::Unknown}, + {"Green3", TRANSLATE_NOOP("USB", "Player 3 Green"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER3_GREEN, GenericInputBinding::Unknown}, + {"Yellow3", TRANSLATE_NOOP("USB", "Player 3 Yellow"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER3_YELLOW, GenericInputBinding::Unknown}, + + {"Red4", TRANSLATE_NOOP("USB", "Player 4 Red"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER4_RED, GenericInputBinding::Unknown}, + {"Blue4", TRANSLATE_NOOP("USB", "Player 4 Blue"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER4_BLUE, GenericInputBinding::Unknown}, + {"Orange4", TRANSLATE_NOOP("USB", "Player 4 Orange"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER4_ORANGE, GenericInputBinding::Unknown}, + {"Green4", TRANSLATE_NOOP("USB", "Player 4 Green"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER4_GREEN, GenericInputBinding::Unknown}, + {"Yellow4", TRANSLATE_NOOP("USB", "Player 4 Yellow"), nullptr, InputBindingInfo::Type::Button, CID_BUZZ_PLAYER4_YELLOW, GenericInputBinding::Unknown}, + }; + + return bindings; + } + + std::span BuzzDevice::Settings(u32 subtype) const + { + return {}; + } +} // namespace usb_pad diff --git a/pcsx2/USB/usb-pad/usb-buzz.h b/pcsx2/USB/usb-pad/usb-buzz.h new file mode 100644 index 0000000000..16c0ba8b66 --- /dev/null +++ b/pcsx2/USB/usb-pad/usb-buzz.h @@ -0,0 +1,94 @@ +// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team +// SPDX-License-Identifier: LGPL-3.0+ + +#pragma once +#include "SaveState.h" +#include "USB/qemu-usb/desc.h" +#include +#include + +namespace usb_pad +{ + enum BuzzControlID + { + CID_BUZZ_PLAYER1_RED, + CID_BUZZ_PLAYER1_BLUE, + CID_BUZZ_PLAYER1_ORANGE, + CID_BUZZ_PLAYER1_GREEN, + CID_BUZZ_PLAYER1_YELLOW, + CID_BUZZ_PLAYER2_RED, + CID_BUZZ_PLAYER2_BLUE, + CID_BUZZ_PLAYER2_ORANGE, + CID_BUZZ_PLAYER2_GREEN, + CID_BUZZ_PLAYER2_YELLOW, + CID_BUZZ_PLAYER3_RED, + CID_BUZZ_PLAYER3_BLUE, + CID_BUZZ_PLAYER3_ORANGE, + CID_BUZZ_PLAYER3_GREEN, + CID_BUZZ_PLAYER3_YELLOW, + CID_BUZZ_PLAYER4_RED, + CID_BUZZ_PLAYER4_BLUE, + CID_BUZZ_PLAYER4_ORANGE, + CID_BUZZ_PLAYER4_GREEN, + CID_BUZZ_PLAYER4_YELLOW, + CID_BUZZ_COUNT, + }; + + struct BuzzState + { + BuzzState(u32 port_); + ~BuzzState(); + + USBDevice dev{}; + USBDesc desc{}; + USBDescDevice desc_dev{}; + + u32 port = 0; + + #pragma pack(push, 1) + struct + { + u8 head1; + u8 head2; + + u8 player1_red : 1; + u8 player1_yellow : 1; + u8 player1_green : 1; + u8 player1_orange : 1; + u8 player1_blue : 1; + u8 player2_red : 1; + u8 player2_yellow : 1; + u8 player2_green : 1; + + u8 player2_orange : 1; + u8 player2_blue : 1; + u8 player3_red : 1; + u8 player3_yellow : 1; + u8 player3_green : 1; + u8 player3_orange : 1; + u8 player3_blue : 1; + u8 player4_red : 1; + + u8 player4_yellow : 1; + u8 player4_green : 1; + u8 player4_orange : 1; + u8 player4_blue : 1; + + u8 tail : 4; + } data = {}; + #pragma pack(pop) + }; + + class BuzzDevice final : public DeviceProxy + { + public: + const char* Name() const override; + const char* TypeName() const override; + float GetBindingValue(const USBDevice* dev, u32 bind_index) const override; + void SetBindingValue(USBDevice* dev, u32 bind_index, float value) const override; + std::span Bindings(u32 subtype) const override; + std::span Settings(u32 subtype) const override; + USBDevice* CreateDevice(SettingsInterface& si, u32 port, u32 subtype) const override; + }; + +} // namespace usb_pad diff --git a/pcsx2/USB/usb-pad/usb-pad.cpp b/pcsx2/USB/usb-pad/usb-pad.cpp index 8a5c8e135d..df7fa70b2f 100644 --- a/pcsx2/USB/usb-pad/usb-pad.cpp +++ b/pcsx2/USB/usb-pad/usb-pad.cpp @@ -37,12 +37,6 @@ namespace usb_pad "Licensed by Sony Computer Entertainment America", "Harmonix Drum Kit for PlayStation(R)3"}; - static const USBDescStrings buzz_desc_strings = { - "", - "Logitech Buzz(tm) Controller V1", - "", - "Logitech"}; - static const USBDescStrings kbm_desc_strings = { "", "USB Multipurpose Controller", @@ -339,18 +333,6 @@ namespace usb_pad return len; } - case WT_BUZZ_CONTROLLER: - { - // https://gist.github.com/Lewiscowles1986/eef220dac6f0549e4702393a7b9351f6 - buf[0] = 0x7f; - buf[1] = 0x7f; - buf[2] = data.buttons & 0xff; - buf[3] = (data.buttons >> 8) & 0xff; - buf[4] = 0xf0 | ((data.buttons >> 16) & 0xf); - - return 5; - } - case WT_SEGA_SEAMIC: { UpdateSteering(); @@ -695,11 +677,6 @@ namespace usb_pad ret = sizeof(pad_driving_force_hid_separate_report_descriptor); memcpy(data, pad_driving_force_hid_separate_report_descriptor, ret); } - else if (s->type == WT_BUZZ_CONTROLLER) - { - ret = sizeof(buzz_hid_report_descriptor); - memcpy(data, buzz_hid_report_descriptor, ret); - } p->actual_length = ret; break; default: @@ -951,80 +928,6 @@ namespace usb_pad return {}; } - // ---- Buzz ---- - - const char* BuzzDevice::Name() const - { - return TRANSLATE_NOOP("USB", "Buzz Controller"); - } - - const char* BuzzDevice::TypeName() const - { - return "BuzzDevice"; - } - - std::span BuzzDevice::SubTypes() const - { - return {}; - } - - std::span BuzzDevice::Bindings(u32 subtype) const - { - static constexpr const InputBindingInfo bindings[] = { - {"Red1", TRANSLATE_NOOP("USB", "Player 1 Red"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON0, GenericInputBinding::Circle}, - {"Blue1", TRANSLATE_NOOP("USB", "Player 1 Blue"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON4, GenericInputBinding::R1}, - {"Orange1", TRANSLATE_NOOP("USB", "Player 1 Orange"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON3, GenericInputBinding::Cross}, - {"Green1", TRANSLATE_NOOP("USB", "Player 1 Green"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON2, GenericInputBinding::Triangle}, - {"Yellow1", TRANSLATE_NOOP("USB", "Player 1 Yellow"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON1, GenericInputBinding::Square}, - - {"Red2", TRANSLATE_NOOP("USB", "Player 2 Red"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON5, GenericInputBinding::Unknown}, - {"Blue2", TRANSLATE_NOOP("USB", "Player 2 Blue"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON9, GenericInputBinding::Unknown}, - {"Orange2", TRANSLATE_NOOP("USB", "Player 2 Orange"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON8, GenericInputBinding::Unknown}, - {"Green2", TRANSLATE_NOOP("USB", "Player 2 Green"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON7, GenericInputBinding::Unknown}, - {"Yellow2", TRANSLATE_NOOP("USB", "Player 2 Yellow"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON6, GenericInputBinding::Unknown}, - - {"Red3", TRANSLATE_NOOP("USB", "Player 3 Red"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON10, GenericInputBinding::Unknown}, - {"Blue3", TRANSLATE_NOOP("USB", "Player 3 Blue"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON14, GenericInputBinding::Unknown}, - {"Orange3", TRANSLATE_NOOP("USB", "Player 3 Orange"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON13, GenericInputBinding::Unknown}, - {"Green3", TRANSLATE_NOOP("USB", "Player 3 Green"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON12, GenericInputBinding::Unknown}, - {"Yellow3", TRANSLATE_NOOP("USB", "Player 3 Yellow"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON11, GenericInputBinding::Unknown}, - - {"Red4", TRANSLATE_NOOP("USB", "Player 4 Red"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON15, GenericInputBinding::Unknown}, - {"Blue4", TRANSLATE_NOOP("USB", "Player 4 Blue"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON19, GenericInputBinding::Unknown}, - {"Orange4", TRANSLATE_NOOP("USB", "Player 4 Orange"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON18, GenericInputBinding::Unknown}, - {"Green4", TRANSLATE_NOOP("USB", "Player 4 Green"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON17, GenericInputBinding::Unknown}, - {"Yellow4", TRANSLATE_NOOP("USB", "Player 4 Yellow"), nullptr, InputBindingInfo::Type::Button, CID_BUTTON16, GenericInputBinding::Unknown}, - }; - - return bindings; - } - - std::span BuzzDevice::Settings(u32 subtype) const - { - return {}; - } - - USBDevice* BuzzDevice::CreateDevice(SettingsInterface& si, u32 port, u32 subtype) const - { - PadState* s = new PadState(port, WT_BUZZ_CONTROLLER); - - s->desc.full = &s->desc_dev; - s->desc.str = buzz_desc_strings; - - if (usb_desc_parse_dev(buzz_dev_descriptor, sizeof(buzz_dev_descriptor), s->desc, s->desc_dev) < 0) - goto fail; - if (usb_desc_parse_config(buzz_config_descriptor, sizeof(buzz_config_descriptor), s->desc_dev) < 0) - goto fail; - - pad_init(s); - - return &s->dev; - - fail: - pad_handle_destroy(&s->dev); - return nullptr; - } - // ---- Keyboardmania ---- const char* KeyboardmaniaDevice::Name() const diff --git a/pcsx2/USB/usb-pad/usb-pad.h b/pcsx2/USB/usb-pad/usb-pad.h index 0fc2681714..f05eb9cc5a 100644 --- a/pcsx2/USB/usb-pad/usb-pad.h +++ b/pcsx2/USB/usb-pad/usb-pad.h @@ -61,7 +61,6 @@ namespace usb_pad WT_DRIVING_FORCE_PRO_1102, //hw with buggy hid report? WT_GT_FORCE, //formula gp WT_ROCKBAND1_DRUMKIT, - WT_BUZZ_CONTROLLER, WT_SEGA_SEAMIC, WT_KEYBOARDMANIA_CONTROLLER, WT_COUNT, @@ -95,17 +94,6 @@ namespace usb_pad USBDevice* CreateDevice(SettingsInterface& si, u32 port, u32 subtype) const override; }; - class BuzzDevice final : public PadDevice - { - public: - const char* Name() const; - const char* TypeName() const; - std::span SubTypes() const; - std::span Bindings(u32 subtype) const; - std::span Settings(u32 subtype) const; - USBDevice* CreateDevice(SettingsInterface& si, u32 port, u32 subtype) const; - }; - class SeamicDevice final : public PadDevice { public: @@ -1108,105 +1096,6 @@ namespace usb_pad // 137 bytes }; - ////////// - // Buzz // - ////////// - - static const uint8_t buzz_dev_descriptor[] = { - 0x12, // bLength - 0x01, // bDescriptorType (Device) - 0x00, 0x02, // bcdUSB 2.00 - 0x00, // bDeviceClass (Use class information in the Interface Descriptors) - 0x00, // bDeviceSubClass - 0x00, // bDeviceProtocol - 0x08, // bMaxPacketSize0 8 - 0x4C, 0x05, // idVendor 0x054C - 0x02, 0x00, // idProduct 0x0002 - 0xA1, 0x05, // bcdDevice 11.01 - 0x03, // iManufacturer (String Index) - 0x01, // iProduct (String Index) - 0x00, // iSerialNumber (String Index) - 0x01, // bNumConfigurations 1 - }; - - static const uint8_t buzz_config_descriptor[] = { - 0x09, // bLength - 0x02, // bDescriptorType (Configuration) - 0x22, 0x00, // wTotalLength 34 - 0x01, // bNumInterfaces 1 - 0x01, // bConfigurationValue - 0x00, // iConfiguration (String Index) - 0x80, // bmAttributes - 0x32, // bMaxPower 100mA - - 0x09, // bLength - 0x04, // bDescriptorType (Interface) - 0x00, // bInterfaceNumber 0 - 0x00, // bAlternateSetting - 0x01, // bNumEndpoints 1 - 0x03, // bInterfaceClass - 0x00, // bInterfaceSubClass - 0x00, // bInterfaceProtocol - 0x00, // iInterface (String Index) - - 0x09, // bLength - 0x21, // bDescriptorType (HID) - 0x11, 0x01, // bcdHID 1.11 - 0x33, // bCountryCode - 0x01, // bNumDescriptors - 0x22, // bDescriptorType[0] (HID) - 0x4E, 0x00, // wDescriptorLength[0] 78 - - 0x07, // bLength - 0x05, // bDescriptorType (Endpoint) - 0x81, // bEndpointAddress (IN/D2H) - 0x03, // bmAttributes (Interrupt) - 0x08, 0x00, // wMaxPacketSize 8 - 0x0A, // bInterval 10 (unit depends on device speed) - }; - - static const uint8_t buzz_hid_report_descriptor[] = { - 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) - 0x09, 0x04, // Usage (Joystick) - 0xA1, 0x01, // Collection (Application) - 0xA1, 0x02, // Collection (Logical) - 0x75, 0x08, // Report Size (8) - 0x95, 0x02, // Report Count (2) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x35, 0x00, // Physical Minimum (0) - 0x46, 0xFF, 0x00, // Physical Maximum (255) - 0x09, 0x30, // Usage (X) - 0x09, 0x31, // Usage (Y) - 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x75, 0x01, // Report Size (1) - 0x95, 0x14, // Report Count (20) - 0x25, 0x01, // Logical Maximum (1) - 0x45, 0x01, // Physical Maximum (1) - 0x05, 0x09, // Usage Page (Button) - 0x19, 0x01, // Usage Minimum (0x01) - 0x29, 0x14, // Usage Maximum (0x14) - 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) - 0x75, 0x01, // Report Size (1) - 0x95, 0x04, // Report Count (4) - 0x25, 0x01, // Logical Maximum (1) - 0x45, 0x01, // Physical Maximum (1) - 0x09, 0x01, // Usage (0x01) - 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0xC0, // End Collection - 0xA1, 0x02, // Collection (Logical) - 0x75, 0x08, // Report Size (8) - 0x95, 0x07, // Report Count (7) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x46, 0xFF, 0x00, // Physical Maximum (255) - 0x09, 0x02, // Usage (0x02) - 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) - 0xC0, // End Collection - 0xC0, // End Collection - // 78 bytes - }; - /////////////////// // Keyboardmania // /////////////////// diff --git a/pcsx2/pcsx2.vcxproj b/pcsx2/pcsx2.vcxproj index f9b0f83eab..a0c70b5e14 100644 --- a/pcsx2/pcsx2.vcxproj +++ b/pcsx2/pcsx2.vcxproj @@ -392,6 +392,7 @@ + @@ -842,6 +843,7 @@ + diff --git a/pcsx2/pcsx2.vcxproj.filters b/pcsx2/pcsx2.vcxproj.filters index 27b0cd06f1..bc919af5c5 100644 --- a/pcsx2/pcsx2.vcxproj.filters +++ b/pcsx2/pcsx2.vcxproj.filters @@ -1187,6 +1187,9 @@ System\Ps2\USB\usb-hid + + System\Ps2\USB\usb-pad + System\Ps2\USB\usb-pad @@ -2130,6 +2133,9 @@ System\Ps2\USB\usb-hid + + System\Ps2\USB\usb-pad + System\Ps2\USB\usb-pad