/McAirpos

MakeCode Arcade games in RetroPie and Recalbox 7.1.1/8, running natively as ELF executables on Raspberry Pi OS with 1-2 gamepads

Primary LanguagePythonMIT LicenseMIT

McAirpos

MakeCode Arcade games in RetroPie, Recalbox 8/7 and Batocera, running natively as ELF executables on Raspberry Pi OS/Linux ARM with gamepad and keyboard support for up to 2 players.

RetroPie Batocera Recalbox
(In-game screenshots provided by retro2png)

Many thanks to @willmtemple, @mmoskal and @pelikhan for all their help and support, and lately @rdmueller and @edthedev for their contributions. Special thanks to @hobbitalastair, @MerlijnWajer and @freethinker, whose projects, termfix, uinput-mapper and ttyecho, I have used in my solution!!!

2022.06.15: Batocera 34 support and installation script
2022.06.05: FINALLY the settings namespace/extension has been fixed for Raspberry Pi/ARM, by @nopid!
2022.05.31: Two new Ansible playbooks for installing McAirpos on multiple Recalbox 8 devices at once
2021.12.18: Recalbox 8 support and installation scripts and Python 3.x support for uinput-mapper and major revision of launCharc
2021.06.29: Updated controller configuration section in README.md
2021.01.26: New quick installation script for RetroPie/RPi OS

Controller support out-of-the-box, tested ok with various combinations of:

It should also work with other controllers with little or no modification of the uinput-mapper arcadeX.py config files.

Feedback is valueable, so please don't hesitate to open an issue here for sharing with the community about other controllers that work and how, or if something doesn't work for you.

Please scroll down this page or click the following links for: Downloading game files, Contents, Features, Why McAirpos?, Prerequisites, Installation, Updates, Usage, Controller layout and configuration, Developement news, Issues, Todo list, Mentions and Retro gaming.

Happy retro gaming and retro game making!!!

@Vegz78
(Thank you for awarding McAirpos a star if you like and use it!)
(If you're interested in retro gaming in general, please also check out the blog, retrospill.ninja)

Make your own or dowload MakeCode Arcade games for RetroPie

I've made a solution for making MakeCode Arcade ready for downloading native executables of games here:
https://vegz78.github.io/McAirpos

Either make your own games and extensions in the MakeCode web editor, or download from various places, like:

Contents

Features

Why the need for McAirpos?

The current MakeCode Arcade natively executable game files compiled with the Raspberry Pi as target have 2 problems preventing a nice experience from within RetroPie:

  • The parent game process ID shifts during game play, which makes RetroPie think the game has exited and then puts it still running in the background. On exit, the game files do not release and clean up the framebuffer and key inputs, giving the impression that the system has frozen/halted.
    microsoft/pxt-arcade#2435
  • The game files natively do not support most newer EV_ABS type or multiple game controllers, but only 1 EV_KEY type gamepad or 1 keyboard input event, even though multiple players are supported in the games.
    microsoft/pxt-arcade#2245

McAirpos works around both these issues, making MakeCode Arcade games play like other games in RetroPie.

Prerequisites

  • curl or wget
  • Drivers for gamepads you have that don't work "out of the box"
  • ALSA sound driver(almost always included)

Installation

RetroPie/Raspberry Pi OS

Recalbox

Batocera

Other

Quick automatic installation for RetroPie/RPi OS

Run this command without sudo in a terminal or the CLI on RetroPie/RPi OS:
curl -sL https://raw.githubusercontent.com/Vegz78/McAirpos/master/install.sh | bash -

Or clone the repository like in the 1st manual installation point below and run:
~/McAirpos/install.sh

Manual installation for RetroPie/RPi OS

  1. Clone this repo from and into /home/pi/:
    git clone https://github.com/Vegz78/McAirpos.git
    (Paths are currently hardcoded and will only work with the repo directly under /home/pi/)
  2. Copy the folder .../MakeCode/sd with all its contents into the root folder /:
    sudo cp -r ~/McAirpos/McAirpos/MakeCode/sd /
    (The game files are hardcoded to write to and read from this root/sd folder)
  3. Make sure the contents of /sd are owned and writable for your user(normally pi):
    From /: sudo chown -R pi /sd&&sudo chgrp -R pi /sd&&sudo chmod -R 755 /sd
  4. Copy the contents of the file ./McAirpos/EmulationStation/es_systems.cfg_MakeCode into the end of the file /etc/emulationstation/es_systems.cfg. Make sure not to delete the </systemList> tag at the end of the file.
  5. Copy the folder ./McAirpos/EmulationStation/makecode with all its contens into /etc/emulationstation/themes/carbon/.
    sudo cp -r ~/McAirpos/McAirpos/EmulationStation/makecode /etc/emulationstation/themes/carbon
  6. Create a makecode games folder under /home/pi/RetroPie/roms/ and fill it up with native MakeCode Arcade games.
    Make sure that the makecode games folder is owned by pi and has the correct permissions:
    sudo chown -R pi:pi ~/RetroPie/roms/makecode&&sudo chmod -R 755 ~/RetroPie/roms/makecode
    Also, make sure that every game_file.elf has executable permissions if they aren't set automatically when copying them to the makecode games folder:
    sudo chmod -R 755 ~/RetroPie/roms/makecode

Manual installation for Recalbox and Batocera

Please use the automatic installation scripts below. If you still want to do a manual installation, access the script files and follow the instructions inside. :-)

