Skip to content

Commit 638db72

Browse files
committed
fix: cap evshim's vjoy count to currently-connected controllers
EVSHIM_MAX_PLAYERS was hardcoded to WinHandler.MAX_PLAYERS (=4), so evshim always registered four SDL virtual joysticks regardless of how many physical controllers were actually connected. Games (ToS, etc.) would see one or more phantom unbound gamepads — they didn't respond to input because no slot had a controller, and rumble routed at them went nowhere because getControllerForSlot returned null. Cap to controllerManager.getDetectedDevices().size() with a floor of 1 so the virtual on-screen gamepad still has a vjoy when no physical controller is present at launch. Mem files for all four slots are still pre-created; only the SDL vjoy registration is bounded.
1 parent 2f045e3 commit 638db72

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

app/src/main/java/com/winlator/xenvironment/components/BionicProgramLauncherComponent.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,7 @@ private int execGuestProgram() {
181181

182182
// Always pre-create all 4 mem files so controllers can be hot-plugged during gameplay.
183183
// Unused gamepads just read zeroes (no-op in evshim).
184-
final int enabledPlayerCount = WinHandler.MAX_PLAYERS;
185-
for (int i = 0; i < enabledPlayerCount; i++) {
184+
for (int i = 0; i < WinHandler.MAX_PLAYERS; i++) {
186185
String memPath;
187186
if (i == 0) {
188187
// Player 1 uses the original, non-numbered path that is known to work.
@@ -223,7 +222,16 @@ private int execGuestProgram() {
223222

224223
EnvVars envVars = new EnvVars();
225224

226-
// Use the ControllerManager's dynamic count for the environment variable
225+
// Tell evshim how many SDL virtual joysticks to register, capped at the count of
226+
// currently-detected physical controllers. Without the cap we'd always spawn
227+
// MAX_PLAYERS vjoys regardless of how many were connected, and games (e.g. ToS
228+
// controller tester) would see phantom unbound gamepads — they don't respond to
229+
// input and rumble routed at them goes nowhere. Floor at 1 so the virtual
230+
// on-screen gamepad still has a vjoy when no physical controller is present.
231+
final int connectedControllerCount =
232+
com.winlator.inputcontrols.ControllerManager.getInstance().getDetectedDevices().size();
233+
final int enabledPlayerCount =
234+
Math.max(1, Math.min(connectedControllerCount, WinHandler.MAX_PLAYERS));
227235
envVars.put("EVSHIM_MAX_PLAYERS", String.valueOf(enabledPlayerCount));
228236
if (true) {
229237
envVars.put("EVSHIM_SHM_ID", 1);

0 commit comments

Comments
 (0)