SDL icon indicating copy to clipboard operation
SDL copied to clipboard

PS3 gamepads do not work with macOS 12

Open vit9696 opened this issue 2 years ago • 14 comments

As of macOS 12.0.1 HID controllers are recognised but fail to provide any input to macOS. In particular, IOHIDDeviceRegisterInputValueCallback/IOHIDDeviceRegisterInputReportCallback apparently never call callbacks with e.g. Sony DualShock 3, but likely others.

This was originally reported as https://github.com/hrydgard/ppsspp/issues/15112 and sent as FB9745903 to Apple. The simplest project I was able to reproduce it is https://github.com/armadillu/MacJoystickHIDTest.

vit9696 avatar Nov 08 '21 11:11 vit9696

@slouken any comment on this besides the label changes :)? I think implementing direct DS3 HID packet handling on macOS through libusb will likely work, but am unsure whether it is worth the effort.

For rumble purposes it is nice, in the past I did exactly that, but I still left other data like button input to SDL at that time.

vit9696 avatar Nov 08 '21 22:11 vit9696

I don't have a macOS 12 system right now, but I did report it to Apple and they're investigating.

BTW, we don't have HIDAPI support for the DS3, but that's certainly something we can add, if you're interested in contributing it.

slouken avatar Nov 09 '21 06:11 slouken

@slouken I tried libusb router, and it does not seem to be too easy. IOUSBHostHIDDevice.kext owns the USB interface, so libusb_claim_interface would fail. This can be resolved by ensuring libusb_detach_kernel_driver gets called and succeeded: for this one needs to run the app with root privileges. But even in this case I get timeouts.

On the other side, I did find a workaround for the native macOS HID API by reviewing my old code for DS3 dating back to 10.6 days :-) For some reason macOS driver is no longer sending the initialisation sequence for DS3, which is the reason why the gamepad does nothing. I have a suspect this happened before, because I added exactly this code some while ago, though the intent was to support rumbling.

It was enough for me to run the following code to get DS3 working in all applications until replug:

    {
        uint8_t dataBlob[] = { 0x42, 0x0C, 0x00, 0x00};
        IOHIDDeviceSetReport(device, kIOHIDReportTypeFeature, 0xF4, dataBlob, sizeof(dataBlob));
    }

And the following sequence could be used to activate rumble support and additionally disable LEDs.

    {
        uint8_t dataBlob[] = {
            0x01,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00, // rumble values [0x00, right-timeout, right-force, left-timeout, left-force]
            0x00,
            0x00, // Gyro
            0x00,
            0x00,
            0x00, // 0x02=LED1 .. 0x10=LED4
            /*
             * the total time the led is active (0xff means forever)
             * |     duty_length: how long a cycle is in deciseconds:
             * |     |                              (0 means "blink very fast")
             * |     |     ??? (Maybe a phase shift or duty_length multiplier?)
             * |     |     |     % of duty_length led is off (0xff means 100%)
             * |     |     |     |     % of duty_length led is on (0xff is 100%)
             * |     |     |     |     |
             * 0xff, 0x27, 0x10, 0x00, 0x32,
             */
            0xff,
            0x27,
            0x10,
            0x00,
            0x32, // LED 4
            0xff,
            0x27,
            0x10,
            0x00,
            0x32, // LED 3
            0xff,
            0x27,
            0x10,
            0x00,
            0x32, // LED 2
            0xff,
            0x27,
            0x10,
            0x00,
            0x32, // LED 1
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            // Necessary for Fake DS3
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
        };
        static const size_t RumbleLengthL = 4;
        static const size_t RumblePowerL = 5;
        static const size_t RumbleLengthR = 2;
        static const size_t RumblePowerR = 3;
        dataBlob[RumbleLengthL] = dataBlob[RumbleLengthR] = 80;
        dataBlob[RumblePowerL]                            = 255;
        dataBlob[RumblePowerR]                            = 1;
        IOHIDDeviceSetReport(device, kIOHIDReportTypeOutput, 1, dataBlob, sizeof(dataBlob));
    }

Question is, should we integrate it into SDL? This simple set of sequences does not cover everything but is necessary to activate DS3 support on macOS 12.0.1. I attached a small program that can be run once after connecting the gamepad as a workaround…

ds3activate.zip

vit9696 avatar Nov 12 '21 00:11 vit9696

I'm having trouble making an Xbox Wireless Controller work. Could this be related?

kode54 avatar Jan 02 '22 07:01 kode54

Thank you for this! I actually prefer it to the old method, it used to be super finicky to connect.

AlexNelsonMusic avatar Mar 19 '22 07:03 AlexNelsonMusic

I tried running the script OP provided, but the D-Pad is not working, and both triggers appear as permanently pressed. Any ideas on how to tackle that?

crishs2001 avatar Mar 28 '22 07:03 crishs2001

I tried running the script OP provided, but the D-Pad is not working, and both triggers appear as permanently pressed. Any ideas on how to tackle that?

I have the same issue. A fix would be awesome

cortozld avatar Apr 16 '22 12:04 cortozld

both triggers appear as permanently pressed

same issue as well...

andrekandore avatar Apr 17 '22 10:04 andrekandore

I got my Dualshock 3 working using the provided binary, however PCSX2 doesnt seem to support the pressure sensitivity. Don't know if it uses SDL to be honest, anyone know more about this? Tried MGS 2 & 3, cant lower weapons without firing and grabbing an enemy in MGS3 while pressing lightly kills them instead of starting an interrogation.