Quick automatic installation for Recalbox

To install McAirpos on your Recalbox, you will need shell access (Linux console) to it. If you have a keyboard connected, you can enter the shell by pressing F4 + ALT+F2. Otherwise, connect your Recalbox to the network (cable or WiFi), start a terminal on your PC and execute ssh root@recalbox. The name recalbox might be different (for a GPi Case, it is ssh root@recalboxgpi). You can lookup the correct name in the network settings of your Recalbox or use the IP address. Default User/Pass: root/recalboxroot

Run one of these commands from the shell:

Recalbox 8 with jack or usb audio:
curl -sL https://raw.githubusercontent.com/Vegz78/McAirpos/master/install_recalbox_v8.sh | bash -
(if you experience nuisance where audio switches to HDMI after exit of MakeCode Arcade games, please see here for a workaround...)

Recalbox 8 with HDMI audio:
curl -sL https://raw.githubusercontent.com/Vegz78/McAirpos/master/install_recalbox_v8_HDMI-Audio-Fix.sh | bash -

Recalbox 7-Reloaded!:
curl -sL https://raw.githubusercontent.com/Vegz78/McAirpos/master/install_recalbox_v7.sh | bash -

If you don't know which script to use, start with updating your Recalbox and the v8 script. If you run into problems with the sound, try the v8_HDMI-Audio-Fix script below, or the general HDM-Audio-Fix script for Linux kernels >= v.5.

