Home Projects Contact Me

ThumbTwister


Role: Solo Developer

Description: ThumbTwister is a lightweight background service that intercepts and rotates your physical thumbstick inputs before passing the rotated inputs to a virtual controller, ensuring all your games and applications read the rotated inputs without detecting your physical hardware.

  • Automatic Setup: I made an installer using Inno Setup Compiler and an Inno Setup Script. The setup script defines the installation directories, the exact files to include, registry modifications, and post install commands. The compiler reads the .iss file and fetches the staged ThumbTwister.exe, necessary runtime libraries, and UI assets before compressing and wrapping them along with an extraction stub, into a single executable.
    The installer requests admin privileges via UAC, which is required to install pre-requisites to protected directories and modify the system registry to allow drivers to register themselves as services, write uninstallation metadata and configure the HID whitelist. It executes bundled driver setups using silent command line arguments ensuring the required environment is present before the application runs. It creates start menu or desktop shortcuts and writes the application's metadata to the Windows Registry, finally generating an unins000.exe and unins000.dat file in the installation directory.

  • HID Hiding: I integrated HidHide, a kernel-level filter to isolate the physical controller from the rest of the operating system. When ThumbTwister launches, it programmatically interfaces with HidHide's command-line executable to automatically enable a global device cloak.
    It intercepts enumeration requests to the Windows HID stack. It blacklists the physical controller's Hardware Instance ID so that game engines and platforms like Steam cannot detect the raw hardware. Simultaneously, the driver whitelists the ThumbTwister.exe application path. This allows ThumbTwister to maintain read access to the raw hardware input data via the Microsoft GameInput API. By blinding the OS to the physical device, games are forced to exclusively read the rotated inputs from the virtual Xbox 360 controller.

  • Calibration Engine: I built a custom calibration engine to dynamically calculate the physical angular offset of the user's thumbs. When activated, the engine prompts the user to push the thumbstick in four cardinal directions (Up, Down, Left, Right). To ensure genuine data collection, the engine employs a validation algorithm to randomise the requested directions while preventing predictable geometric arcs.
    The engine captures Cartesian (X, Y) coordinates once the stick exceeds a 90% magnitude threshold. It normalises these input vectors and calculates the cosine and sine components between the user's physical push and the ideal vector. These values are averaged across all samples and converted back into a polar angle using atan2f to derive the rotational offset in degrees. This final offset is then continuously applied to the input stream via a 2D rotation matrix before being passed to the virtual controller.

  • Virtual Controller: I implemented the ViGEmClient library to interface with the ViGEmBus kernel driver, allowing the application to spawn a virtual controller. This serves as the final output destination for the read-translate-inject pipeline.
    After the GameInput API reads the physical device and the calibration engine applies the rotational offset, the resulting float values are mathematically clamped and scaled into standard 16-bit signed integers (SHORT). Simultaneously, a bitwise translation converts the physical input button and trigger states into the required XUSB_REPORT format. This data packet is continuously injected into the virtual target, creating a system-wide emulation of a physical controller outputting the corrected thumbstick data.

  • Visualiser: The visualiser was built using Raylib and Raygui to provide a realtime graphical representation of both the raw physical inputs and the adjusted virtual outputs. It features dynamic scaling and interactive UI components to track the calibration process or manually adjust offsets via sliders.

ThumbTwister is a project that I started due to a friend of mine who would not stop complaining about dying in Hollow Knight because his "thumbs are too long, causing imprecise directional input" (his thumbs are fine, he is just bad at the game). It did get me thinking though, that ThumbTwister could come to serve as an efficent, open-sourced accessibility tool. With this in mind, I plan to make continous improvements to the project over time, and welcome anyone else that wishes to do the same.