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

Gamepad settings

Game 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.
Game Options › Gamepad: the same menu script as the keyboard one, with Xbox button names.
Gamepad: the same menu as the keyboard one, with button names.

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 · THUG1 port
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 · THUG1 port

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 · THUG1 port

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.

diffTHUG1 port: Scripts/patches/levels/mainmenu/mainmenu_scripts.q

In THUG2 the same menu script lives in Scripts/patches/scripts/game/menu/gamemenu_options.q, rebuilt with THUG2's menu pieces; see chapter 4.

configGame/config.ini