Skip to content

Instantly share code, notes, and snippets.

@JeodC
Last active March 17, 2025 21:05
Show Gist options
  • Save JeodC/aa89f7b387d9dd7976d39bf585e471fd to your computer and use it in GitHub Desktop.
Save JeodC/aa89f7b387d9dd7976d39bf585e471fd to your computer and use it in GitHub Desktop.
A beginner's guide to creating wine ports for the Ayn Odin 2, Retroid Pocket 5, and Retroid Pocket Mini

Rocknix Wine Ports

Using wine is a deep rabbit hole for anyone not familiar with the software, and an even deeper rabbit hole when combined with box86 or box64. This guide attempts to serve as a basic introduction to using the built-in wine and box packages included with Rocknix on a Retroid Pocket 5. While the Retroid Pocket Mini is a similar setup chain, it is weaker hardware than the Retroid Pocket 5 and thus the examples provided here may not function as well.

Terminology - Wine and Box86/64

The first thing anyone should understand is the vernacular used throughout this guide. Two tools are used to make wine ports possible on ARM64:

  • Box86 and Box64 by ptitSeb are Linux x86 and x86_64 emulators targeting AARCH64/ARM64 architecture.

  • Wine is a software that allows Windows programs to run on Linux systems. Prebuilt wine binaries can be downloaded from the wine-builds GitHub page.

The program flow thus becomes Game -> Windows -> Wine -> Box -> ARM64. Rocknix generally keeps their packaged binaries updated, however it is entirely possible to use our own versions.

To get started, we need to load Rocknix onto our Retroid Pocket 5 system. Rocknix releases can be found on their GitHub page. Alternatively, on the Rocknix Home Page we can join the community Discord server, where we can locate nightly builds in the #dev-builds channel (must be a developer).

Unity and Wine

PortMaster already brings a lot of games to ARM64 systems, but one of the game engines consistently withheld (and for good reason) is Unity. Unity Engine demands a lot of processing power and memory, so weaker handhelds like the popular Anbernic RG35XXH and the R36S stand no chance to run Unity games. In order to run a Unity game, we need to gather a few dependencies. Remember, wine is a small Windows container, so whatever a game would need to run in Windows, we need to add via wine.

For this example, we are running Box64 v0.3.4 and Wine 10.3 amd64 which is multiarch (no wine64 binary).

* It may be helpful to have a usb-c to usb-a dongle and a wireless mouse handy during setup.

Example: TUNIC

Let's begin with our framework, the Tunic.sh launch script. Open a text editor (I favor Notepad++) and save a new file Tunic.sh. We'll piggyback off of PortMaster as a base so we can borrow their environment variables.

#!/bin/bash

if [ -d "/opt/system/Tools/PortMaster/" ]; then
  controlfolder="/opt/system/Tools/PortMaster"
elif [ -d "/opt/tools/PortMaster/" ]; then
  controlfolder="/opt/tools/PortMaster"
else
  controlfolder="/roms/ports/PortMaster"
fi

source $controlfolder/control.txt
[ -f "${controlfolder}/mod_${CFW_NAME}.txt" ] && source "${controlfolder}/mod_${CFW_NAME}.txt"
get_controls

# Variables
GAMEDIR=/$directory/windows/tunic
EXEC="Tunic.exe"

This is fine to start with, but notice that we are pointing to our game directory as ports/tunic. We need to create our game folder next. In the same place we created our Tunic.sh file, create a new folder named tunic. Inside that folder, create two more folders--one called data, and one called config. Finally, create a new file called tunic.gptk and paste the following inside:

back = \"
start = \"
a = \"
b = \"
x = \"
y = \"
l1 = \"
l2 = \"
r1 = \"
r2 = \"
up = \"
down = \"
left = \"
right = \"
left_analog_up = \"
left_analog_down = \"
left_analog_left = \"
left_analog_right = \"
right_analog_up = \"
right_analog_down = \"
right_analog_left = \"
right_analog_right = \"

The gptk file is what works with GPToKeyB. It's a GamePad to Keyboard emulator, so if any games require a mouse or lack native gamepad controls, we can still play our games. Your file tree should now look like this:

│   Tunic.sh
└───tunic
    │   tunic.gptk
    ├───config
    └───data

Let's continue with our Tunic.sh file. Next we need to enter our game directory and ensure we record a log so we can troubleshoot if something goes wrong. Add the following next:

# CD and set log
cd $GAMEDIR
> "$GAMEDIR/log.txt" && exec > >(tee "$GAMEDIR/log.txt") 2>&1

