Skip to content

macOS gamepad support#756

Closed
kotleni wants to merge 18 commits intoLizardByte:nightlyfrom
kotleni:macos-gamepad-support
Closed

macOS gamepad support#756
kotleni wants to merge 18 commits intoLizardByte:nightlyfrom
kotleni:macos-gamepad-support

Conversation

@kotleni
Copy link

@kotleni kotleni commented Jan 11, 2023

Description

Implemented gamepad support on macOS. This works with my driver for virtual HID devices (you can copy this repository for yourself, the code is not licensed). Vibration not supported. I also added the IOKit dependency (shipped with Xcode).

Sunshine host tested on Macbook Air M1 (2020).
Tested on two clients (Moonlight-nx (Nintendo Switch), and Moonlight (iOS)).

Screenshot

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@CLAassistant
Copy link

CLAassistant commented Jan 11, 2023

CLA assistant check
All committers have signed the CLA.

Copy link
Collaborator

@cgutman cgutman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kexts require some special signing entitlements, right?


// Map triggers
if(gamepad_state.lt > 0) gamepad.buttons |= GAMEPAD_BTN_LT;
if(gamepad_state.rt > 0) gamepad.buttons |= GAMEPAD_BTN_RT;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to emulate these with analog axes? Digital triggers are problematic for driving games and other games where precise trigger control is required.

Copy link
Author

@kotleni kotleni Jan 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that now I can implement analog support. Maybe I might do it in the future.

Copy link
Author

@kotleni kotleni Jan 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, I don't have device with analog trigger, for testing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. See comments in PR.

}

// Fill up the input arguments.
virtgamepad_input[0] = (uint64_t)strdup(VIRTGAMEPAD_NAME); // device name
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like your driver is identifying the gamepads by name. Can we concatenate the nr parameter to the hardcoded name or something to support multiple gamepads?

Copy link
Author

@kotleni kotleni Jan 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name can be changed, it's dynamic. (It's not a inditifier)

@kotleni
Copy link
Author

kotleni commented Jan 12, 2023

Kexts require some special signing entitlements, right?

Yes, you need be identified developer (100$ per year), but it's needed only for building.
But I have public release on GitHub. release

@kotleni
Copy link
Author

kotleni commented Jan 12, 2023

Analog triggers don't work (I just emulate digital triggers). I will make another PR in the future with support for analog triggers.

@ReenigneArcher
Copy link
Member

Thank you for this PR! It might take me a few days to get this merged.

In the meantime can you update the documentation?

  • remove statements that gamepad doesn't work on macOS
  • add statements to usage and troubleshooting (similar to windows) about how to use gamepads on macOS

In your other repo, please improve the installation instructions for someone who would install the release version.

I'd like to have a few macOS users test this as well before it's merged.

@kotleni
Copy link
Author

kotleni commented Jan 13, 2023

@ReenigneArcher
I did it.

Due to the complexity of installing kernel extensions, this will be a problem for normal users.
For advanced users, this shouldn't be a problem.

@brad-richardson
Copy link
Contributor

What kind of game compatibility do you expect from this? When I looked at adding controller support previously it seemed like games either had to 1) explicitly look for your controller (so needed to emulate something popular like 360/ps4 controllers) or 2) use GCController (which we can’t provide a source input for). I know very little about this space but would like to learn.

Awesome work though, I’ll take it for a spin this weekend!

@kotleni
Copy link
Author

kotleni commented Jan 13, 2023

@brad-richardson
I guess macOS games use GameController to implement gamepad support. If so, then there will be no problems with support.
All games launched through Steam work fine. I've tested a couple more games/apps outside of Steam, they work great too.
Regarding the emulation of popular gamepads, this is really possible. Perhaps in the future (if necessary) we will do this.

It needs testing by other users.

Copy link
Member

@ReenigneArcher ReenigneArcher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add:

notes-append "For gamepad support, install VirtualHID from 'https://github.com/kotleni/VirtualHID-macOS/releases/latest'

to the Portfile, just before the final note with the documentation link.

@kotleni
Copy link
Author

kotleni commented Jan 14, 2023

@ReenigneArcher
Done.

@brad-richardson
Copy link
Contributor

I tried this out and wasn't able to get it working. I only see "Gamepad: Unable to open IOService" when I run sunshine.

I took a couple of additional steps that I suspect are unique to M1 macs or macOS 13:

  1. It only showed a prompt to load the extension if I ran the installer script while the settings app was already opened to privacy & security
  2. When I attempted to load the extension (with SIP already disabled) it said I had to enable an additional setting in recovery mode. This was at Utilities -> Startup Security -> "Allow user management of kernel extensions"

Even after "enabling" the extension and restarting as prompted it seems to not have taken effect - eg kextstat | grep virthd returns nothing.

I think this is fine to ship as is for a first pass, especially if you think this could be a known problem for arm macs or the new OS. I would be interested in debugging further though

@kotleni
Copy link
Author

kotleni commented Jan 15, 2023

I tried this out and wasn't able to get it working. I only see "Gamepad: Unable to open IOService" when I run sunshine.

I took a couple of additional steps that I suspect are unique to M1 macs or macOS 13:

  1. It only showed a prompt to load the extension if I ran the installer script while the settings app was already opened to privacy & security

  2. When I attempted to load the extension (with SIP already disabled) it said I had to enable an additional setting in recovery mode. This was at Utilities -> Startup Security -> "Allow user management of kernel extensions"

Even after "enabling" the extension and restarting as prompted it seems to not have taken effect - eg kextstat | grep virthd returns nothing.

I think this is fine to ship as is for a first pass, especially if you think this could be a known problem for arm macs or the new OS. I would be interested in debugging further though

I tested on the same configuration.

The second point is normal behavior, macOS says about it - that's why I did not write about it in the instructions.

Have you tried re-running the installer after the system has restarted? Did the Apple logo flicker a couple of times on reboot?

@kotleni
Copy link
Author

kotleni commented Jan 16, 2023

@ReenigneArcher Done.

@kotleni
Copy link
Author

kotleni commented Jan 17, 2023

Okay

@brad-richardson
Copy link
Contributor

@kotleni Your release installer.py doesn't have a valid download URL on GITHUB_RELEASE, I assume you meant to add VERSION within the {}. It would be good to output the logs from the subprocess calls there to make it easier to debug. I followed the steps manually, here's my error log at the load step:

Executing: /usr/bin/kmutil load -p /Users/brad/Downloads/VirtualHID.kext
Error Domain=KMErrorDomain Code=30 "Validating extension failed: Kext it.kotleni.virthid v1.0.0d1 in executable kext bundle it.kotleni.virthid at /Users/brad/Downloads/VirtualHID.kext:

Filesystem error: Invalid permissions 664 on /Users/brad/Downloads/VirtualHID.kext/Contents/_CodeSignature/CodeResources: should not be group/other writable
Filesystem error: Invalid permissions 664 on /Users/brad/Downloads/VirtualHID.kext/Contents/MacOS/VirtualHID: should not be group/other writable
Filesystem error: Invalid permissions 664 on /Users/brad/Downloads/VirtualHID.kext/Contents/Info.plist: should not be group/other writable" UserInfo={NSLocalizedDescription=Validating extension failed: Kext it.kotleni.virthid v1.0.0d1 in executable kext bundle it.kotleni.virthid at /Users/brad/Downloads/VirtualHID.kext:

Filesystem error: Invalid permissions 664 on /Users/brad/Downloads/VirtualHID.kext/Contents/_CodeSignature/CodeResources: should not be group/other writable
Filesystem error: Invalid permissions 664 on /Users/brad/Downloads/VirtualHID.kext/Contents/MacOS/VirtualHID: should not be group/other writable
Filesystem error: Invalid permissions 664 on /Users/brad/Downloads/VirtualHID.kext/Contents/Info.plist: should not be group/other writable}

Is it not properly signed? Did I do something bad with the permissions?

@kotleni
Copy link
Author

kotleni commented Jan 17, 2023

@brad-richardson
Hello. It's error looks like wrong permissions.
You chowned kext folder recursively? (sudo chown -R root:wheel ./VirtualHID.kext)
And you have disabled SIP in system?

@brad-richardson
Copy link
Contributor

You chowned kext folder recursively?
And you have disabled SIP in system?

Screenshot 2023-01-17 at 6 50 06 PM

@kotleni
Copy link
Author

kotleni commented Jan 18, 2023

@brad-richardson

Try it: sudo chmod -R 777 ./VirtualHID.kext

@kotleni
Copy link
Author

kotleni commented Jan 18, 2023

@brad-richardson
And about installer.py
It's works for me. Link is valid, because version puted later in url = GITHUB_RELEASE.format(VERSION)

@brad-richardson
Copy link
Contributor

Yeah my bad, I missed the format below. I fixed the file permission issues by just copying into /tmp first like you do in your script.

