Linux Gaming: Running The Original StarCraft on ODROIDs

Did you know you can run the original StarCraft on your ODROID? If not, please let me tell you how it works, at least if you have an ARMHF-based ODROID such as the ODROID-XU4, C1, or U3. This is actually nothing new, and I’ve known about it for years now, but it has stayed under most ODROID users’ radar. Let’s start with the things you need to get things working and later talk about why it works, how it works, and what the limits are, if there are any.

Requirements

  • Windows PC to install StarCraft
  • An ODROID running an ARMHF image, such as the ODROID-XU4 with Debian or Ubuntu
  • Internet connection to download and install drivers and packages to run StarCraft
  • StarCraft + Brood War installation CDs (NOT the installer from Blizzard, but the original CDs or CD images)

Preparing the game folder

Generally this is not a hard task, and what you need are your original CDs (or CD images) for StarCraft along with the Brood War expansion. Since by now Blizzard offers a free online installer for StarCraft and Brood War, some might argue it’s even legal to download the ISO files if you don’t have the game yourself. Keep in mind though, that you need the CDs or CD images of the ORIGINAL StarCraft with the Brood War addon, and NOT the online installer from Blizzard. Once you install the game and the addon, you also need to patch it to version 1.16.1 (for example, from https://www.moddb.com/games/starcraft/downloads/starcraft-brood-war-v1161-patch). This is very important as it will only work with this version. Once you have installed the game, addons, and the patch, there are two more steps you need to perform. On your StarCraft CD (ISO), you will find the file install.exe which is about 600MB in size. Copy that file to the installation folder of StarCraft, and rename it StarCraft.mpq. After that, insert the Brood War CD (ISO) and copy the install.exe from here as well, then rename it into BroodWar.mpq. This step is very important, since it’s required to play the game without CDs. The resulting folder should be about 1.3 GB in size. Copy that folder over to your ODROID.

Installing requirements and game binaries

Once you’re done, there are two things you need to run the game. First, you need to download the binaries needed to run the game and extract them into your game folder. These binaries were made by notaz, which is a developer from the OpenPandora project who has brought us impressive tools like:

  • PCSX ReARMed – Playstation 1 emulator for ARM devices
  • PicoDrive – A very fast Sega emulator especially for the Sega 32X

Go into the StarCraft game folder on your ODROID, and run the following command which will download and extract his binaries for StarCraft:

$ wget https://notaz.gp2x.de/misc/starec/libscr.tar.xz -O- | tar xJ
Then you need to install Wine to run the game:
$ sudo apt install wine
After this, all requirements are installed and in place and we can try out the game.

Starting StarCraft

To run, StartCraft you need to to change into your StarCraft folder and run the following command:

$ LD_LIBRARY_PATH=. setarch linux32 -L wine libscr_sa_arm.exe.so
If you’ve done everything right, after a short moment of loading, StarCraft should start up and run in all it’s 640x480 glory.

Figure 1 - Booting up StarCraft on an ODROID
Figure 1 - Booting up StarCraft on an ODROID

Figure 2 - You can play both StarCraft and Brood War
Figure 2 - You can play both StarCraft and Brood War

Please keep in mind the game was designed to run on a 4:3 display and in a 640x480 resolution which is what the game will start and run on. If you have an ODROID that can change the screen resolution on the fly, like the ODROID X, X2, U2/U3, or XU3/XU4, the screen will change to 640x480 (if supported by your monitor/TV) and run just as a native application would. If you run it on an ODROID that can’t change display resolution, like the ODROID C1, you might look at a very tiny picture with a lot of black space around it.

Optimizing our setup

While now we can play StarCraft already, it’s quite inconvenient to start the game this way, and I would much rather have a StarCraft symbol to double click and start the game instead. So let’s put in a little bit of effort and make the installation pretty.

Extracting Icons

First we need one of two tools to extract the icons from the StarCraft.exe file. Either we install “icontool” or “7zip” to extract icons from and .exe file. We also need “imagemagick” to convert the icons. Since, in my opinion, 7zip is more universal helpful (it’s a file compressor/decompressor, after all) and is probably installed on your system already, I prefer that method. Just to make sure, let’s install it and then extract the icons.

$ sudo apt install p7zip-full imagemagick
$ 7z x StarCraft.exe .rsrc/ICON
$ mv .rsrc/ICON .
$ rm -r .rsrc
You should find a folder called ICON in your StarCraft folder, in which you can see the icons that the game offers us to use. We can choose any of these icons to create our start icon for the game. I personally prefer the one called “modern 9.ico”, but some might prefer the more “classic 14.ico” instead. Depending on what you like, we now convert the new icon in something more usable for us:
$ convert ICON/9.ico StarCraft.png
Now we should see a nice StarCraft.png file in our StarCraft folder.

Create a desktop shortcut

At this point, I’m going to assume that your game is located in a folder /home/odroid/StarCraft, so please adjust this in the lines below accordingly if it’s at a different location. Now we can create a script to start our game. Open your favorite text editor and enter the following lines:

#!/bin/bash
cd /home/odroid/StarCraft
LD_LIBRARY_PATH=. setarch linux32 -L wine libscr_sa_arm.exe.so
Save the file as StarCraft.sh in your StarCraft games folder, and make sure we can start it with the following command:
$ chmod +x StarCraft.sh
Next we need a .desktop file which we can use to start our game. Open your favorite text editor again and create a new file with the following content:
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Exec=/home/odroid/StarCraft/StarCraft.sh
Name=StarCraft
Icon=/home/odroid/StarCraft/StarCraft.png
Save this file as StarCraft.desktop on your Desktop (/home/odroid/Desktop/StarCraft.desktop). The last step is to make the file executable again:
$ chmod +x /home/odroid/Desktop/StarCraft.desktop
You should now see a new Icon called StarCraft on your desktop, and when you double click it the game should start.

Figure 3 - This brings back memories of one of my favorite games of all time
Figure 3 - This brings back memories of one of my favorite games of all time

Figure 4 - StarCraft plays as well as it played 20 years ago
Figure 4 - StarCraft plays as well as it played 20 years ago

Optimizing performance

You might notice some slight lagging here and there, which is due to the fact that by default, Wine tries to use OpenGL to enhance the gaming experience for rendering the windows. ODROIDs don’t have OpenGL, and it’s really not needed for this game, so it’s best to disable it entirely. For this we just need to install winetricks and run a single command:

$ sudo apt install winetricks
$ winetricks ddr=gdi
With that, the game should run very smoothly on your ODROID. (Optional) running in window mode You might not like the game to change your screen resolution to 640x480, or your TV (or ODROID) does not support the switching to 640x480. For this, there is an option to run your game embedded into a window instead. On the command line, run the following command, which will open a wine config window:
$ winecfg
Switch to the tab “Graphics” and check the checkbox next to “Emulate a virtual desktop”. This will run your game directly on your desktop in a window. Since the window will still be just 640x480, I suggest you use a smaller desktop resolution such as 1280x720 for example. That way, the window will not seem so lost on the big screen. With this, you now have everything you need to run StarCraft on your ODROID. You can either run it in fullscreen in 640x480, or in a window on your desktop. We now have a nice shortcut on your desktop that we can use to play the game whenever we want. At this point, you should have a fully working StarCraft and Brood War experience. Everything is there: videos, music, sound, levels, with all the campaigns and individual levels you want to play. If you’re content with this, you can stop reading here, since what follows now is just technical background on how this works, why it uses Wine, and why it doesn’t run on ARM64 images (for example, on the ODROID-N2 or C2).

Figure 5 - Configure wine to run in a virtual desktop so we don’t need to switch resolution on our Monitor / TV
Figure 5 - Configure wine to run in a virtual desktop so we don’t need to switch resolution on our Monitor / TV

Figure 6 - Running StarCraft in a Window directly on the desktop, keep in mind the window is only 640x480 and can’t be changed
Figure 6 - Running StarCraft in a Window directly on the desktop, keep in mind the window is only 640x480 and can’t be changed

How it works

I want to explain how this works, including why the game runs on ARMHF based ODROIDs but not on ARM64 ODROIDs, specifically what Wine is used for, and the purpose of the file that we downloaded and extracted. Wine – (W)ine (I)s (N)ot an (E)mulator There is still a misconception about wine. That it will allow you to run Windows programs and games under Linux by emulating a Windows Machine. This is not true: Wine does NOT turn your ARM Linux into an x86 Windows system! Wine is a Windows-API re-implementation, which means that the commands that a Windows .exe file is sending to the Windows OS and the CPU are translated into Linux code that runs under Linux. Imagine it like this: If a Windows .exe file has a code that says “open a new window of the size 100x100 pixel” this code will be translated into a Linux command that does the same thing, creating a new window that has 100x100 pixel. The Windows API code used for this is rewritten to do the same under Linux. However, it’s a little bit more complex than that. At the basic level, we have binary code, which means that the .exe file was written for a specific CPU architecture. In the case of Windows, it’s either written for 32-bit processors (x86 code) or 64-bit processors (x86_64, also known as amd64). Linux has the same thing: a binary file is either for 32-bit x86 Linux or 64-bit x86_64 Linux. Since 64-bit processors can run 32-bit code normally, if you have 32-bit drivers installed, you normally can run 32-bit code as well, which is why most Windows applications are still 32-bit although they run on a 64-bit processor. Also, many old applications, such as StarCraft for example, were written when only 32-bit processors existed, so obviously it’s a 32-bit (or x86) binary. Now ODROIDs have neither an x86 nor a x86_64 processor. They have ARM processors running either on an 32-bit ARMHF or 64-bit ARM64 Linux, and this is where the trouble starts. A 32-bit x86 Windows application requires a 32-bit x86 wine installation to convert the code into 32-bit x86 Linux code. A 32-bit ARMHF wine installation can only translate 32-bit armhf Windows code into 32-bit ARMHF Linux code (the same goes for arm64 code). Which means that in order to run x86 StarCraft on ODROIDs, ODROIDs would have to run an x86 version of Wine, but since ODROIDs are ARM boards, this is not possible, unless you use x86 emulation on ODROIDs, which tends to be rather slow. It would work if there was an ARMHF version of StarCraft, because if there were a 32-bit ARMHF StarCraft.exe for Windows, we could run that under an ARHF wine version. Unfortunately, there never was an ARMHF version of StarCraft, nor has there ever been an ARMHF Windows version for which there are any programs or games in existence (if you ignore Windows Phones, which do not run a full version of Windows).

Why does it work?

This is where notaz comes into play, since he did exactly that: he created an ARMHF version of StarCraft. If you check the game folder, you will notice that there are only a few binary files for StarCraft (.exe or .dll files), and some are for the editor and can be ignored, since we don’t use the editor. The rest relates to StarCraft.exe and some libraries that are used to run the video files. Notaz “disassembled” the code of these binary files. For those who do not know what this means, there is a programming language called “Assembler” which is very close to how a processor actually works and hard to understand or read:

# -----------------------------------------------------------------------------
# A 64-bit Linux application that writes the first 90 Fibonacci numbers. It
# needs to be linked with a C library.
#
# Assemble and Link:
# gcc fib.s
# -----------------------------------------------------------------------------

.global main

.text
main:
push %rbx # we have to save this since we use it

mov $90, %ecx # ecx will countdown to 0
xor %rax, %rax # rax will hold the current number
xor %rbx, %rbx # rbx will hold the next number
inc %rbx # rbx is originally 1
print:
# We need to call printf, but we are using eax, ebx, and ecx. printf
# may destroy eax and ecx so we will save these before the call and
# restore them afterwards.

push %rax # caller-save register
push %rcx # caller-save register

mov $format, %rdi # set 1st parameter (format)
mov %rax, %rsi # set 2nd parameter (current_number)
xor %rax, %rax # because printf is varargs

# Stack is already aligned because we pushed three 8 byte registers
call printf # printf(format, current_number)

pop %rcx # restore caller-save register
pop %rax # restore caller-save register

mov %rax, %rdx # save the current number
mov %rbx, %rax # next number is now current
add %rdx, %rbx # get the new next number
dec %ecx # count down
jnz print # if not done counting, do some more

pop %rbx # restore rbx before returning
ret
format:
.asciz "%20ld\n"
Assembler mainly works on CPU registers, which is also why the code is very processor-dependent. A 64-bit CPU register won’t fit in a 32-bit CPU register, hence a 64-bit command cannot run on a 32-bit processor. This code is much harder to understand than, for example, C or C++ code, and as I said, it does not run on a foreign CPU architecture. However, there are equivalent calls on a different CPU architecture. Comparing two registers in Assembler is the same on ARM as it is on x86, except that the registers are different. Some code that exist for x86 does not exist the same way under ARM, but the same result can be achieved in a different way. What this means is, if you put a LOT of effort into translating the disassembled Windows x86 binary code into ARMHF binary code, you end up with an ARMHF Windows binary that does the same as the x86 binary did, except for ARMHF. This is roughly what notaz did, plus some extra stuff. The result are the binaries that we downloaded from him which are available at https://notaz.gp2x.de/misc/starec/libscr.tar.xz. With that, we have ARMHF Windows binaries, that we can now run on ARMHF Wine in order to translate the API calls to Linux code, resulting in the ability to run StarCraft on ODROIDs.

Why does this not work on the ODROID-C2 or N2?

If you have followed my explanation, you should know why it doesn’t work. We only have ARMHF StarCraft binaries that run on an ARMHF version of Wine. The ODROID-N2 and C2 run a 64-bit ARM64 operating system, and their Wine version is an ARM64 version as well, which doesn’t run ARMHF Windows binaries. So you might ask yourself, since ARM64 CPUs are technically able to run ARMHF code, would it work if the ODROID-N2/C2 ran an ARMHF version of Wine? The answer to that is: YES! If you run an ARMHF operating system on your ODROID-C2 or N2, you could run StarCraft as well. It should even work if you add ARMHF as a foreign architecture to your image and install the ARMHF version of Wine, but to be honest, I haven’t tried it yet.

Be the first to comment

Leave a Reply