After running the script, there will be a "makecode" roms folder. Copy your .elf files (generate through https://vegz78.github.io/McAirpos/) to this folder via scp, directly to your card or SMB mount for MakeCode Arcade to appear as an emulator in the Recalbox main menu after the next reboot.

Installation on multiple Recalbox devices

For RecalBox 8, two Ansible playbooks are available for installing McAirpos remotely to multiple devices at once. This is well suited for classroom or makerspace settings with many simultaneous programming and arcade projects.

Quick automatic installation for Batocera

To install McAirpos on Batocera, you will need shell access (Linux console). If you have a keyboard connected, you can enter the shell by pressing CTRL+ALT+F5. Otherwise, connect your Batocera device to the network (cable or WiFi), start a terminal on your PC and execute ssh root@batocera. You can lookup the correct name in the network settings of your Recalbox or use the IP address. Default User/Pass: root/linux

Run this command from the shell:
curl -sL https://raw.githubusercontent.com/Vegz78/McAirpos/master/install_batocera.sh | bash -

Missing HDMI audio in MakeCode Arcade games

For Linux kernels >= v.5 (newer RetroPie, Recalbox and Raspberry Pi OS releases, check with uname -a) there is a problem where HDMI audio is not found, as required by MCA games, on the first ALSA audio device, hw:0,0, and MakeCode Arcade games either crash, freeze or play without sound. To resolve this on a recently updated McAirpos installation, run this script:
curl -sL https://raw.githubusercontent.com/Vegz78/McAirpos/master/HDMI-Audio-Fix.sh | bash -
Batocera does not seem to have this problem, since audo is handled by Pipewire.

SSL certificate error

On some systems, you might get an SSL certificate error when running the curl commands. Then try one of these commands instead: Vegz78#41 (comment)

Updating

Bugfixes, changes and additions are released sporadically as updates to the main branch, without any formal system for releases and history. News about the latest and most important updates are published with dates in the development section, with links to further details in the commit comments.

Updates to included files located outside the ~/home/pi/McAirpos are seldomly expected, so to update, from inside this folder, simply type: git pull

Alternatively, if you've made changes to any of the files in this folder, simply back up those files, and then remove the folder and clone again, from /home/pi: rm -rf ./McAirpos&&git clone https://github.com/Vegz78/McAirpos.git

Usage

  • Fire up EmulationStation and navigate to your MakeCode Arcade games menu and select the game to play, or

  • Run from the text console(games do not run within X):
    ~/McAirpos/McAirpos/launCharc/launCharc ~/RetroPie/roms/makecode/_gamefile.elf_

    • nomap command line option for manual configuration of 1 keyboard(2 players) or 1 EV_KEY type gamepad interface(e.g. GPIO with 1 or more controllers/players) using the /sd/arcade.cfg file directly without running uinput-mapper:
      ~/McAirpos/McAirpos/launCharc/launCharc nomap ~/RetroPie/roms/makecode/_gamefile.elf_
      and similarly inside /etc/emulationstation/es_systems.cfg.
    • keybswap command line option for swapping from the lowest(default) autodiscovered keyboard input handler to the highest, if your keyboard is not detected correctly.
    • verbose command line option for verbose logging to stdout instead of /tmp/McAirpos.log.

NB: The game_files.elf and launCharc only work in RetroPie(booted directly into or started from the CLI) and in the Linux console/CLI. They do not work(cannot open gfx display) when run in a terminal emulator or in RetroPie started from within a desktop/gui/X environment.

NB2: The game_files.elf must be executable and the ~/RetroPie/roms/makecode folder must be writable:
sudo chmod -R 755 ~/RetroPie/roms/makecode
Typical symptoms when this is not the case, are games not launching with only a black screen and /tmp/McAirpos.log showing "Did not find the file /tmp/pxt-pid..." and/or "Timed out trying to find game's process ID..." after having tried to launch a game.

If something goes wrong and the screen/keyboard freezes inside the game, it should be possible to regain control of the console/RetroPie by a combination of CTRL+\, CTRL+C, CTRL+D and CTRL+C.

Default and modifying the layout for controls

Default button mappings with corresponding EV_ABS and (EV_KEY) codes*:

Move Keyboard PL1 Keyboard PL2 Gamepads/Controllers PL1&PL2
Up W (17) Up arrow (103) BTN_DPAD_UP /-ABS_HAT0Y /-ABS_Y** (17/103)
Down S (31) Down arrow (108) BTN_DPAD_DOWN /ABS_HAT0Y /ABS_Y (31/108)
Left A (30) Left arrow (105) BTN_DPAD_LEFT /-ABS_HAT0X /-ABS_X (30/105)
Right D (32) Right arrow (106) BTN_DPAD_RIGHT /ABS_HAT0X /ABS_X (32/106)
Fire/A Left Ctrl (29) Right ALT (100) BTN_SOUTH(/BTN_A) /BTN_THUMB (29/100)
Fire2/B Left Shift (42) Space bar (57) BTN_EAST(/BTN_B) /BTN_THUMB2 (42/57)
Exit Esc (1) BTN_START /BTN_BASE4 /ABS_Z (1)
Restart F1 (59) BTN_SELECT /BTN_BASE3 /ABS_RZ (59)
Menu F2 (60) BTN_MODE(/BTN_PS) /KEY_HOMEPAGE (60)
Code type: (EV_KEY) (EV_KEY) EV_ABS, and some EV_KEY(BTN_s) (EV_KEY1/E_VKEY2)
Mapping: (Game-native) (Game-native) uinput-mapper to (game-native)
In files: arcade.cfg arcade.cfg arcade1&2.py
* (EV_KEY) codes in arcade.cfg and in the 'code' fields
in arcade1&2.py must always correspond.
** Negative EV_ABS values are values less than the
center value, positive are greater than center

For many gamepads and controllers, there should be no or little need for modification of the config files. For DIY Arcade controllers, you might save some time and complexity by please checking that the physical wirings are correct as a first step and before attempting to modify the config files.

Buttons in MakeCode Arcade games operate with raw input events on the lowest level - the Linux Input Subsystem. It's therefore often best to get your controllers to work correctly inside McAirpos first, and according to the most logic physical button function/location for every input event EV code name the controller outputs(The physical button intended for the 'fire' function, should typically output the EV codes BTN_SOUTH(/BTN_A) or BTN_THUMB, and not output BTN_SELECT etc.). When the buttons are correctly wired and set up in McAirpos, they can then easily be reconfigured accordingly inside RetroPie and other programs working with controllers on a higher level.

Changing button layouts:

  • Edit /sd/arcade.cfg for keyboard(or EV_KEY type gamepads, where all values are either 0 or 1), or
  • Edit the uinput mapping files arcade1.py for only 1 controller, and both arcade1.py and arcade2.py under ~/McAirpos/McAirpos/uinput-mapper/configs/ for 2 EV_ABS type gamepads/controllers*
    (where most commonly only the joystick has EV_ABS values that vary typically somewhere between -256 and 256 along each axis).


When using EV_ABS type gamepads/controllers(most common case for USB/BT interfaces) with uinput-mapper, please:

  1. Leave /sd/arcade.cfg alone/as-is
  2. Check and take note of all the EV codes and values that your controller outputs for each button and joystick direction with evtest
  3. Physically (re-)wire the real button with its intended function(e.g. Exit) so that evtest outputs one of the codes in the rightmost column of the same row as this function in the table above, if possible
  4. If not possible to rewire or the controller does not output all of those codes accordingly or uniquely, edit arcade1&2.py so that each button's or joystick direction's EV_KEY or EV_ABS code is included and corresponds/is mapped to the same (EV_KEY) code as in /sd/arcade.cfg, for its intended function** image

When using EV_KEY type key gamepads/controllers(most common case for keyboards and GPIO interfaces) with only one /dev/input/eventX and without the need for uinput-mapper, please:

  1. Check and take note of all the EV_KEY codes that your controller outputs for each button and joystick direction with evtest
  2. Edit only /sd/arcade.cfg with the correct /dev/input/eventX number and (EV_KEY) code mappings corresponding to the physical wiring
    (This is explained much better and in detail here and here)
  3. Run launCharc with the nomap argument image

Finding your controller's input eventX number and the EV codes and values that its buttons and joystick outputs:

  1. Find your gamepad's /dev/input/eventX number: more /proc/bus/input/devices
  2. Read out all the gamepad's registered button names and types, and test to which button name each physical button is mapped by running: evtest /dev/input/eventX, where X is the input number found in the first point. Exit evtest with CTRL+C.

Optimizing controller performance

In an attempt to maximize the number of game controllers supported, McAirpos runs a self-calibrating routine on every launch of a game and has a few redundant uinput mappings.

Even though it has been reported to run all right even on a Raspberry Pi Zero, if you experience an occasional choppiness during gameplay or hangs in either direction(before max stroke in all directions is read), and if you are technically inclined to optimize, you can:

(*Theoretically, it should be possible with up to 4 players/controllers on the RPi, but this is most feasible with 4 EV_KEY controls game-natively on the same input event(GPIO/Keyboard?) in arcade.cfg. Setting up this automatically with uinput-mapper for 4 EV_ABS controllers, proved hard du do(4 *arcade.py with lots of mappings etc.), and all the cross-mappings in uinput-mapper would probably put to much strain on the RPi, unless all redundant mappings are removed and the auto calibration routine is hard-coded with the correct EV_ABS value ranges instead. Then, maybe it would be possible with a fixed setup, where all controllers are always on and on the same input event.)

(**If you have any great working and optimized uinput-mapper arcade1&2.py controller configurations, please share them for others' to use, by uploading the file to an issue for the same controller type in the issues section!)

Issues

Don't hesitate to open an issue if it doesn't work as expected or you have suggestions for improvements. But please first:

  1. Read the usage section thoroughly, and
  2. Check and double-check that your game_files.elf are executable and that your games folder is writable:
    sudo chmod -R 755 ~/RetroPie/roms/makecode, and
  3. Check the physical wiring of DIY Arcade controllers and whether your issue might already have been solved, and
  4. If your game is still not launching, provide a copy of /tmp/McAirpos.log, or
  5. If your controller is still not working, provide an evtest readout of your controller with indications about which button functions you intend for which listed input events

I'm still just learning to code and I don't mind a little spaghetti code as long as it just works.. ;-)

I would really appreciate feedbacks from your own experiences with McAirpos and maybe pick up some tricks of the trade while we sort out the bugs together!

Development news

2022.06.15: Added Batocera 34 support and installation script.
2022.05.31: Added Ansible deployment playbooks for Recalbox 8 to enable installation on multiple devices at once.
2021.12.18: New automatic installation scripts for McAirpos on Recalbox 8 - one for analog/jack audio and one for HDMI audio. Larger refactoring and bug fixes of the launCharc launcher and some more bugfixes.
2021.12.16: Added McAirpos support for Recalbox 8, including Python 3.x support in addition to 2.7 for uinput-mapper, fix for broken HDMI alsa audio in MCA games and testing and verifying support for the Retroflag GPi case controller. Thank you very much, @rdmueller, for testing changes and the GPi controller, and contributing to solutions!
2021.07.13: Tested McAirpos running ok with keyboard and gamepad controllers on fresh RetroPie 4/400 image, v4.7.1(buster, kernel 5.4.72).
2021.07.06: Major revision of the arcade1&2.py controller configuration files.
2021.06.29: Updated controller configuration section in README.md.
2021.02.02: Added support and quick installation script for Recalbox 7.1.1-Reloaded!, only tested on a RPi4 4GB. Silent game launch with logging to /tmp/McAirpos.log instead of stdout, argument option verbose for old launch with text to screen. Some small fixes and cleanup of code.
2021.01.28: Tested McAirpos running ok with keyboard and gamepad controllers on the following systems:
-RPi4 B 4GB: RetroPie 4/400 image, v4.7.1(buster, kernel 5.4.72), RetroPie(FKMS ON), CLI(FKMS ON&OFF)
-RPi4 B 4GB: RetroPie v4.7.3 on top of RPi OS(buster, kernel 4.19.97), RetroPie(FKMS ON), CLI(FKMS ON&OFF)
-RPi3 B+/B: RetroPie 2/3 image, v4.7.1(buster, kernel 5.4.72), RetroPie(FKMS ON), CLI(FKMS ON&OFF)
-RPi3 B+: RetroPie v4.7.3 on top of RPi OS(buster, kernel 5.4.83), RetroPie(FKMS ON), CLI(FKMS ON&OFF)
-RPi3 B+: RetroPie v4.6 on top of RPi OS(stretch, kernel 4.19.66), RetroPie(FKMS OFF), CLI(FKMS ON&OFF)
-RPi3 B: RetroPie 4.2.12 on top of RPi OS(jessie, kernel 4.9.35), RetroPie(FKMS OFF), CLI(FKMS ON&OFF)
-RPi4 B 4GB, RPi3 B+/B: RPi OS Lite image 2020-12-02(buster, kernel 5.4.79), CLI(FKMS ON&OFF)
2021.01.26: Got tired of doing the manual installation procedure on all my test images and made a quick automatic installation script for everyone to use.
2021.01.24: Stability improvements for game launch and exit, more accurate keyboard autodiscovery, defaults to lowest keyboard input event handler, new keybswap command line option to swap to highest.
2021.01.18: Bugfixes, improvements and further testing, most notably fixed the occasional mismatch of /dev/input/eventX between uinput-mapper and launCharc in /sd/arcade.cfg, and now possible to map 1 & 2 controllers without keyboard connected. Feedback about additional working controllers and about possible reasons for occasional instability/game exit, especially on older RPi devices and RPi OS/RetroPie distros, is still appreciated.
2021.01.15: Added nomap option for manual configuration and use of /sd/arcade.cfg directly for controllers, instead of auto-detection and uinput-mapper. With some great help from @Kay-Wolfe, gamepad support is now expanded.

Todo

Some thoughts and ideas I might start grappling with in the near or distant future. Don't hesitate to post good ideas in the issues section. If it's to big or difficult for me, maybe you want to contribute directly with a pull request?

  • Follow up bugs and improve stability
  • Expand gamepad support further
  • Collect a library of well working controller configurations(Please share working /sd/arcade.cfg and arcade1&2.py files with the name and type of controllers in the issues section)
  • Silent start, verbose option and/or log file
  • Support and install script for RecalBox
  • Attempt to include as scriptmodule in RetroPie-Setup and as an included system in Recalbox?(Going to be needing some help with this, anyone up to the task?)
  • More command line options;
  • Make more generic as a launcher for other games needing controller mapping?

Mentions