Skip to content

Commit e96ae4e

Browse files
Ripper MoonRipper Moon
authored andcommitted
Release v1.2.25 enable SDL game-controller backend per prefix
Xbox/PlayStation controllers enumerated under GPTK (they showed up in Steam and in games) but delivered no input: macOS's GameController framework takes exclusive ownership of those pads (UsbExclusiveOwner in ioreg), which starves Wine's default raw-HID backend. Affects USB and Bluetooth alike and is independent of Steam Input. Wine's SDL backend reads the pad through the same macOS framework cooperatively, so input reaches games. - gptk_apply_input_backend sets winebus "Enable SDL"=1 in a prefix, once, via a per-prefix marker; the value loads when the prefix's wineserver next starts. - gptk-launch applies it on every launch (covers existing prefixes) and again after wineboot on --init (covers freshly created ones). - GPTK_CONTROLLER_SDL (default 1) gates it; documented in env.example, README, and docs/steam.md with the macOS exclusive-grab explanation.
1 parent 027f3a5 commit e96ae4e

6 files changed

Lines changed: 48 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ The screenshots show the launcher profile and a live Elden Ring GPTK run. See [d
5151
- `gptk-stubs`: cross-compiles and installs minimal stub DLLs for Wine/GPTK missing APIs (GameInput, etc.) so delay-load crashes are resolved without touching game files.
5252
- `gptk-dsound-nocap`: installs a DirectSound no-capture forwarder into a prefix (and sets the Wine override) so Steam Voice cannot stall the Elden Ring ERSC Golden Pot lobby. It forwards to the prefix's own dsound and redistributes nothing copyrighted.
5353
- `gptk-steam-layout`: assigns a Steam Input controller layout (`.vdf`) to a Steam app id by writing the selection into the prefix's controller config sets, so a layout applies even though Steam's in-client configurator renders blank under GPTK. Steam must be stopped; config sets are backed up before editing.
54+
- SDL game-controller backend enabled per prefix so Xbox/PlayStation pads actually deliver input under GPTK (macOS exclusively claims those controllers, which starves Wine's default raw-HID backend). Toggle with `GPTK_CONTROLLER_SDL`.
5455
- Dynamic path configuration through `~/.rippermoon-gptk.env`.
5556
- Configurable Wine drive mappings with any letters except `C:`.
5657
- Installer bootstrap with timestamped logs.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.2.24
1+
1.2.25

bin/gptk-launch

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,15 @@ gptk_configure_environment "${prefix_path}"
151151
[[ -n "${log_file}" ]] || log_file="$(gptk_log_file "${prefix_name}")"
152152
gptk_note "open-file limit ${GPTK_EFFECTIVE_NOFILE_LIMIT:-$(ulimit -n 2>/dev/null || print unknown)}"
153153

154+
# Ensure the SDL game-controller backend on existing prefixes (runs once).
155+
gptk_apply_input_backend "${prefix_path}"
156+
154157
if [[ "${do_init}" == "1" ]]; then
155158
gptk_note "initializing prefix ${prefix_path}"
156159
gptk_run_logged "${log_enabled}" "${log_file}" gptk_run_tool wineboot -u
157160
gptk_link_configured_drives "${prefix_path}"
161+
# New prefixes have a windows dir only after wineboot, so apply it here too.
162+
gptk_apply_input_backend "${prefix_path}"
158163
fi
159164

160165
if [[ -n "${set_winver}" ]]; then

docs/steam.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,11 @@ From the GUI:
124124
3. Pick the game and click **Add**. It appears as a tile; its **Launch** button starts Steam and the game in one click.
125125

126126
You can also set a profile's **Steam App ID** by hand in App Settings to make any profile launch this way. The download path itself prefers the internal `S:` library; a Steam library on an external drive that unmounts mid-download is the usual cause of "Unpack failed" content errors.
127+
128+
## Controllers don't respond in games
129+
130+
If a controller shows up in Steam and in the game's settings but does nothing when you press buttons, the cause is macOS, not Wine. macOS's GameController framework takes **exclusive ownership** of Xbox and PlayStation pads (visible as `UsbExclusiveOwner` in `ioreg`), which starves Wine's default raw-HID backend — the pad enumerates (so it appears everywhere) but no button or stick input reaches the game. This affects USB and Bluetooth equally and is independent of Steam Input.
131+
132+
RipperMoonKit fixes this by enabling Wine's **SDL controller backend** per prefix (`winebus` `Enable SDL`), which reads the pad through that same macOS framework cooperatively, so input flows to games. It is applied automatically the first time a prefix is launched (and on prefix init), and loads when the prefix's Steam/Wine next starts. Set `GPTK_CONTROLLER_SDL=0` in `~/.rippermoon-gptk.env` to opt out.
133+
134+
To apply it immediately to a prefix that is already running, close Steam/the game so the Wine driver reloads, then launch again. A controller that still works through Steam Input but not natively is a separate, game-specific issue.

env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ export GPTK_NOFILE_LIMIT="49152"
3434
export GPTK_DXR="1"
3535
export GPTK_USE_DXVK="0"
3636
export GPTK_MTL_HUD_ENABLED="0"
37+
# Read game controllers through Wine's SDL backend so input reaches games.
38+
# macOS exclusively claims Xbox/PlayStation pads, which starves the default
39+
# raw-HID backend (the pad enumerates but sends no input). Set to 0 to opt out.
40+
export GPTK_CONTROLLER_SDL="1"
3741

3842
# Installer bootstrap defaults.
3943
export STEAM_SETUP_URL="https://cdn.akamai.steamstatic.com/client/installer/SteamSetup.exe"

libexec/gptk-common.zsh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ gptk_init_defaults() {
8383
GPTK_STEAM_PREFIX
8484
GPTK_STEAM_LEGACY_CEF
8585
GPTK_STEAM_RESET_WEBHELPER_CACHE
86+
GPTK_CONTROLLER_SDL
8687
)
8788
typeset -A env_overrides=()
8889

@@ -118,6 +119,7 @@ gptk_init_defaults() {
118119
export GPTK_METALFX="${GPTK_METALFX:-0}"
119120
export GPTK_ADVERTISE_AVX="${GPTK_ADVERTISE_AVX:-0}"
120121
export GPTK_NOFILE_LIMIT="${GPTK_NOFILE_LIMIT:-49152}"
122+
export GPTK_CONTROLLER_SDL="${GPTK_CONTROLLER_SDL:-1}"
121123
}
122124

123125
gptk_find_wine_home() {
@@ -312,6 +314,33 @@ gptk_log_file() {
312314
print -r -- "${GPTK_LOG_DIR}/${prefix_name}-${stamp}.log"
313315
}
314316

317+
# Make Wine read game controllers through the SDL backend. macOS's GameController
318+
# framework takes exclusive ownership of Xbox/PlayStation pads, which starves
319+
# Wine's default raw-HID backend: the controller enumerates (so it shows up in
320+
# games and Steam) but delivers no button/stick input. The SDL backend reads the
321+
# pad through that same framework cooperatively, so input actually reaches games.
322+
# Applied once per prefix (marker-guarded); the value loads when the prefix's
323+
# wineserver next starts. Disable with GPTK_CONTROLLER_SDL=0.
324+
gptk_apply_input_backend() {
325+
local prefix_path="$1"
326+
if [[ "${GPTK_CONTROLLER_SDL:-1}" != "1" ]]; then
327+
return 0
328+
fi
329+
if [[ ! -d "${prefix_path}/drive_c/windows" ]]; then
330+
return 0
331+
fi
332+
local marker="${prefix_path}/.gptk-input-backend-sdl"
333+
if [[ -e "${marker}" ]]; then
334+
return 0
335+
fi
336+
if gptk_run_tool reg add "HKLM\\System\\CurrentControlSet\\Services\\winebus" \
337+
/v "Enable SDL" /t REG_DWORD /d 1 /f >/dev/null 2>&1; then
338+
: > "${marker}"
339+
gptk_note "enabled SDL game-controller backend for ${prefix_path:t}"
340+
fi
341+
return 0
342+
}
343+
315344
gptk_run_logged() {
316345
local log_enabled="$1"
317346
local log_file="$2"

0 commit comments

Comments
 (0)