Notice the hashtag (#) which denotes a comment in bash. This makes it easy for us to section our script and return to it later if need be, and also makes it easy to cut out and borrow common sections for later use in other wine ports. If you're curious what precisely any part of our script does, toss it into ChatGPT and ask. In short:

  • Change directory to $GAMEDIR (the variable we defined earlier)
  • Create a log file (remove all contents if file exists)
  • Redirect standard output and error to the log file
  • Set file permissions here if necessary

The next portion of our script has to do with displaying a splash image while the game loads. This is a courtesy so the user doesn't stare at a black screen wondering if their game is frozen at boot.

# Display loading splash
$ESUDO $GAMEDIR/splash "$GAMEDIR/splash.png" 30000 & 

This simply runs a file called splash with the argument $GAMEDIR/splash.png and the time in milliseconds, and the ampersand (&) at the end tells the script to continue executing and not wait for the timer to end.

Environment Variable Exports

We've come to an important section of our Tunic.sh launch script, the Exports section.

# Exports
export SDL_GAMECONTROLLERCONFIG="$sdl_controllerconfig"
export WINEDEBUG=-all

These few lines are extremely important. The first line identifies our gamepad so SDL correctly maps the physical buttons to what the game expects them to be. The second export has to do with logging. WINEDEBUG controls the debugging output generated by wine. By default, we can easily generate an impressively large $GAMEDIR/log.txt file, with a lot of bloat. The following are some common uses for the WINEDEBUG export:

  • WINEDEBUG=-all: Suppresses all debug messages
  • WINEDEBUG=+d3d,+wgl,+opengl,+vulkan: Debug issues with Direct3D, the Windows Graphics Layer, OpenGL, and Vulkan.

We can add one more export to our list, but we'll get to its meaning later.

export DXVK_HUD=1

Lastly, we need to set up our wine prefix and architecture. Notice that in the variables section above we set EXEC="Tunic.exe". We'll use that here to determine what wine prefix and arch to use.

# Determine architecture
if file "$GAMEDIR/data/$EXEC" | grep -q "PE32" && ! file "$GAMEDIR/data/$EXEC" | grep -q "PE32+"; then
    export WINEARCH=win32
    export WINEPREFIX=~/.wine32
elif file "$GAMEDIR/data/$EXEC" | grep -q "PE32+"; then
    export WINEPREFIX=~/.wine64
else
    echo "Unknown file format"
fi

If we were to manually use file Tunic.exe we would get the following:

Tunic.exe: PE32+ executable (GUI) x86-64, for MS Windows, 7 sections

The PE32+ tells us this is a 64-bit game and so the elif line above will kick in and set our wineprefix to wine64. Winearch is already set to win64 by default, so we don't need to explicitly set it here.

Moving on, we need to install game dependencies. The first time we try to boot a Unity game with wine, we will be told to install wine-mono. A popup will tell us to do this, which is where the mouse comes in handy. If you don't have a mouse, you can use the touchscreen if applicable or temporarily borrow a gptk file from some other port like Clannad and use the joysticks as a mouse to move through the GUI installer. Copy the contents into a mouse.gptk file and put it next to the tunic.gptk file for now.

Back to our launch script, we'll add the following:

# Install dependencies
if ! winetricks list-installed | grep -q "^dxvk$"; then
    pm_message "Installing dependencies."
    winetricks dxvk
fi

Winetricks and Dependencies

Almost every game we try to run with wine will have some sort of middleware requirement. For example, every Unity game needs wine-mono, because that is a replacement for the Microsoft DotNet runtime. Another dependency we need is dxvk, which stands for DirectX To Vulkan. We will use winetricks to install it. Winetricks is similar to a package manager in that it can manage various runtime libraries, frameworks, and settings for applications running under wine. More information can be found at the Winetricks WineHQ Page.

Fow now, all we need is to install dxvk with winetricks and output a terminal message of what we're doing. In other games, we may use winetricks to install specific Visual C++ redistributables.

Wrapping up the launch script

The next step is the configuration directory. Remember that tunic/config folder we made earlier?

# Config Setup
mkdir -p $GAMEDIR/config
bind_directories "$WINEPREFIX/drive_c/users/root/AppData/LocalLow/Andrew Shouldice/Secret Legend" "$GAMEDIR/config"

We use mkdir to create the config directory if it doesn't exist (a failsafe), and then use bind_directories courtesy of PortMaster to link the Windows save directory to our config folder. This way, our savedata is next to the game itself, and if we somehow corrupt our wine prefix, we won't lose our saves. A game's save location can usually be found by checking its PCGamingWiki Page.

Finally, it's time to run our game.

# Run the game
$GPTOKEYB "$EXEC" -c "$GAMEDIR/tunic.gptk" &
box64 wine "$GAMEDIR/data/$EXEC"

We toggle the $GPTOKEYB environment variable and bind our executable to it, so we can use Start + Select to easily quit our game. If this is your first time running wine and you've been following along, rename tunic.gptk to mouse.gptk here. After installing wine-mono, you can change it back.

Can you guess what's happening next? We are telling box64 to run wine, and telling wine to run the Tunic.exe file located in the tunic/data folder.

Finally, make sure your Tunic.sh file is in Unix (LF) line ending format and save it. Copy Tunic.sh and the folder tunic to your roms/ports folder, and then in your tunic/data folder, paste all of the Tunic game data.

The finishing touches

The game should boot and play now, but we're missing our splash screen! I've uploaded this example as a repository, and it includes the splash binary and a splash.png for Tunic. Also, remember our export DXVK_HUD=1 line? When we run the game we'll see a FPS output in the top left corner of our screen. Tunic hovers around 20 FPS with the lowest ingame settings, but we may be able to optimize things further in the future. This is a basic guide, after all. To disable the performance HUD, set export DXVK_HUD=0 or delete the export line entirely.

image

Considerations

Tunic was chosen for the example because it is DRM-free. You may use the GOG, itch.io, or Steam releases and it should work all the same. I tested the game using my Steam release. For games with DRM, such as Steam DRM, you will have to find some way to bypass it--and of course, games with DRM are most likely not going to have distributed port wrappers from PortMaster or Rocknix.

PortMaster and the recognized SBC Community do not condone piracy and will not provide support for bypassing DRM.

@pablotp
Copy link

pablotp commented Feb 27, 2025

Many thanks for this guide! Well-written and way to follow also by beginners.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment