Skip to content

Commit 9bd578b

Browse files
authored
Merge pull request #28 from Florin9doi/buzz
Buzz controller
2 parents de5e430 + c959ca9 commit 9bd578b

File tree

6 files changed

+230
-2
lines changed

6 files changed

+230
-2
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ set(CMAKE_MODULE_PATH
1919

2020
SET (PLUGIN_VERSION_MAJOR "0")
2121
SET (PLUGIN_VERSION_MINOR "8")
22-
SET (PLUGIN_VERSION_PATCH "2")
22+
SET (PLUGIN_VERSION_PATCH "5")
2323
SET (PLUGIN_VERSION "${PLUGIN_VERSION_MAJOR}.${PLUGIN_VERSION_MINOR}.${PLUGIN_VERSION_PATCH}")
2424
SET (TargetNameVer "${TargetName}-${PLUGIN_VERSION}")
2525
SET (DEBIAN_PACKAGE "libusbqemu-wheel-unstable")

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ On Windows:
7676
cd some/where/USBqemu-wheel
7777
mkdir build
7878
cd build
79-
cmake .. -G"Visual Studio 14"
79+
cmake .. -G"Visual Studio 16 2019" -A Win32
8080
cmake --build . --config Release
8181
cmake --build . --target install
8282

src/device_init.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ void RegisterDevice::Initialize()
1616
inst.Add(DEVTYPE_HIDKBD, new DeviceProxy<usb_hid::HIDKbdDevice>());
1717
inst.Add(DEVTYPE_HIDMOUSE, new DeviceProxy<usb_hid::HIDMouseDevice>());
1818
inst.Add(DEVTYPE_RBKIT, new DeviceProxy<usb_pad::RBDrumKitDevice>());
19+
inst.Add(DEVTYPE_BUZZ, new DeviceProxy<usb_pad::BuzzDevice>());
1920
}

src/deviceproxy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ enum DeviceType
2424
DEVTYPE_HIDKBD,
2525
DEVTYPE_HIDMOUSE,
2626
DEVTYPE_RBKIT,
27+
DEVTYPE_BUZZ,
2728
};
2829

2930
struct SelectDeviceName {

src/usb-pad/usb-pad.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ static const USBDescStrings rb1_desc_strings = {
3030
"Harmonix Drum Kit for PlayStation(R)3"
3131
};
3232

33+
static const USBDescStrings buzz_desc_strings = {
34+
"",
35+
"Logitech Buzz(tm) Controller V1",
36+
"",
37+
"Logitech"
38+
};
39+
3340
void PadDevice::Initialize()
3441
{
3542
RegisterPad::Initialize();
@@ -383,8 +390,19 @@ void pad_copy_data(PS2WheelTypes type, uint8_t *buf, wheel_data_t &data)
383390
case WT_ROCKBAND1_DRUMKIT:
384391
w->lo = (data.buttons & 0xFFF);
385392
w->lo |= (data.hatswitch & 0xF) << 16;
393+
break;
386394

395+
case WT_BUZZ_CONTROLLER:
396+
// https://gist.github.com/Lewiscowles1986/eef220dac6f0549e4702393a7b9351f6
397+
w->hi = 0x7f;
398+
w->lo = 0x7f << 24;
399+
w->lo |= ((data.buttons >> PAD_CIRCLE) & 1) << 16; // red
400+
w->lo |= ((data.buttons >> PAD_CROSS) & 1) << 20; // blue
401+
w->lo |= ((data.buttons >> PAD_R1) & 1) << 19; // orange
402+
w->lo |= ((data.buttons >> PAD_SQUARE) & 1) << 18; // green
403+
w->lo |= ((data.buttons >> PAD_TRIANGLE) & 1) << 17; // yellow
387404
break;
405+
388406
default:
389407
break;
390408
}
@@ -652,6 +670,94 @@ int RBDrumKitDevice::Freeze(int mode, USBDevice *dev, void *data)
652670
return PadDevice::Freeze(mode, dev, data);
653671
}
654672

