Click here to return to the main page
Well, it's no secret of mine that I love fighting games. I love Guilty Gear, I love Street Fighter, and I love Tekken.
It's pretty well known that the control scheme for fighting games is quite unique
Confusing at first, but it becomes second nature with time. (The image above doesn't mention that a directional input is typically also paired with an "attack" button)
This is just a simplification that exists because there are now many different control schemes for fighting games.
Today, most people are comfortable using typical Xbox or Playstation controllers, and I've used my fair shair of both.
But certain characters in fighting games, namely Zangief from Street Fighter and Iron Tager from Blazblue, have what are called "Full Circle Inputs" or "360 inputs."
Grapplers, the archetype of fighting game characters that focus around grabs, tend to have these sort of inputs
3 full circles? Might as well run my thumb over a belt sander
Watch this clip! I'm in it!
This is a Witch Games tournament for Guilty Gear Strive I joined with an Xbox controller. While I do not voice over, the producers of this tournament do. I finished the tournament 8th place as Potemkin, the larger, green-clad grappler seen in the clip. The organizers were quite hyped with my performance, but I could've done better, and my thumb could've hurt less
The move they were most excited about was Potemkin's signature grab, the Potemkin Buster.
It too has a complicated, thumb-tearing input, which can be written as (632146 + P)
Traditional controllers were getting me nowhere with this, and hurt too much to warrant continuous use.
While I was aware of "Fightsticks," controllers made specifically for fighting games and modelled after the controls seen on classic arcade cabinets, I was still not a fan of using the large stick to control my inputs
Mayflash Fightstick
I figured it was best to engineer a cost-effective solution to my problem. I could keep the array of buttons to the right, but perhaps instead of using a large stick, I could use something I was much more comfortable with.
I could make a simple circuit of buttons in two groups, the WASD cluster and the Face cluster, and hook these buttons up to a microcontroller to serve as a controller!
The Face cluster consists of 6 buttons, which accomodates most fighting games.
Rough sketch of the idea
I'm no stranger to electronics, and this isn't my first project with programmable microcontrollers, but this was something I saw myself using nigh everyday, hours per week. I would want to pull this off professionally, and produce a high quality build.
This meant using keyboard switches instead of buttons for tactile comfort, for one thing. Most importantly, it meant I was not gonna hand solder wires between the switches and the microcontroller pins.
For this build, I would design a PCB instead of hand soldering wires.
Before working on the PCB schematic, I would have to decide on the components I wish to use on the board.
I am a personal fan of Cherry MX footprint standard switches, and mostly anything by Kailh.
They have 2 pins, one for signal and one for ground. Even better, they are sold in packs of 10 and my board uses exactly 10!
For the microcontroller, I want something with a small footprint and something I have used before. I could use the Arduino Nano, but it uses a mini-usb connection which I find inconvenient.
I considered the Raspberry Pi Pico as an alternative, as it uses a micro-usb connection and is programmed with Python, a personal strength of mine. However the board I did decide on was the best evolution of the Pico's benefits, the Adafruit Feather RP2040. It used USB-C, my personal favorite, and ran with the same processor as the Pico, the RP2040, meaning that it could also be programmed with Python.
I intended to use EagleCAD by Autodesk for designing the PCB. I had access to the limited trial, and I had heard online that it was decent for its job.
To start, I first needed to install some libraries that would add the footprints for the Feather and the switches, and I found these online,
for Adafruit products and for the Cherry MX standard switches
Using EagleCAD, I first designed a schematic. A schematic does not have to be true to component placement in space, but rather just indicates where certain traces should be connected
You will notice each switch has 2 pins. One of each goes straight to ground, and the other goes a respective pin on the Feather. I will admit, the pins were chosen arbitrarily and for convenience while designing the schematic.
From here I could move onto the board's design. Unfortunately, using the free trial of EagleCAD, the board had a size limit, but I was still able to run with a layout I had in mind
I routed the traces as dictated in my schematic, using the top layer of the PCB, as denoted in red, for the signal pins, and the bottom layer of the PCB, as denoted in blue, for ground connections.
Now I had the components and the design for the board, I just needed to order it.
I went with JLCPCB, since I heard plenty of great things about them internationally
I ordered the PCB in black solder mask and waited. The final cost excluding shipping ended up being far less than I anticipated, with 5 pieces coming out to be $7.40. (It is impossible to buy just one of a PCB, the lowest amount is 5)
Now from here I had to solder the components to the PCB
And construction is finished! All that's left now is programming, and the fightpad is complete
First and foremost, we import our libraries. The usb_hid library allows the Feather to emulate keyboard actions as a USB device
import board
import digitalio
import time
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
The code itself can be split into two parts, defining the pins on the board and checking for voltage differences to detect a button press.
# Pin definitions
button_pin_w = digitalio.DigitalInOut(board.D5) # Key "w" assigned to pin D5
button_pin_w.direction = digitalio.Direction.INPUT # Pin set to "INPUT" meaning it will read the state of the buttons
button_pin_w.pull = digitalio.Pull.UP # Pull-up resistor enabled, reads True when not pressed
button_pin_s = digitalio.DigitalInOut(board.D9) # Repeat for each pin
button_pin_s.direction = digitalio.Direction.INPUT
button_pin_s.pull = digitalio.Pull.UP
...
After defining the pins, we must create the keyboard object, which allows the Feather to emulate keypresses as if it were a USB keyboard
# Create a Keyboard object
kbd = Keyboard(usb_hid.devices)
Here are two functions I've defined that will make detecting keypresses a lot easier
# Function to send the key press
def send_key(key):
kbd.press(key)
# Function to release the key
def release_key(key):
kbd.release(key)
The main loop continuously checks each pin's state. When a button is pressed, its voltage goes LOW, the loop then checks if its corresponding Keycode is not in the 'keys_pressed' set. If it isn't, the key is added to the set. When that button is released, its voltage returns to HIGH, and the loop checks if it is in the set. If so, it is removed.
# Main loop
keys_pressed = set() # Track the currently pressed keys
while True:
# Check if the "W" button is pressed (the pin goes LOW when the button is pressed)
if not button_pin_w.value:
if Keycode.W not in keys_pressed:
send_key(Keycode.W)
keys_pressed.add(Keycode.W)
else:
if Keycode.W in keys_pressed:
release_key(Keycode.W)
keys_pressed.remove(Keycode.W)
# Check if the "S" button is pressed (the pin goes LOW when the button is pressed)
if not button_pin_s.value:
if Keycode.S not in keys_pressed:
send_key(Keycode.S)
keys_pressed.add(Keycode.S)
else:
if Keycode.S in keys_pressed:
release_key(Keycode.S)
keys_pressed.remove(Keycode.S)
# ... (similar code for other buttons)
Finally, a small delay is needed to debounce the switch and prevent multiple inputs from one press.
# Add a small delay to avoid excessive key presses (adjust as needed)
time.sleep(0.025)
I programmed the Feather from the Mu Python editor, and uploaded to the circuit.
I bound the WASD keys to, well, W, A, S, and D
The six face buttons were bound to U, I, O on the first row and J, K, L on the second row. Most fighting games will use these keys for keyboard players, and they can be reconfigured later
The inputs on a notepad document worked just fine, but the fightpad must pass its real test.
It works perfectly! And look at the virtual controller on the bottom left. It shows that my fightpad is perfectly capable of outputting diagonal directions, made by holding two directions at once.
I find this way better than using a controller's sticks or D-pad, as it pulls stress away from the single thumb. Now I can use more fingers for each directional input.
I decided to call it the Panbox, derivative of my online username on most platforms, TheDemopan
Better yet, my friends saw potential in the fightpad, some where even interested to purchase.
Having not really sold much in the past, I set a relatively small price for the Panbox at $25. This would be a markdown of about 17%
I was more than happy to take the commission, however. Here's another Panbox I made for a friend.