jackun / USBqemu-wheel

PCSX2 usb plugin for wheels and increasingly more stuff
The Unlicense
121 stars 21 forks source link

Trying to add support for Keyboardmania #52

Open aleksre opened 4 years ago

aleksre commented 4 years ago

Hi. I'm currently trying to add support for the Keyboardmania controller to USBqemu, but because I am a noob when it comes to both C programming and HID devices in general I think I need some help.

I have added the basics to support the controller in my branch here https://github.com/jackun/USBqemu-wheel/compare/master...aleksre:Keyboardmania and it is currently partially working. Keys C1 - A#1 work, (the first 11 keys). The rest of the keys and buttons don't.

About the controller: The controller has buttons start, select, wheel up, wheel down, and 24 keys (28 buttons total), All are digital on/off buttons. LilyPad diagnostics reports that the first 6 buttons (Button 57 - 62) are pressed at all times. Button 0 - 25 are used by the keys. The exceptions are button 13 and 20 which are used by select and start respectively. Button 26 and 27 are wheel up and wheel down. Analogue Y and X axis is also present in the diagnostics but these just stay idle at 0.5 (there is no analogue device on the controller).

Dump of all keypresses: (Using Simple HID Write)

RD 00  3F 00 00 40 00 00 00 00 // Start
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 40 00 00 00 00 00 // Select
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 00 20 00 00 00 // Wheel Up
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 00 40 00 00 00 // Wheel Down
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 01 00 00 00 00 00 00 // C1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 02 00 00 00 00 00 00 // C#1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 04 00 00 00 00 00 00 // D1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 08 00 00 00 00 00 00 // D#1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 10 00 00 00 00 00 00 // E1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 20 00 00 00 00 00 00 // F1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 40 00 00 00 00 00 00 // F#1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 01 00 00 00 00 00 // G1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 02 00 00 00 00 00 // G#1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 04 00 00 00 00 00 // A1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 08 00 00 00 00 00 // A#1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 10 00 00 00 00 00 // B1
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 20 00 00 00 00 00 // C2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 01 00 00 00 00 // C#2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 02 00 00 00 00 // D2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 04 00 00 00 00 // D#2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 08 00 00 00 00 // E2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 10 00 00 00 00 // F2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 20 00 00 00 00 // F#2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 00 01 00 00 00 // G2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 00 02 00 00 00 // G#2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 00 04 00 00 00 // A2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 00 08 00 00 00 // A#2
RD 00  3F 00 00 00 00 00 00 00 
RD 00  3F 00 00 00 10 00 00 00 // B2
RD 00  3F 00 00 00 00 00 00 00 

I'm guessing part of the problem is case WT_KEYBOARDMANIA_CONTROLLER: in usb-pad.cpp. But the actual mapping has been trial and error up until this point so there could be things I'm missing there as well.

In addition to DInput, I would also like to add support for RawInput with passthrough to use the official controller without mapping anything. This is mainly because manual key mapping using the controller is basically impossible with 6 buttons constantly pressed down. I have no idea what is needed to support this though.

Thanks

jackun commented 4 years ago

By glance, looks like it should work. The thing seems to be button mapping. DInput dialog maps C1 to button 10 (IDC_ASS10), I think, but C1 is first bit so button id should be IDC_ASS0. Looks like you already listed the buttons in ascending order from C1, just move Start (between F#2 and G2) etc

And maybe custom control check like with Buzz

aleksre commented 4 years ago

Oh right, that makes sense. The custom control check was the missing piece. Otherwise only 12 buttons will be added. All buttons are working now 👍

Do you how I can add passthrough support?

jackun commented 4 years ago

I guess it is kind of annoying currently because it's pretty hardcoded for wheels. But probably add "Pass-through" check box to config dialog, check if it is keyboardmania device (mDevType is "keyboardmania_device", which itself probably could be just "keyboardmania") , if true, try finding the HID device according to VID/PID(1, 2). You'd probably have to do the check before CreateFileW on line usb-pad-raw.cpp#L424 and just let it check for the second time on line 433 to keep compat with wheel device, for now.

If you want to merge it back then rebase it on develop. Plugin is getting merged back into PCSX2 ~v1.8.0

aleksre commented 4 years ago

Ok, I didn't quite understand what I specifically need to do before CreateFileW, but I have updated my branch with an initial implementation (also merged with develop): https://github.com/jackun/USBqemu-wheel/compare/develop...aleksre:Keyboardmania

The connected controller shows in the device list now, and checking the Logitech pass-though checkbox now definitely does something. Mapping is not correct though. Most buttons do nothing, those that do are incorrect, and multiple simultaneous keypresses map to single keys, so I'm guessing the hex data is not forwarded properly.

jackun commented 4 years ago

Rebase, not merge ;) Gives nicer commits.

before CreateFileW

I meant, maybe if it tries to find kbdmania there automatically so then there's no need to select it manually from config dialog. if (!strcmp(mDevType, KeyboardmaniaDevice::TypeName()) .. etc... (actually both char*'s point to same address? :thinking:)

And probably

bool isClassicLogitech = (attr.VendorID == PAD_VID) && (attr.ProductID != 0xC262);
bool isKeyboardmania = (attr.VendorID == 0x0507) && (attr.ProductID == 0x0010);
if (!isClassicLogitech && !isKeyboardmania) {

Have to think why it doesn't work with pass-through. One thing's that the queue gets filled up quicker than game reads input.

aleksre commented 4 years ago

Allright. Rebase version 😁: https://github.com/jackun/USBqemu-wheel/compare/develop...aleksre:Keyboardmania-rebase

Not sure if it helps, but I noted down some of the current mappings The only single-to-single button mappings are D#1, A#1, and E2. All of them map to F1 in the game.

There are many multiple-to-single mappings. A few of them are: D1 + D#1 -> D2 D#1 + E1 -> C2 E1 + F1 -> A2 D2 + F2 -> E2 G1 + C2 -> F#1 A#1 + C2 -> B2

I meant, maybe if it tries to find kbdmania there automatically so then there's no need to select it manually from config dialog.

I don't know if I agree with this. As a user I would expect a connected controller to show up there. This also gives me confidence that it is actually detected. In addition, if I have 2 controllers connected I should be able to choose which controller is mapped to which player.