UniversalController is an Android app that connects to your RetroPie via Bluetooth. You can use it as a generic, virtual controller for the different platforms. A short list of currently supported controllers:
Useful for controlling SNES games, and RetroPie itself
Supports all the keys (F-keys, Run/Stop etc) that one needs during use
Commodore Amiga Keyboard
Mouse
Useful for Amiga games (for example) that require mouse input
A generic touchscreen joystick (Note: To use it you have to switch the joystick in VICE to "numpad")
Android keyboards are optimized for usability, this can be useful for writing longer text
Intellivision
ColecoVision
Some of the more crammed keyboards (Amiga, C64) support pinch and zoom. E.g. if a game needs repeated use of the F-keys you can zoom in on those.
This app does not replace an actual joystick or game controller, for two reasons: one, Bluetooth has an inherent latency that kills any fast-moving action game, two, when you look at the screen your hands slowly move out of position on your smartphone because there is no tactile feedback.
So, this tools is awesome for navigating through menus and stuff, and even for slow gameplay. You will not successfully play Great Giana Sisters with it.
MAKE A BACKUP OF YOUR SYSTEM
Seriously, this app is alpha-stage at best. It patches at least one system file (the Bluetooth config), so something could go wrong.
Ok, here's the installation procedure:
cd
git clone https://github.com/threebrooks/UniversalController
cd UniversalController/linux
sudo ./install.sh
Hopefully the installation went well, then restart the RPi with
sudo shutdown -r now
The app is located in the android/ folder of the project, it's an Android Studio project.
That's the easy one. You should start with copying maybe the Commodore 64 keyboard code and use that as a template.
Now, the way these keyboard-like controllers work is that there are two PNG files (look at the android/app/src/main/res/drawable folder): one normal picture of the keyboard (e.g. controller_c64.png) and one "mask" picture (controller_c64_mask.png) that is the same size as the normal one.
"Display" image
"Mask" image
The app only shows the Display picture, but when you touch a section of the picture, the underlying code (the "BitmapControllerView" class you inherit from does this for you) looks up the exact same image location in the Mask picture, and calls the onPixelClick() function with the RGB value of the mask image's pixel you clicked on.
If you look at the Mask picture, you see that all the buttons are yellow boxes. They are all different shades of yellow however! Each box has a different RGB value. (to make it easy in the code, they all have the same red and green value, the only thing changing is the blue value). When you create your own masking picture, write down the different RGB values and what key they map to, and then carry that over to the onPixelClick function. The good thing about this approach is that there is no limitation as to the shape of the keys, or even that they are contiguous! You can map the two Alt keys to the same color for example if you want.
So, to add another controller, create the two pictures and put them into that folder, then refer to them in the constructor of your controller class.
Two more places need to be adjusted:
Test and debug, and then create a pull request!
That's a bit harder. You have to inherit from ControllerBaseView and build up your own layout.
I take zero responsibility for any damage this tool might do to your Android device or Raspberry Pi (I can't see how it even could, but better point it out). The tool is as-is, license is entirely and completely free. Improve, copy, modify, do whatever you like.