673+
// ---- Buzz ----
674+
675+
USBDevice* BuzzDevice::CreateDevice(int port)
676+
{
677+
std::string varApi;
678+
LoadSetting(nullptr, port, TypeName(), N_DEVICE_API, varApi);
679+
PadProxyBase* proxy = RegisterPad::instance().Proxy(varApi);
680+
if (!proxy)
681+
{
682+
SysMessage(TEXT("Buzz: Invalid input API.\n"));
683+
USB_LOG("usb-pad: %s: Invalid input API.\n", TypeName());
684+
return NULL;
685+
}
686+
687+
USB_LOG("usb-pad: creating device '%s' on port %d with %s\n", TypeName(), port, varApi.c_str());
688+
Pad* pad = proxy->CreateObject(port, TypeName());
689+
690+
if (!pad)
691+
return NULL;
692+
693+
pad->Type(WT_BUZZ_CONTROLLER);
694+
PADState* s = new PADState();
695+
696+
s->desc.full = &s->desc_dev;
697+
s->desc.str = buzz_desc_strings;
698+
699+
if (usb_desc_parse_dev(buzz_dev_descriptor, sizeof(buzz_dev_descriptor), s->desc, s->desc_dev) < 0)
700+
goto fail;
701+
if (usb_desc_parse_config(buzz_config_descriptor, sizeof(buzz_config_descriptor), s->desc_dev) < 0)
702+
goto fail;
703+
704+
s->f.wheel_type = pad->Type();
705+
s->pad = pad;
706+
s->port = port;
707+
s->dev.speed = USB_SPEED_FULL;
708+
s->dev.klass.handle_attach = usb_desc_attach;
709+
s->dev.klass.handle_reset = pad_handle_reset;
710+
s->dev.klass.handle_control = pad_handle_control;
711+
s->dev.klass.handle_data = pad_handle_data;
712+
s->dev.klass.unrealize = pad_handle_destroy;
713+
s->dev.klass.open = pad_open;
714+
s->dev.klass.close = pad_close;
715+
s->dev.klass.usb_desc = &s->desc;
716+
s->dev.klass.product_desc = s->desc.str[2];
717+
718+
usb_desc_init(&s->dev);
719+
usb_ep_init(&s->dev);
720+
pad_handle_reset((USBDevice*)s);
721+
722+
return (USBDevice*)s;
723+
724+
fail:
725+
pad_handle_destroy((USBDevice*)s);
726+
return nullptr;
727+
}
728+
729+
std::list<std::string> BuzzDevice::ListAPIs()
730+
{
731+
return RegisterPad::instance().Names();
732+
}
733+
734+
const TCHAR* BuzzDevice::LongAPIName(const std::string& name)
735+
{
736+
auto proxy = RegisterPad::instance().Proxy(name);
737+
if (proxy)
738+
return proxy->Name();
739+
return nullptr;
740+
}
741+
742+
int BuzzDevice::Configure(int port, const std::string& api, void* data)
743+
{
744+
auto proxy = RegisterPad::instance().Proxy(api);
745+
if (proxy)
746+
return proxy->Configure(port, TypeName(), data);
747+
return RESULT_CANCELED;
748+
}
749+
750+
int BuzzDevice::Freeze(int mode, USBDevice* dev, void* data)
751+
{
752+
return PadDevice::Freeze(mode, dev, data);
753+
}
754+
755+
void BuzzDevice::Initialize()
756+
{
757+
RegisterPad::Initialize();
758+
}
759+
655760
REGISTER_DEVICE(DEVTYPE_PAD, PadDevice);
656761
REGISTER_DEVICE(DEVTYPE_RBKIT, RBDrumKitDevice);
762+
REGISTER_DEVICE(DEVTYPE_BUZZ, BuzzDevice);
657763
} //namespace

src/usb-pad/usb-pad.h

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,26 @@ class RBDrumKitDevice
5353
static void Initialize();
5454
};
5555

56+
class BuzzDevice
57+
{
58+
public:
59+
virtual ~BuzzDevice() {}
60+
static USBDevice* CreateDevice(int port);
61+
static const TCHAR* Name()
62+
{
63+
return TEXT("Buzz Device");
64+
}
65+
static const char* TypeName()
66+
{
67+
return "buzz_device";
68+
}
69+
static std::list<std::string> ListAPIs();
70+
static const TCHAR* LongAPIName(const std::string& name);
71+
static int Configure(int port, const std::string& api, void* data);
72+
static int Freeze(int mode, USBDevice* dev, void* data);
73+
static void Initialize();
74+
};
75+
5676
// Most likely as seen on https://github.com/matlo/GIMX
5777
#define CMD_DOWNLOAD 0x00
5878
#define CMD_DOWNLOAD_AND_PLAY 0x01
@@ -99,6 +119,7 @@ enum PS2WheelTypes {
99119
WT_DRIVING_FORCE_PRO_1102, //hw with buggy hid report?
100120
WT_GT_FORCE, //formula gp
101121
WT_ROCKBAND1_DRUMKIT,
122+
WT_BUZZ_CONTROLLER,
102123
};
103124

104125
inline int range_max(PS2WheelTypes type)
@@ -1034,6 +1055,105 @@ static const uint8_t rb1_hid_report_descriptor[] = {
10341055
// 137 bytes
10351056
};
10361057

