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

Gamepad settings

How to add Options › Gamepad on top of the keyboard menu: the same code for both devices, conflicts that know A means Ollie when skating and Accept in menus, and a prompt that listens to the controller.

GoalRebind any controller button, two per action, without breaking menu navigation for the person holding the controller.
Options › Gamepad: same menu script as the keyboard one, with Xbox names and icons.
Options › Gamepad: same menu script as the keyboard one, with Xbox names and icons.

1One binding engine, two device tables

p_keybindings became p_bindings: a table per device, plus where each action works.

diffWn32/Code/Plat/Sys/SIO/p_bindings.h · working tree
new fileWn32/Code/Plat/Sys/SIO/p_bindings.cpp

2Conflicts only where actions meet

excerptWn32/Code/Plat/Sys/SIO/p_bindings.cpp

Keyboard actions are all mBIND_ANYWHERE, so for keys this collapses to "one key, one action". Same code, two personalities.

3Rewrite the controller reader around bindings

Every input (buttons and both triggers) is read into a per-port table with its context; actions decide the PS2 bits. On a trigger, nollie/switch still press both halves only when pulled past halfway, like the Xbox.

diffWn32/Code/Plat/Sys/SIO/p_siodev.cpp · working tree

4Listen to the controller: fresh presses only

The A you pressed to open the prompt is still down when it opens. Only a button that goes down after counts; everything held is blocked until released. Start cancels, like Escape on the keyboard, and isn't bindable for that reason.

diffWn32/Code/Plat/Sys/SIO/p_siodev.cpp · working tree

First version captured the A that opened the prompt. Every action got bound to A. Very consistent. Very useless.

5Rescue Select

Back used to send Select, which looked unused until panelstuff.q turned up: { pad_select goal_retry_select_handler }. It's the quick goal retry. It became an action (and a keyboard action too, unbound by default).

6One menu script for both devices

Script functions take a device; the menu sets a global and the same rows, prompt and dialogs serve both. X (Square in menus) clears the selected slot, so controller-only players can unbind too.

diffScripts/patches/levels/mainmenu/mainmenu_scripts.q · working tree
configGame/config.ini