Under this barbaric name hides a module which is particularly close to the heart of one of our developers, since it will allow to revive all these computer games, forgotten by all the Recalboxers who have no keyboard connected, that is to say, almost everyone ...
During the glorious decade of the 80's, a number of microcomputers saw the light of day... But at that time, the controller did not yet exist, and the joystick was only fully exploited on a console.
Microcomputer games have keyboard-oriented ergonomics, and for the lucky ones, keyboard or joystick. Often the keyboard is needed to skip the intro or to start the game.
It was therefore impossible to enjoy these games without having a keyboard connected.
At least until now, because Recalbox includes a Pad-To-Keyboard module which is responsible for mapping pad actions to keyboard key presses/releases!
This feature works using small very simple configuration files.
It is very simple :
START
button on your pad to the SPACE
key, and the problem is fixed.START
and the game will see that you have pressed the space key on a keyboard.A
button to SPACE
.And no doubt that talented external developers can even give us a small interface to create these configurations effortlessly.
When it detects a P2K (Pad to Keyboard) configuration for a game, the frontend will create a virtual keyboard that will be seen by the system as a real physical keyboard. Throughout the playing session, the frontend will intercept pad events, and depending on the configuration, it will generate key presses and releases.
Emulators that listen to the keyboard will then use these keyboard events in the machine they are emulating, as if they came from a physical keyboard.
Only one thing: key sequences with combinations in the middle. It's either one or the other.
It will be impossible for example to write a word that requires characters accessible with SHIFT on the emulated machine.
Maybe it will come in the next versions 😉
The configuration files of a pad-to-keyboard mapping can be defined in 2 different ways:
For a folder, it will need to be inside of this folder and will be named .p2k.cfg
.
This will give a final path of the type /path/to/.p2k.cfg
. This fill will apply to all games in this foler and sub-folders.
For a specific rom (or game), it must have the same name as the rom, with the extension .p2k.cfg
added to the existing extension.
Which, for /path/to/mygame.ext
, will ultimately result in /path/to/mygame.ext.p2k.cfg
.
If several files are present, they are overrided in descending folder order, up to the specific configuration of the games, if it exists. This will be seen in detail a little later.
The mapping configuration is based on a Nintendo controller (A / B / X / Y buttons).
Let's start from an example used during the tests:
# dpad to arrow keys
0:up = up
0:down = down
0:right = right
0:left = left
# button A to SPACE
0:a = space
# B to Y key (for Y/N prompts)
0:b = y
# And finally, map START button to ENTER
0:start = enter
As you can see in this example, the structure is very simple.
You can leave empty lines to separate the blocks, and use the #
character at the start of the line for comments / descriptions / memos.
The mapping configuration lines are of the form PAD:ACTION = KEY
, with:
PAD
: Controller number as defined in the frontend, or the natural order of the pads if there is no forced assignment. It is rare for more than one controller to be mapped, so the number 0 will be used in the vast majority of cases for the first controller.ACTION
: Joystick action to map. You can map all buttons, directional arrows (D-Pad) and 4 primary directions of analog joysticks, which represents up to 25 actions that can be assigned to keyboard keys, on a full standard pad.KEY
: The keyboard key associated with the action of the joystick. When the action of the stalk is engaged, the corresponding button is pressed. When the action of the stalk is disengaged, the corresponding button is released. As seen above, the mapping is 1 to 1. If you want to simulate for example LEFTSHIFT + A, you will have to assign LEFTSHIFT to a button on the joystick ( for example L1), and the A key to another button (say the Y button). Pressing L1 + Y simultaneously will result in a LEFTSHIFT + A. An exception exists for analog joysticks. Since they can be placed diagonally, this feature can be used to press 2 keys at the same time.The case of
ACTION
andKEY
does not matter, nor does any spaces at the start of a line, at the end of a line, or around the=
.
Here is the complete list of usable pad actions:
Action | Description | Action | Description |
---|---|---|---|
up |
Digital PAD, direction up | j1up |
Joystick #1 (left), direction up |
down |
Digital PAD, direction down | j1down |
Joystick #1 (left), direction down |
left |
Digital PAD, direction left | j1left |
Joystick #1 (left), direction left |
right |
Digital PAD, direction right | j1right |
Joystick #1 (left), direction right |
a |
Button A | j2up |
Joystick #2 (right), direction up |
b |
Button B | j2down |
Joystick #2 (right), direction down |
x |
Button X | j2left |
Joystick #2 (right), direction left |
y |
Button Y | j2right |
Joystick #2 (right), direction right |
l1 |
Button L1 | l2 |
Button L2 |
r1 |
Button R1 | r2 |
Button R2 |
start |
Button START | l3 |
Button L3 |
select |
Button SELECT | r3 |
Button R3 |
Actions can also be preceded by a +
sign to indicate that they are to be executed in conjunction with the pad's HOTKEY
button.
The following example will operate the F1 to F4 keys when the HOTKEY
button is combined with the DPAD directions:
# Special actions on dpad
0:+up = f1
0:+down = f2
0:+right = f3
0:+left = f4
The virtual keyboard created by the frontend is an agnostic keyboard. He does not know any language or particular disposition. It is therefore a 105 keys QWERTY keyboard of the most basic.
In order not to lose users, only certain keys common to all keyboards can be configured. There are two good reasons for this:
However, no panic, in the vast majority of cases, you will be using simple key mappings. You just have to keep in mind that the layout of the letters is in QWERTY.
A picture is better than a long speech:
As mentioned above, the configuration files, when there are several at different folder floors and / or for the game itself, override each other.
The P2K module will start by reading the one above, then will go down to the folder of the rom by reading all the configuration files it finds, to finish with the rom, if it exists.
Which means that the configurations can be added, or modified!
Example 1: The configurations are added
File /path/to/.p2k.cfg:
# Map START to ENTER
0:start = enter
File /path/to/game.ext.p2k.cfg:
# Map SELECT to SPACE
0:select = space
Will give the equivalent of:
# Map START to ENTER
0:start = enter
# Map SELECT to SPACE
0:select = space
Example 2: The configurations change
File /path/to/.p2k.cfg:
# Map START to ENTER
0:start = enter
# Map SELECT to SPACE
0:select = space
File /path/to/game.ext.p2k.cfg:
# Map SELECT to F1
0:select = f1
Will give the equivalent of:
# Map START to ENTER
0:start = enter
# Map SELECT to F1
0:select = f1
Example 3: The configurations are modified by removing mappings
File /path/to/.p2k.cfg:
# Map START to ENTER
0:start = enter
# Map SELECT to SPACE
0:select = space
File /path/to/game.ext.p2k.cfg:
# Remove SELECT mapping!
0:select =
Will give the equivalent of:
# Map START to ENTER
0:start = enter
You can add a description in the frontend like this:
To do this, you need to add two semicolons to make it appear.
There is an example:
# Recalbox's Pad-to-Keyboard configuration
#Arkanoid Revenge of Doh (1987)(Sharp - SPS)
#SHARP X6800
#left move key 4
0:left = kp4 ;; Move left
#right move key 6
0:right = kp6 ;; Move right
#shoot key space
0:a = space ;; Fire!
#hispeed move key shift
0:b = leftshift ;; Speedup!
You can emulate the movement of the mouse and the press / release of its 3 buttons directly from your pad.
For an accurate emulation, a pad with an analog joystick is recommended, but emulation is perfectly possible with buttons or a d-pad.
In addition to the KEY
keys on the keyboard seen above, there are 7 values, corresponding to the 4 directions of movement plus the 3 mouse buttons.
Mouse Element | Description |
---|---|
mouse.button.left |
Left mouse button |
mouse.button.middle |
Middle mouse button or wheel click |
mouse.button.right |
Right mouse button |
mouse.move.left |
Move mouse left |
mouse.move.up |
Move mouse up |
mouse.move.right |
Move mouse right |
mouse.move.down |
Mouse move down |
These values can be assigned to any ACTION
.
Let's say we have a simple SNES pad with a DPAD and 4 buttons, and we want to use the mouse on a mouse-only DOS game, this is what a p2k file would look like:
# Recalbox's Pad-to-Keyboard configuration
# DOS GAME
# Mouse moves
0:up = mouse.move.up
0:right = mouse.move.right
0:down = mouse.move.down
0:left = mouse.move.left
# Mouse buttons
0:a = mouse.button.left
0:b = mouse.button.right
With such a configuration, the cursor movements accelerate at the start before stabilizing at a certain speed.
You can also use an analog joystick, for example the right joystick of an XBox controller:
# Recalbox's Pad-to-Keyboard configuration
# DOS GAME
# Mouse moves
0:j2up = mouse.move.up ;; Mouse move
0:j2right = mouse.move.right ;; Mouse move
0:j2down = mouse.move.down ;; Mouse move
0:j2left = mouse.move.left ;; Mouse move
# Mouse buttons
0:a = mouse.button.left ;; Left button
0:b = mouse.button.right ;; Right button
In this case, it is the push of an analog joystick that will regulate the speed of the cursor movement.
If you use the left or right joysticks to emulate mouse movement, you can use the simplified configuration 0:j1 = mouse.moves
or 0:j2 = mouse.moves
(watch out for the 's' !).
If we take the previous configuration, it can be simplified as follows:
# Recalbox's Pad-to-Keyboard configuration
# DOS GAME
# Mouse moves
0:j2 = mouse.moves ;; Mouse move
# Mouse buttons
0:a = mouse.button.left ;; Left button
0:b = mouse.button.right ;; Right button
For games that only need a mouse, and there are many, you can map the mouse to several pad elements, like this:
# Recalbox's Pad-to-Keyboard configuration
# DOS GAME
# Mouse moves
0:up = mouse.move.up
0:right = mouse.move.right
0:down = mouse.move.down
0:left = mouse.move.left
0:j1 = mouse.moves ;; Mouse move
0:j2 = mouse.moves ;; Mouse move
# Mouse buttons
0:a = mouse.button.left ;; Left button
0:b = mouse.button.right ;; Right button
With this p2k file, the two joysticks and the dpad can be used to control the mouse cursor finely, depending on individual preferences and the level of precision required.
With P2K, the keyboard emulation possibilities are greatly extended to support key combinations, and key sequences (as when typing).
In both cases, the system supports up to 32 keys. So either 32 keys pressed almost simultaneously, or a sequence of 32 consecutive keys.
To declare a keystroke combination, it's very simple, just separate the keys by spaces (and nothing else but spaces!), like this:
# Assign CTRL+C to R1
0:r1 = leftctrl c ;; Break the program!
Note that when R1 is pressed, the keys are pressed in the exact order of the statement. Then when R1 is released, the keys are released in the reverse order.
In case the emulator requires a delay between keys (to keep the first button pressed and to press a second button) or in case you need an explicit delay for some reason, you can precede the keys which need to stay pressed with +xxx
where xxx is a delay in milliseconds.
Example:
# Assign CTRL+C to R1
0:r1 = +100 leftctrl c ;; Break the program!
Here, when R1 is pressed, the P2K is pressing the LEFT CONTROL key, waits 100ms pressed, then presses the C key, doing the CTRL+C combinaison. The last key does not introduce a delay. Then when R1 is released, the keys are released in reverse order: C is released, wait 100ms, then release LEFT CONTROL.
The +
explicitly indicates that this is a combination of keys. It can be used on its own, without the delay, but will be useless in this case, because without an explicit indicator, several declared keys will form a combination.
For a keystroke sequence we need to use the explicit /
indicator, like this:
# Assign the sequence FGHJ to R1
0:r1 = / f g h j ;; Type FGHJ!
Here, when R1 is pressed, the system will generate the following sequence: press F, release F, press G, release G, press H, release H, press J, release J. There is no delay between presses and releases, and in the strict order of declaration.
Note that when R1 is released, nothing happens. The sequence is sent only on a press.
Again, some emulators/games might have problems with keystroke sequences without delays. So we can declare a delay of 25ms between each press/release, like this:
# Assign the sequence FGHJ to R1
0:r1 = /25 f g h j ;; Type FGHJ!
In this case, the sequence will be: press F, wait 25ms, release F, wait 25ms, press G, wait 25ms, release G, wait 25ms, press H, wait 25ms, release H, wait 25ms, press J, wait 25ms, release J.
No delay after the last release.
Guaranteed 100% without input-lag, and it works on all computers!
The P2K module is in high priority, which means that it takes control as soon as a pad event occurs, to translate it and send it back to the virtual keyboard instantly.
On Raspberry Pi 3, the measurements taken between the reception of the Pad action and the reception of the keyboard press give results much lower than what could generate the slightest input lag.
That's it, have you configured your favorite games to be fully playable with the controller?
So don't let others do the same job over and over again: share your configurations!
We have opened a special thread on the Recalbox forum, so that everyone can share their configurations.
You can also include your creations in ScreenScraper so that they are downloaded automatically when scraping.
However, be careful: try to stay logical, and have a mapping that is as intuitive as possible:
Good gaming!