1058+
//////////
1059+
// Buzz //
1060+
//////////
1061+
1062+
static const uint8_t buzz_dev_descriptor[] = {
1063+
0x12, // bLength
1064+
0x01, // bDescriptorType (Device)
1065+
0x00, 0x02, // bcdUSB 2.00
1066+
0x00, // bDeviceClass (Use class information in the Interface Descriptors)
1067+
0x00, // bDeviceSubClass
1068+
0x00, // bDeviceProtocol
1069+
0x08, // bMaxPacketSize0 8
1070+
0x4C, 0x05, // idVendor 0x054C
1071+
0x02, 0x00, // idProduct 0x0002
1072+
0xA1, 0x05, // bcdDevice 11.01
1073+
0x03, // iManufacturer (String Index)
1074+
0x01, // iProduct (String Index)
1075+
0x00, // iSerialNumber (String Index)
1076+
0x01, // bNumConfigurations 1
1077+
};
1078+
1079+
static const uint8_t buzz_config_descriptor[] = {
1080+
0x09, // bLength
1081+
0x02, // bDescriptorType (Configuration)
1082+
0x22, 0x00, // wTotalLength 34
1083+
0x01, // bNumInterfaces 1
1084+
0x01, // bConfigurationValue
1085+
0x00, // iConfiguration (String Index)
1086+
0x80, // bmAttributes
1087+
0x32, // bMaxPower 100mA
1088+
1089+
0x09, // bLength
1090+
0x04, // bDescriptorType (Interface)
1091+
0x00, // bInterfaceNumber 0
1092+
0x00, // bAlternateSetting
1093+
0x01, // bNumEndpoints 1
1094+
0x03, // bInterfaceClass
1095+
0x00, // bInterfaceSubClass
1096+
0x00, // bInterfaceProtocol
1097+
0x00, // iInterface (String Index)
1098+
1099+
0x09, // bLength
1100+
0x21, // bDescriptorType (HID)
1101+
0x11, 0x01, // bcdHID 1.11
1102+
0x33, // bCountryCode
1103+
0x01, // bNumDescriptors
1104+
0x22, // bDescriptorType[0] (HID)
1105+
0x4E, 0x00, // wDescriptorLength[0] 78
1106+
1107+
0x07, // bLength
1108+
0x05, // bDescriptorType (Endpoint)
1109+
0x81, // bEndpointAddress (IN/D2H)
1110+
0x03, // bmAttributes (Interrupt)
1111+
0x08, 0x00, // wMaxPacketSize 8
1112+
0x0A, // bInterval 10 (unit depends on device speed)
1113+
};
1114+
1115+
static const uint8_t buzz_hid_report_descriptor[] = {
1116+
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
1117+
0x09, 0x04, // Usage (Joystick)
1118+
0xA1, 0x01, // Collection (Application)
1119+
0xA1, 0x02, // Collection (Logical)
1120+
0x75, 0x08, // Report Size (8)
1121+
0x95, 0x02, // Report Count (2)
1122+
0x15, 0x00, // Logical Minimum (0)
1123+
0x26, 0xFF, 0x00, // Logical Maximum (255)
1124+
0x35, 0x00, // Physical Minimum (0)
1125+
0x46, 0xFF, 0x00, // Physical Maximum (255)
1126+
0x09, 0x30, // Usage (X)
1127+
0x09, 0x31, // Usage (Y)
1128+
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
1129+
0x75, 0x01, // Report Size (1)
1130+
0x95, 0x14, // Report Count (20)
1131+
0x25, 0x01, // Logical Maximum (1)
1132+
0x45, 0x01, // Physical Maximum (1)
1133+
0x05, 0x09, // Usage Page (Button)
1134+
0x19, 0x01, // Usage Minimum (0x01)
1135+
0x29, 0x14, // Usage Maximum (0x14)
1136+
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
1137+
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
1138+
0x75, 0x01, // Report Size (1)
1139+
0x95, 0x04, // Report Count (4)
1140+
0x25, 0x01, // Logical Maximum (1)
1141+
0x45, 0x01, // Physical Maximum (1)
1142+
0x09, 0x01, // Usage (0x01)
1143+
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
1144+
0xC0, // End Collection
1145+
0xA1, 0x02, // Collection (Logical)
1146+
0x75, 0x08, // Report Size (8)
1147+
0x95, 0x07, // Report Count (7)
1148+
0x26, 0xFF, 0x00, // Logical Maximum (255)
1149+
0x46, 0xFF, 0x00, // Physical Maximum (255)
1150+
0x09, 0x02, // Usage (0x02)
1151+
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
1152+
0xC0, // End Collection
1153+
0xC0, // End Collection
1154+
// 78 bytes
1155+
};
1156+
10371157
struct dfp_buttons_t
10381158
{
10391159
uint16_t cross : 1;

0 commit comments

Comments
 (0)