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.
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).
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.
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.
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 messagesWINEDEBUG=+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
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.
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 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.
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.
Great job