I'm able to load the extension then enable and reboot like it instructs, but the extension is still just not there after I login. Any other ideas?

@brad-richardson
Copy link
Contributor

I don't want to derail this PR, are you in the LizardByte discord? I'm interested in your thoughts on https://support.apple.com/guide/deployment/system-and-kernel-extensions-in-macos-depa5fb8376f/web. It seems like Apple is headed for removal of kexts entirely but I wonder if it would be possible to package your kext as part of the Sunshine install

@kotleni
Copy link
Author

kotleni commented Jan 18, 2023

@brad-richardson Yes, I joined to server now, find me in off topic channel.

@kotleni
Copy link
Author

kotleni commented Jan 18, 2023

@brad-richardson Try kextstat | grep -v com.apple for printing all enabled kexts. This output have it.kotleni.virthid?

@ReenigneArcher ReenigneArcher added the help wanted Extra attention is needed label Jan 25, 2023
@ReenigneArcher ReenigneArcher marked this pull request as draft January 25, 2023 22:23
@ReenigneArcher

This comment was marked as outdated.

@briankendall
Copy link
Contributor

I can add that switching away from using a kext and to DriverKit system extension would allow users of modern macOS to install the driver without needing to disable SIP, rebooting, or otherwise change the security settings of their mac. The only thing they'd need to do is authorize loading the system extension in the System Preferences / Settings app.

Unfortunately this is Apple, so of course there are developer-hostile restrictions to doing this. It requires a paid developer account on top of having to ask for special permission from Apple to use the entitlement that grants an app permission to load a dext. The dext also needs to be bundled with a specific app, even if it's intended to be used across multiple apps. But getting over these hurdles will make it much more accessible to normal users.

@LizardByte-bot
Copy link
Member

This PR is stale because it has been open for 90 days with no activity. Comment or remove the stale label, otherwise this will be closed in 10 days.

@classicalwow
Copy link

@kotleni hi,did the kext support x64 gamepad? i install the kext,but not work

@kotleni
Copy link
Author

kotleni commented Jul 1, 2023

@classicalwow It never worked out for me, my implementation doesn't work properly, I stopped trying to implement it.

P.S. Special thanks to Apple. 💩

@classicalwow
Copy link

classicalwow commented Jul 4, 2023

image @kotleni excuse me, I really want to use this feature,i install the kexts and build kotleni:macos-gamepad-support from source,but got wrong,help me,plz.

kextstat | grep -v com.apple

   64    0 0xffffff8005d0f000 0x16000    0x16000    it.kotleni.virthid (1.0.0d1) 0270B242-FC62-3136-9873-64DBB4E19075 <63 7 6 3>

@kotleni
Copy link
Author

kotleni commented Jul 5, 2023

@classicalwow Yes, this is main problem with my implementation.
Unresolved bug in kernel extension :<

@kotleni kotleni closed this by deleting the head repository Aug 14, 2023
@iMonZ
Copy link

iMonZ commented Sep 30, 2023

Is there another option to implement gamepad support for sunshine?

@kotleni
Copy link
Author

kotleni commented Oct 3, 2023

@iMonZ Idk. Maybe we can use Steam Input (but it's not documented). :o

@iMonZ
Copy link

iMonZ commented Oct 17, 2024

@kotleni Could it be that kext were deprecated by macOS?
Could we maybe use SystemExtensions to implement this?
Otherwise its still possible to use kext but you need to disable a setting in the BIOS. So we could at least make just a proof of concept

@kotleni
Copy link
Author

kotleni commented Oct 17, 2024

@kotleni Could it be that kext were deprecated by macOS?
Could we maybe use SystemExtensions to implement this?
Otherwise its still possible to use kext but you need to disable a setting in the BIOS. So we could at least make just a proof of concept

Hey. Idk what is "System extension", but my kext was very unstable.
macOS don't want to load it for some users, or it's can be loaded only once. And it's hard to debug this, bcs I don't see any logs in kernel messages :)

So, maybe u need to recheck it? 🤔

@thealonealex
Copy link

is this something that still exists? I would love to test it!

@ReenigneArcher
Copy link
Member

ReenigneArcher commented Dec 9, 2024

No, but it might be easier to implement this now: https://developer.apple.com/documentation/gamecontroller/gcvirtualcontroller?language=objc

@kayakyakr
Copy link

No, but it might be easier to implement this now: https://developer.apple.com/documentation/gamecontroller/gcvirtualcontroller?language=objc

Seems to be targetted to creating a controller in iOS. Wouldn't necessarily be able to give us a controller on mac.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.