For education purposes only · no game files included · bring your own THUG
Guide 09

Controllers

How SDL game controllers became the game's pads: hotplugging into free ports, the macOS "same controller twice" quirk, the Xbox layout, and rumble.

GoalPlug in a controller any time: the first one plays with the keyboard as player 1, a second one is player 2, and it vibrates.

1Hotplug into the first free port

Each frame, port 0's device closes unplugged controllers and opens new ones into the first free port.

new fileWn32/Code/Plat/Sys/SIO/p_siodev.cpp · a4cac21

2Dodge the macOS double

A controller connected at launch shows up twice: via the IOKit driver (has a device path, gets no input) and the GameController framework (no path, works). Keep the one that works.

new fileWn32/Code/Plat/Sys/SIO/p_siodev.cpp · a4cac21

Symptom: controller connected, LED on, game connected to it, zero input. The game was talking to the evil twin.

3Speak Xbox to a PS2 engine

The game runs its Xbox controls on PS2-shaped data. Triggers use the Xbox thresholds (pressed at 0x20, "full" at 128 of 255); sticks map from ±32767 to 0–255 with 0x80 centred.

excerptWn32/Code/Plat/Sys/SIO/p_siodev.cpp
ButtonSkatingMenusCreate-A-Park
A / X / B / Yollie / flip / grab, talk / grindaccept / delete letter / back / spaceplace / rotate / rotate / delete
LT / RTnollie, spin left / switch, spin right (pull fully for both)L1 / R1lower / raise
LB / RBget off / back on board (caveman)–zoom in / out
Back / Startretry goal / pauseback / –– / pause

All but Start, the D-pad and the sticks are rebindable: Gamepad settings.

4Rumble

Two actuators, like the Xbox pad. The strength is re-sent every frame with a short duration, so loading screens (when the game stops updating) don't leave the controller buzzing forever.

diffWn32/Code/Plat/Sys/SIO/p_siodev.cpp · a4cac21

* 257: 255 × 257 = 65535. The cheapest exact 8-to-16-bit scale there is.

5Say which joysticks don't count

diffWn32/Code/Plat/Sys/SIO/p_sioman.cpp · a4cac21

The old log line also opened every controller just to print its player index. A leak dressed as a debug print.