ARCH R

PortMaster

Running native game ports on the R36S

PortMaster is a catalogue of game ports built for handhelds like this one: open source engine reimplementations, Godot and Love2D games, and PC binaries wrapped so they run on ARM. It comes installed.

Ports are not emulation. Each one is a real program running on the console, so what works and how well is decided port by port.


Opening it

EmulationStation → Tools → Start PortMaster.

The first run unpacks PortMaster into /storage/roms/ports/PortMaster/ and copies over the pieces ArchR maintains: control.txt, mapper.txt, mod_ArchR.txt and the controller database. It also hides the PortMaster folder from the Ports game list, so you see your ports and not its internals.

Everything after that is PortMaster's own interface. Browse, install, and the port shows up as a .sh launcher in the Ports system, next to a folder with its files.

If Ports is not on the home screen yet, that is because it is still empty. It appears once you have installed something, or right away if you turn on Show empty systems in Game Collection Settings.


What ArchR provides for ports

PieceWhat it is for
box86, box64Running x86 and x86_64 binaries on ARM
32-bit libraries in /usr/lib32The 32-bit side that box86 ports need
/usr/lib/compatOlder library versions that ports built for Debian expect
gptokeybTurns joypad input into keyboard and mouse events
oga_controlsThe older input helper, for ports that still call it
Python 3 with lzmaUsed by the PortMaster interface and by several ports
mod_ArchR.txtSourced by PortMaster, sets the library paths and screen size options for this system

/dev/uinput is world-writable through a udev rule, which is what lets gptokeyb create its virtual keyboard.

The controller mapping a port sees is generated from your EmulationStation configuration by mapper.txt at launch, so a port inherits whatever pad setup the rest of the system uses.


Running a port

Select the launcher in Ports and press A, the same as a game. What happens around it:

  • Syncthing, Tailscale, ZeroTier and the file-sharing server are stopped for the duration, and only the ones that were running are started again afterwards.
  • The Bluetooth agent is stopped and restarted.
  • Kernel same-page merging is paused, because on a Cortex-A35 it shows up as frame-time spikes.
  • The CPU governor goes to performance and the GPU is pinned at its highest frequency.
  • The port runs at high priority.

Exiting is the port's business, not the system's. Most use a hold on START or a combination documented in the port's own description. L1 + SELECT + START force-quits anything that will not close on its own.


Ports that need the original game

A lot of ports are the engine only, and you supply the data files from a copy you own. PortMaster tells you which files are missing and where they go, per port. Drop them into /storage/roms/ports/<port>/ over SSH or Samba.


Performance

The RK3326 has four Cortex-A35 cores and a Mali-G31. It is a slow chip by design, and the difference between tiers is large:

  • Ports built natively for ARM run best. Most Godot, Love2D and SDL games in the catalogue are in this group.
  • Ports that go through box86 or box64 pay a translation cost on top. Some are fine, some are not, and the port's own notes are more reliable than any general rule.
  • Anything expecting a discrete GPU is not going to work here.

PortMaster labels each port with the hardware it is known to run on. That label is worth more than a guess from the specs.

If a port is close but not quite there, System Settings → Enable CPU Overclock unlocks the 1512 MHz operating point. Without it the CPU tops out at 1416 MHz. It is off by default, it costs battery and heat, and it is honoured during gameplay rather than forced on.

The same menu has Default GPU scaling governor if you want the GPU pinned outside of games too.


Troubleshooting

A port opens to a black screen and nothing happens. Read /var/log/exec.log, which holds the output of the last launch. Most black screens are a missing data file or a missing library, and the log names it.

Input does nothing. The port is probably waiting on gptokeyb. Check that /dev/uinput exists and is writable (ls -l /dev/uinput).

The port complains about a library version. It was built against something newer than what is in /usr/lib/compat. Report it to the port's maintainer through the PortMaster community, since the fix belongs in the port.

PortMaster itself will not open. Run /usr/bin/start_portmaster.sh over SSH and read what it prints. The script is safe to run again, it recopies its files each time.

A port you deleted is still in the list. EmulationStation caches the game list. Game Collection Settings → Update gamelists, or restart the frontend.


Where things live

/storage/roms/ports/
├── PortMaster/            the interface and its helpers, hidden in the game list
├── <PortName>.sh          the launcher you see in ES
├── <PortName>/            the port's own files
└── gamelist.xml

/storage/.config/PortMaster/
├── control.txt            paths and device profile, sourced by every port
├── mapper.txt             builds the controller mapping at launch
├── mod_ArchR.txt          the system-specific hooks
└── gamecontrollerdb.txt

To remove a port, delete its .sh and its folder, then update the game lists.

On this page