Joystick Mapping in MAME
You would think that setting up a control scheme for a game like Pac-Man would be really simple; after all, you only need to move in four different directions - Up, Down, Left, Right. The problem, it turns out, is that the controls are a little too simple. Most modern joysticks and D-pads are designed to take eight directions, so when you use, say, a standard XBOX-style controller to play Pac-Man, it's easy to accidentally command a diagonal motion that the game doesn't understand. The results of such a command can be... disastrous.
Fortunately, if you're playing in MAME, there are things you can do to make an 8-way joystick friendlier to 4-way commanding.
Generating a configuration file
In what follows, I'm going to assume that you already have a controller plugged in and configured to work in your OS. Open MAME and select the game you want to configure it for:Select "Configure Machine" in the bottom menu, and then "Save Machine Configuration" in the window that pops up. You haven't changed anything in the configuration yet, just created an editable .ini file, in our case "pacman.ini". This file should appear in the MAME install directory.
Once the file is created, open it in a text editor and search the file for the string, "joystick_map". By default, it's set to "auto", which means that MAME makes an educated guess about how to configure the joystick. We want to replace it with something specifically tailored to the game we're playing. The remainder of this article is about what you're going to put here instead, and why it can make a big difference in the gaming experience.
The Joystick Map Grid
The joystick map is made up of a 9x9 grid of values, representing the 81 different joystick positions that MAME recognizes. The central cell of the grid is the joystick's nominal, untouched position and other grid cells represent possible deviations from this center position.
The values that fill each cell are directional commands in the game, so if a particular cell is filled with the value corresponding to "left", for example, then tilting the joystick to that position will send Pac-Man left.
This is what the standard map looks like for an 8-way joystick:
This is what the standard map looks like for an 8-way joystick:
Every joystick position represents a directional command except the central 3x3 -- these cells are empty because they represent the neutral position. In most games, this is interpreted as a stationary condition. There are multiple cells that are neutral because usually you don't want very small deviations from neutral to induce motion. Similarly, there are 9 cells that command left, 9 that command up-left, 9 that command up, and so on.
The problem we have with Pac-Man is that the diagonal commands are not recognized, meaning that 36 cells in the above joystick map are ambiguous. I don't know exactly what the emulator does with these commands, but we would be better served filling them with something meaningful. As a first pass, we can replace some of these cells with the nearest cardinal direction, like so:
Unfortunately, this still leaves the cells along the diagonal axes unfilled. In general, we don't want to leave them as neutral because this could cause a stop in between direction changes, and we don't want to fill them with a directional command because it would break the symmetry of the joystick. Instead, we'll want to make use of a special value in the joystick map, called a sticky:
The sticky means that when the joystick is in that position, it continues to command the direction that it was commanding previously. So if you're rolling the joystick from left to up, a position along the diagonal axis will command left, whereas when rolling up-to-left, a diagonal position commands up. Putting stickies along the diagonal axes preserves the directional symmetry of the map, while still issuing reasonable commands to the game. The above map is the one I prefer to use in 4-way maze games, like Pac-Man, but there are reasonable alternatives that some might prefer. For example,
With this map, Pac-Man's direction won't change unless the joystick is more directly pointed in one of the cardinal directions -- a "strict" 4-way. The advantage is that it's less prone to erroneous direction changes near the diagonal, the disadvantage is that it's less permissive of intended direction changes near the diagonal.
There are plenty of other reasons you might want to fiddle with the joystick map in MAME, as well. One common example is for Q-Bert (1982), where the game expects 4-way input, but the cardinal directions all command Q-Bert to move diagonally on the screen. If you want the direction Q-Bert moves to correspond to the direction you move the joystick, you would want a map that looks something like this:
For example, sending a "right" command actually sends Q-Bert down and to the right, so we map the "right" command to the bottom right corner of the joystick map.
The above figures are graphical representations of a joystick map, but we can't communicate them to MAME in that form. For that, we'll need to turn the rows of arrows and stickies into a string.
The problem we have with Pac-Man is that the diagonal commands are not recognized, meaning that 36 cells in the above joystick map are ambiguous. I don't know exactly what the emulator does with these commands, but we would be better served filling them with something meaningful. As a first pass, we can replace some of these cells with the nearest cardinal direction, like so:
Unfortunately, this still leaves the cells along the diagonal axes unfilled. In general, we don't want to leave them as neutral because this could cause a stop in between direction changes, and we don't want to fill them with a directional command because it would break the symmetry of the joystick. Instead, we'll want to make use of a special value in the joystick map, called a sticky:
The sticky means that when the joystick is in that position, it continues to command the direction that it was commanding previously. So if you're rolling the joystick from left to up, a position along the diagonal axis will command left, whereas when rolling up-to-left, a diagonal position commands up. Putting stickies along the diagonal axes preserves the directional symmetry of the map, while still issuing reasonable commands to the game. The above map is the one I prefer to use in 4-way maze games, like Pac-Man, but there are reasonable alternatives that some might prefer. For example,
With this map, Pac-Man's direction won't change unless the joystick is more directly pointed in one of the cardinal directions -- a "strict" 4-way. The advantage is that it's less prone to erroneous direction changes near the diagonal, the disadvantage is that it's less permissive of intended direction changes near the diagonal.
There are plenty of other reasons you might want to fiddle with the joystick map in MAME, as well. One common example is for Q-Bert (1982), where the game expects 4-way input, but the cardinal directions all command Q-Bert to move diagonally on the screen. If you want the direction Q-Bert moves to correspond to the direction you move the joystick, you would want a map that looks something like this:
For example, sending a "right" command actually sends Q-Bert down and to the right, so we map the "right" command to the bottom right corner of the joystick map.
The above figures are graphical representations of a joystick map, but we can't communicate them to MAME in that form. For that, we'll need to turn the rows of arrows and stickies into a string.
Translating the Joystick Map to a String
In order to communicate our desired joystick map to MAME, we need to convert it to something that can be placed in the .ini file. First, the arrows in the images above can be converted into numbers using the following mapping.
Note that this is the same direction/number mapping that appears on the NumPad of a keyboard. The only other value we need to represent is the sticky, which is denoted with an "s".
Finally, we distinguish individual rows of the 9x9 grid by separating them with a period. Putting all of this together, we can turn the joystick maps shown in the previous section into strings of numbers and letters:
Map Name | String |
---|---|
8-Way Joystick | 777888999.777888999.777888999.444555666.444555666.444555666.111222333.111222333.111222333 |
4-Way Joystick | s8888888s.4s88888s6.44s888s66.444555666.444555666.444555666.44s222s66.4s22222s6.s222222s |
4-Way Joystick Strict | ss88888ss.sss888sss.4sss8sss6.44s555s66.444555666.44s555s66.4sss2sss6.sss222sss.ss2222ss |
4-Way Joystick Q-Bert | 4444s8888.4444s8888.444458888.444555888.ss55555ss.222555666.222256666.2222s6666.2222s6666 |
These strings of characters can be a bit unwieldy, so MAME has a shorthand notation that uses the following rules:
- The last four rows don't need to be specified if they're symmetric with the first four (i.e., up-down symmetry).
- The last four columns don't need to be specified if they're symmetric with the first four (left-right symmetry).
- If a row has been shortened to 5 or fewer characters by rule #2, repeated values at the end of a row string don't need to be specified.
- Repeated rows don't need to be specified.
777888999.777888999.777888999.444555666.444555666.444555666.111222333.111222333.111222333
By rule #1, we don't need to specify the last four rows because they're up-down symmetric with the first four.
777888999.777888999.777888999.444555666.444555666
By rule #2, we don't need to specify the last four characters in each row because of left-right symmetry.
77788.77788.77788.44455.44455
By rule #3, we don't need to specify the last character in each row because it's a repeat of the previous one.
7778.7778.7778.4445.4445
By rule #4, we can omit repeated rows, leaving us with the final shorthand.
7778...4445
Applying these rules to the table above, we getMap Name | Shorthand |
---|---|
8-Way Joystick | 7778...4445 |
4-Way Joystick | s8.4s8.44s8.4445 |
4-Way Joystick Strict | ss8.sss8.4sss8.44s5.4445 |
4-Way Joystick Q-Bert | 4444s8888.4444s8888.444458888.444555888.ss5.222555666.222256666.2222s6666.2222s6666 |
Note that there is little that can be done to shorten the Q-Bert joystick map because it doesn't have up-down or left-right symmetry.
If you don't want to manipulate the joystick map manually, there are utilities out there for creating them through a GUI, such as the MAME Joystick Map Editor.
Note: A previous version of this article incorrectly stated that Pac-Man would stop when the joystick was in the neutral position.
"We don't want to leave them as neutral because then Pac-Man would stop dead in his tracks in between direction changes,"
ReplyDeleteI don't think Pac-Man is the best example of this. He keeps moving forward when the joystick is in neutral position, and it's normal to make your turn inputs early. The only way to stop Pac-Man is to hit a wall. Dig Dug may illustrate your point better.
I got a Ms. Pac-Man / Galaga repro joystick to solve the 4-way problem. It has a diamond-shaped restrictor plate, rather than the circular ones seen in most 8-way sticks, which prevents the joystick from getting stuck in diagonal corners. It's still possible to hit diagonals - the switches are close enough that there's a small zone on each edge where the actuator will hit two of them at once - but that's quickly overridden once you move the joystick out of that zone and into the intended corner. Real hardware would do the same thing - inputs at the electronic level typically were not directional, but 4-bit binary, and that held true whether the joystick was 4-way or 8-way.
Thanks, that's corrected now.
DeletePac-Man will also stop at corners if a diagonal is currently active, and Donkey Kong will choke outright on any sort of a diagonal.
DeletePersonally I'd use Donkey Kong as the canonical example, but Pac-Man's behavior
in response to diagonals honestly isn't that much better.
Wow, I had no idea about this. Can't wait to try it out.
ReplyDeleteI personally solved the mapping issue of a 8-way into a 4-way joystick disabling the diagonals (seen as two simultaneous directions) directly into the .cfg file for any game it may need: i-e, for th UP key:
ReplyDeleteJOYCODE_1_YAXIS_UP_SWITCH NOT JOYCODE_1_XAXIS_LEFT_SWITCH JOYCODE_1_YAXIS_UP_SWITCH NOT JOYCODE_1_XAXIS_RIGHT_SWITCH JOYCODE_1_YAXIS_UP_SWITCH
This is a super interesting and exciting post. I use MAME (2003 - plus) through RetroArch. Do you know if there is a way to create and edit the .ini file as described with RetroArch or a suitable workaround? Been searching all morning and have found nothing. Thank you so much.
ReplyDelete