maciekish avatar Apr 23 '22 20:04 maciekish

can anyone guide me into using ps3 controller on my MacBook? for use with nividia geforce

brroges avatar May 05 '22 18:05 brroges

This makes my DualShock 3 controller usable but it won't stop vibrating. Any workaround for this particular issue?

yeetyeah59 avatar Jun 03 '22 19:06 yeetyeah59

can anyone guide me into using ps3 controller on my MacBook? for use with nividia geforce

@brroges

look above for ds3activate.zip , connect your ps3 controller to your mac (wired), right click the ds3activate file and select open, if it worked, the controller should vibrate, and now it should work!

MilGreat2010 avatar Jun 16 '22 15:06 MilGreat2010

can anyone guide me into using ps3 controller on my MacBook? for use with nividia geforce

@brroges

look above for ds3activate.zip , connect your ps3 controller to your mac (wired), right click the ds3activate file and select open, if it worked, the controller should vibrate, and now it should work!

@vit9696 @danielholmes

Is it normal that it won't stop vibrating?

andrew1-1 avatar Jul 23 '22 11:07 andrew1-1

I tried running the script OP provided, but the D-Pad is not working, and both triggers appear as permanently pressed. Any ideas on how to tackle that?

i have the exact same problem, except that its my two bumpers instead of the triggers. does anyone know how to fix this?

ShadowBullet25 avatar Jul 31 '22 01:07 ShadowBullet25

I've tried the script but my controller doesn't stop vibrating, need to unplug and plug on my cellphone and open octopus to stop. Any idea?

EzeZucchiatti avatar Aug 23 '22 10:08 EzeZucchiatti

Okay, we can't really do tech support on the script, so let's bring this back to an SDL thing:

  • I assume this still isn't supported out of the box on macOS; @slouken mentioned Apple was investigating, but that was a long time ago and as much as I love my PS3 controller, I wouldn't be surprised if they decided it's not worth adding support now that we're two generations of the PlayStation past it.
  • Do we want to add this to SDL's HIDAPI code? I'm totally ignorant of HIDAPI details; doesn't this controller already work with HIDAPI on other platforms, or have we just been relying on the OS to make it work all this time?

icculus avatar Aug 23 '22 16:08 icculus

Sony no longer supports the PS3 controller on PS Now, which is where most people were getting their driver. I looked into adding support to HIDAPI, but I wasn't actually able to read the controller on Windows or macOS for some reason, and Linux drivers are already working fine.

slouken avatar Aug 23 '22 17:08 slouken

I'll take another quick stab at this and see what I can come up with.

slouken avatar Aug 23 '22 17:08 slouken

So, good news, the latest SDL code supports wired PS3 controllers on macOS, thanks @vit9696!

slouken avatar Aug 24 '22 08:08 slouken

So we can close this issue?

icculus avatar Aug 24 '22 13:08 icculus

I want to leave it open for bug reports and the hope that someone can figure out why the controller initialization code doesn't work on Windows.

slouken avatar Aug 24 '22 13:08 slouken

If nothing pops up we can close this before 2.26 release.

slouken avatar Aug 24 '22 13:08 slouken

It's been confirmed that you can't talk to PS3 controllers using stock Windows drivers. This is documented in https://github.com/libsdl-org/SDL/commit/1fc7f681187f80ccd6b9625214b47db665cd9aaf.

slouken avatar Aug 24 '22 13:08 slouken

Confirmed, this works well on macOS for wired PS3 controllers.

slouken avatar Sep 01 '22 14:09 slouken

@slouken I tried libusb router, and it does not seem to be too easy. IOUSBHostHIDDevice.kext owns the USB interface, so libusb_claim_interface would fail. This can be resolved by ensuring libusb_detach_kernel_driver gets called and succeeded: for this one needs to run the app with root privileges. But even in this case I get timeouts.

On the other side, I did find a workaround for the native macOS HID API by reviewing my old code for DS3 dating back to 10.6 days :-) For some reason macOS driver is no longer sending the initialisation sequence for DS3, which is the reason why the gamepad does nothing. I have a suspect this happened before, because I added exactly this code some while ago, though the intent was to support rumbling.

[Snip]

ds3activate.zip

I compiled the source and ran it (m1 MacBook). The controller rumbled but it's not working in Dolphin? cc -framework CoreFoundation -framework IOKit ds3activate.c -o ds3activate

Edit: My arm64 compiled version worked fine playing an SNES game via OpenEMU. I think I got Dolphin to work but I had to remap everything!

ballo avatar Oct 19 '22 04:10 ballo

I connected the controller and turned on ds3activate.zip, and it vibrated. But it doesn't do anything. it says its connected but nothing works and the light is off

Edit: I found out that it works but only if I hold down the ps button

PirateGuy147 avatar Oct 19 '22 20:10 PirateGuy147

ds3activate.zip How do i stop the rumbling?

LeWolfYT avatar Dec 04 '22 13:12 LeWolfYT

This works great! But L2 and R2 are treated like normal buttons so i cannot modulate the pressure, can it be fixed?

MattiaFenzi avatar Apr 19 '23 07:04 MattiaFenzi

It looks like L2 and R2 aren't pressure sensitive in the DS3 controller: https://en.wikipedia.org/wiki/DualShock#DualShock_3

slouken avatar Apr 19 '23 11:04 slouken

Well they are analog, in fact on PS3 and Windows they can be modulated

MattiaFenzi avatar Apr 19 '23 11:04 MattiaFenzi