Skip to main content

GamePad Xinput API

A game controller coded in Rust using Xinput API

info

Author: Dragotă Andrei
GitHub Project Link: https://github.com/UPB-FILS-MA/project-domnudragota

Description

Introduction

A rudimentary GamePad constructed on a breadboard serves as a functional prototype to test within various gaming environments. This DIY controller operates on the Windows XInput API, allowing the system to recognize it as an Xbox controller, thereby facilitating seamless integration with a wide range of games that support Xbox controller inputs. The underlying electronics and wiring are carefully assembled on a breadboard, providing a flexible platform for development and testing.

Purpose

The primary goal of this project is to assess input latency across different gaming scenarios. By using this GamePad, which mimics the functionality of a standard Xbox controller, researchers can measure the time delay between user input and corresponding in-game actions. The experiment aims to gather data on input latency across a variety of platforms, including different operating systems, computer configurations, and monitor types. This information can help identify factors that contribute to input lag and inform hardware and software optimization strategies to improve gaming responsiveness. Testing environment

In addition to the breadboard GamePad, an official Xbox Series controller (plus PlayStation because why not) is included for comparative analysis. By conducting parallel tests with the DIY controller and the Xbox Series controller, researchers can evaluate how closely the breadboard-built GamePad matches the performance and responsiveness of a commercially available controller. This comparative approach provides a baseline to assess whether the homemade controller exhibits any additional latency or other unexpected behavior.

Conclusions

Basically, this project has both a technical and practical focus: it explores the construction and functionality of a custom-built controller, while simultaneously addressing broader questions related to gaming performance, user experience, and system optimization. The findings from this study could have implications for gamers, developers, and hardware manufacturers interested in minimizing input latency and enhancing gameplay fluidity.

Motivation

As it can be probably guessed from the above paragraphs, I want to combine 2 subjects which are on opposite measurement axis (creativity and art with engineering projects). I believe that this project will help me understand how much time and effort developpers and engineers put when designing even just a little piece of the hardware part for the console or computer. Moreover, I'm keen on challenges and I wish to learn Rust as a new and innovative programming language, in comparison, I come from Java langaguage so Rust might be the perfect mix for me for C/C++ and Java. Furthermore (and last idea I promise) I want to create a small presentation involving statistics and measuring data to show that projects can be done in an equal rhythm with fun, creativity and hard work.

Architecture

architecture

Here is a small diagram of all the connections (I think) should be neccessary for the controller. I'll also try to describe it in words. Hopefully it will make sense.

Main Components

Controller Interface-> This is the collection of user input elements, including buttons, joysticks, and directional pads. It's what the user interacts with to control the game.

Signal Processing-> This component receives input signals from the controller interface and translates them into data that the microcontroller can process. In this case, it includes the voltage dividers for button groupings.

Microcontroller-> The central component responsible for processing input data, managing the XInput API communication, and handling USB communication. The Raspberry Pi Pico W is used for this project.

USB Interface-> This is the connection point between the microcontroller and the host system (e.g., a Windows computer). It allows the controller to be recognized as an XInput device.

XInput Communication-> This component encapsulates the interaction between the microcontroller and the host system through the XInput API. It translates input signals into a format that games can understand.

Connections

Controller Interface to Signal Processing-> The input components (buttons, joysticks, etc.) are connected to the signal processing unit. Voltage dividers are used to group certain buttons, reducing the number of required digital pins.

Signal Processing to Microcontroller-> The processed signals are sent to the microcontroller for further handling. The microcontroller is responsible for interpreting the inputs and sending appropriate responses to the host system.

Microcontroller to USB Interface-> The microcontroller connects to the USB interface, which allows it to communicate with the host system. This connection enables the controller to be recognized as an XInput device.

Microcontroller to XInput Communication -> The microcontroller sends input data to the host system using the XInput API. This component ensures that the controller's input is properly formatted and recognized by compatible games.

Log

Week 6 - 12 May

Designed the hardware on the breadboard, applied the voltage dividers to the circuit, finished up the KiCad hardware schematic

Week 7 - 19 May

Finished up the hardware on the breadboard + final version on KiCad. Should start with software now.

Week 20 - 26 May

Software is finished. Windows detects the Pico W as a generic xbox 360 controller and responds to inputs. Code is in project repo.

Hardware

The controller has 16 buttons, 2 vibration motors, 2 joysticks, resistances of 220 ohms to not blow up the circuit. Pico will process all the inputs from the buttons and will translate it for the XInput app.

To implement the project, you need a board with a native USB port, such as the Raspberry Pi Pico.

I chose to use two voltage dividers to save the digital pins on the board. The directional buttons and the A/B/X/Y buttons are grouped by 4 in a voltage divider.

The disadvantage of these groupings is that two or more buttons from the same group cannot be read simultaneously. For example, pressing buttons A and B at the same time will send to the analog pin the value corresponding to pressing button B, not both. (fixed it, should work)

Another compromise is the fact that, for reasons of availability, the "Trigger" buttons are not analog. The value sent to the XInput API is either 0% pressed or 100% pressed.

Schematics

hardware

hardware_implementation

Bill of Materials

DeviceUsagePrice
Rapspberry Pi Pico WThe microcontroller35 RON
2 x BreadBoardBuild the circuit20 RON
Buttons ( 12-15 )Input for controller5 RON
ResistancesTo not fry the circuit5 RON
2x JoySticksMove and aim with the controller10 RON

Software

LibraryDescriptionUsage
rusty_xinputCrate for RustImplements Xinput .dll in Rust, has several functions
gilrsGilRs - Game Input Library for RustGilRs abstract platform specific APIs to provide unified interfaces for working with gamepads
XinputBread and butter of this project (main driver)Xinput, comes with Windows
embassy_rsEmbassy framework for embedded systemsImplement specifically USB module, ADC converter, UDP Wi-fi
  1. Microsoft Official Doc
  2. Implementation example
  3. Sketch of a controller using spare parts