JibbSmart / JoyShockLibrary

Read DualSense, DualShock 4, JoyCon, and Pro Controller input on PC -- compiled for Windows, but code should work on other platforms.
Other
240 stars 48 forks source link

How can you tell when a new controller is connected at runtime? #51

Open gordonglas opened 2 years ago

gordonglas commented 2 years ago

Hi, I'm wondering how you can use JSL to tell when a new controller is connected during a game. Or is it assumed that you must have everything connected before initializing JSL?

JibbSmart commented 2 years ago

Hi! It currently isn't really set up for detecting connections made on the fly, I'm afraid. Obviously detecting controllers connected after your game/application starts is important. The current way to do it with JSL is probably to have a "detect controllers" button in your settings, and do this repeatedly automatically when there are no controllers connected (or at the "press start" screen when no one has pressed "start" yet)

gordonglas commented 2 years ago

Thanks! I thought of handling it that way (with some sort of detect controllers button). Then I looked deeper at the JSL code and the HID API it uses, and unless I'm missing something or not understanding it, I think I should be able to fork it and modify it (add new functions is probably best in my case) to get it working based on the HID device path (the path appears to be unique across multiple controllers of the same type hooked into different USB ports - I just tested that with multiple DS4s, and seems true - But I don't know what it looks like for Bluetooth yet.) I'm not sure how efficient it would be to call hid_enumerate in the game loop (or maybe I can limit it to every x milliseconds), then compare the device paths it finds with the paths of devices "already connected", then only hid_open_path the devices that are new.

Let me know if you already know this wouldn't work. It would save me some time. :) Thanks for a great library!

JibbSmart commented 2 years ago

Oo, that does sound promising! If you do find some success with it, I'd love it if you could make a PR and it could be included in JSL. I have no idea about performance implications, but it's worth exploring

CasperH2O commented 1 year ago

Hey @gordonglas , this indeed a great feature to have. @Valkirie and me would also like this added in JSL to make use of it within our open source project called Handheld Companion.

Has it already piqued your technical curiosity enough to make a start?

gordonglas commented 1 year ago

Hi @CasperH2O !, I have started it, but I've been slowed down quite a bit because my whole family got sick, there's a lot going on because of the holidays, and I also have a full-time job. I'll hopefully have more time for it soon, because I have my own aspirations to get my game engine going, but I can't really give any ETA with everything that's going on. I'll try to update here when I've made more progress.

gordonglas commented 1 year ago

Just a quick update.

Unfortunately, calling hid_enumerate every game loop frame destroys the framerate, (and all my test app is doing is rendering the FPS - it has no logic/rendering.) Even calling hid_enumerate every second or so could cause very noticeable stutter in gameplay.

The real solution is to call hid_enumerate in a separate thread, but making everything thread-safe (particularly the JoyShock objects) is a whole other issue, and not a quick and easy task. Big changes like this will most likely require a major version increment or fork. I do plan on giving it a try though, so I'll update again when I'm further along. No ETA, unfortunately.

JibbSmart commented 1 year ago

Hi @gordonglas, just a heads-up that I'm exploring a solution for JoyShockLibrary 3.0. Current strategy is making everything thread safe and making it so that JslConnectDevices doesn't create new ids for already-connected devices.

At this stage, JoyShockLibrary likely won't handle automatic detection for the user. But the separate thread is a workable strategy with this change to JslConnectDevices. The best solution probably depends on the OS -- on Windows, watch for WM_DEVICECHANGE events and call JslConnectDevices then. It could even be kicked off on another thread to avoid hitching.

nefarius commented 1 year ago

Shameless plug 😛

EDIT: meh, I need more coffee, this isn't a C# project, but you can use the code as inspiration 😅

JibbSmart commented 1 year ago

@nefarius, your plug is welcome, and this is a good example of where a user might listen for a connection and call JslConnectDevices. In my tests, just calling JslConnectDevices on WM_DEVICECHANGE also seems to be working fine :)

(JSL example using Dear Imgui)