lemmingDev / ESP32-BLE-Gamepad

Bluetooth LE Gamepad library for the ESP32
Other
1.09k stars 179 forks source link

feature request: Add support for "START" and "SELECT" buttons #57

Closed aguaviva closed 2 years ago

aguaviva commented 3 years ago

I've been looking into doing this myself but I couldnt find any good examples, maybe this is low hanging fruit for you or you can point me to a good resource :)

This is how my descriptor looks so far but I am sure I am missing out many things

    //       start and select
    {
        // USAGE_PAGE (Generic Desktop)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x05;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01;

        // USAGE_MAXIMUM (Up to 128 buttons possible)            
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x29;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 2;

        // LOGICAL_MINIMUM (0)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x15;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x00;

        // LOGICAL_MAXIMUM (1)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x25;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01;

        // REPORT_SIZE (1)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x75;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01;

        // REPORT_COUNT (# of buttons)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x95;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 2;

        // UNIT (None)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x65;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x00;

        // USAGE (START)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x3D;

        // USAGE (SELECT)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x3E;
    }
aguaviva commented 3 years ago

Alright I got this working :)

    //       start and select
    {
        // USAGE_PAGE (Generic Desktop)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x05;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01;

        // LOGICAL_MINIMUM (0)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x15;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x00;

        // LOGICAL_MAXIMUM (1)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x25;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01;

        // REPORT_SIZE (1)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x75;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01;

        // REPORT_COUNT (# of buttons)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x95;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 2;

        // UNIT (None)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x65;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x00;

        // USAGE (START)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x3D;

        // USAGE (SELECT)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x3E;

        // INPUT (Data,Var,Abs)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x81;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x02;      

        //padding

        // REPORT_SIZE (1)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x75;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01;

        // REPORT_COUNT (# of padding bits)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x95;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 8-2;

        // INPUT (Const,Var,Abs)
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x81;
        tempHidReportDescriptor[hidReportDescriptorSize++] = 0x03;      
    }

now time to add the "menu" button too!

aguaviva commented 3 years ago

OK I made it! And using this feature I developed the following project: https://github.com/aguaviva/PS3ToBle

Could you check out my code and incorporate the changes I made however you see fit? You comments are more than welcome!

I hope this will help a lot of people use their ps3 controllers with any system :)

lemmingDev commented 3 years ago

Nice work

Could you give any insight into what needs to be done to get BT Classic Serial and BLE working together?

I can get the ESP32 to use both when BLE is connected to a PC and BT Classic Serial is connected to a phone, but there seems to be an issue getting them both connected to the PC at the same time.

https://github.com/lemmingDev/ESP32-BLE-Gamepad/issues/54#issuecomment-816556504

aguaviva commented 3 years ago

I had to change the way BT gets initialized, the commented out part is the old code, see: https://github.com/aguaviva/PS3ToBle/blob/fe1561dd027bfb616992645527eb412b9da89e3a/libraries/PS3_Controller_Host/src/ps3_spp.c#L41

lemmingDev commented 3 years ago

Any idea what would need to be changed either in my library or the official BT Serial library to get them to co-exist?

aguaviva commented 3 years ago

I didn't have to change anything in your library. The only think is that I had to init your lib after the PS3 controller had connected via BT.

In case you need more sampels, here you have 2 sample apps that show what is needed: https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/bluedroid/coex

Any chance you could add the start and select buttons in your lib? I'd like to use the official libraries so it is easy to compile the app :)

lemmingDev commented 3 years ago

I can add them: 0x3D = Start 0x3E = Select

What did you want to do with the PS button?

According to HID Usages document: 0x84 = System Context Menu 0x85 = System Main Menu 0x86 = System App Menu

aguaviva commented 3 years ago

I wanted to map the PS button to the KEYCODE_BUTTON_MODE

https://www.android-doc.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_MODE

This key code is what brings up the emulator menu in Lemuroid, but I couldn't figure out its HID code in the documentation. That is why I tried the above codes but not luck. Anyway later I discovered I could bring up this menu by pressing select and play, so that is what I do.

lemmingDev commented 3 years ago

Let me know if you nut it out

lemmingDev commented 3 years ago

Are you sure the OS / Application doesn't automatically assign those buttons based on the button numbering

Eg - button 1 = A / Cross button 2 = B / Circle button 3 = X / Square button 4 = Y / Triangle button 5 = LB button 6 = RB button 7 = LT button 8 = RT button 9 = Select button 10 = Start button 11 = L3 button 12 = R3 button 13 = Pad Up button 14 = Pad Down button 15 = Pad Left button 16 = Pad Right

lemmingDev commented 3 years ago

Looks like the xbox controllers might map the menu button

https://github.com/ViGEm/ViGEmBus/issues/40

FANHXIN commented 3 years ago

Bleh and BT classic serial coexist, I also want to know

FANHXIN commented 3 years ago

Hi ! lemmingDev

https://github.com/espressif/arduino-esp32/issues/1150

Looks like it's solved. Check it out

FANHXIN commented 3 years ago

$L{`1_7YE{5 U0RZP~N$Y%H

aguaviva commented 3 years ago

Are you sure the OS / Application doesn't automatically assign those buttons based on the button numbering

No it doesn't, you need to annotate buttons in the descriptor

Anyway, I am following this thread and I am excited to see you are making progress.

BTW I am these days playing Zelda on my cellphone with the PS3 controller and I am having a blast, your lib rocks! :)

FANHXIN commented 3 years ago

@aguaviva It seems that u are a game love

u can search for gimx, which might help u

@lemmingDev If u add the functionality of gimx to your library, it's great

Dreams r beautiful, reality is always cruel

lemmingDev commented 2 years ago

Version 4.0 has start and select buttons as requested