Armapitron

a Tron Clone in 3d.
Armagetron Advanced.
Now on the Raspberry Pi.

Download now »

Introduction

Yes, a Tron Clone in 3d.

Armagetron as it's been succinctly put, is a Tron Clone in 3d. It replicates the lightcycle sequence of the movie Tron as an immersive playable game. A game that's been enjoyed by all ages for years. This port to the Raspberry Pi aims to continue that tradition for a new generation of players.

Credit where credit is due, I didn't do this all by myself. In fact, what I've done constitutes the smallest fraction of the work. So please, give thanks to Voodoo who did the hard work of porting the OpenGL engine to OpenGL ES, and to the rest of the Armagetron Advanced development team who have contributed to the project over the years. And of course, don't forget Z-man.

Action shots

Armagetron in motion...

Downloads

This is the important bit right here.

This is a release of Armagetron Advanced 0.2.8.3.2 for the Raspberry Pi. The code is released under the GNU General Public License, so the source is available too!

Holy smokes Batman, it's the memory split!

In order to play Armagetron, your Pi needs to have 128 MB of RAM allocated to the GPU. The default is 64 MB so you may have to change this. This is the gpu_mem setting in the config.txt file.

gpu_mem=128

You can also change this setting with the raspi-config program

sudo raspi-config

Select "8 Advanced Options" "A3 Memory Split" and then enter 128.

Installing

A bit more direction to help get started.

Well... Not so much installation as running the software. These directions are for Rasbian. As far as I know, all the libraries needed by Armagetron are installed by default. However, if by some chance they are not, the first step would be to install them:

sudo apt-get install libsdl1.2debian libsdl-image1.2 libsdl-mixer1.2 libxml2

Hopefully that will have produced a list of "is already on the newest version" and so you may proceed onto the next step, which is extracting the game:

tar jxvf armagetronad-0.2.8.3.2_dist.tar.bz2

A bunch of text looking like a file listing should have just flashed past. At this point you're practically set to run! What comes next is what you'll have to do every time.

cd armagetronad-0.2.8.3.2
./armagetronad_main

There you go! The first time the game runs it will ask about language. This can also be changed later. Go to "Play Game" "Local Game" to get started! Z turns left, X turns right. Try not to crash! If the graphics are frozen once you start the match, check your memory split.

Compiling

So you want to start out from scratch eh?

Right. This time you definitely need to install things. By default GCC, the compiler, is already installed with Rasbian. This is a good start, but we need a bit more.

sudo apt-get install build-essential g++-4.7 libsdl1.2-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libxml2-dev automake

This installs the headers and libraries needed to compile Armagetron. The eagle eyed among you may have noticed build-essential and g++-4.7 in there and those aren't libraries. Correct, that makes sure the bare minimum for compiling is installed and also pulls in the newer version of GCC and friends. The latter produces slightly better code and we want all the help we can get. In order to take advantage of it we need to tell the system to use it though. Debian doesn't have a default way to do this but a kindly fellow has written a script for it, which we can download and run:

wget https://dl.dropboxusercontent.com/u/15313414/Blog/gcc-set-default-version
bash gcc-set-default-version 4.7

At this point we can extract the code, enter the Armagetron directory, and it's compile's away! I've created a script to replace the standard ./configure that specifies the appropriate code optimizations for the Pi.

tar jxvf armagetronad-0.2.8.3.2_src.tar.bz2
cd armagetronad-0.2.8.3.2
./bootstrap.sh
./myconfig.sh
make

Go ahead and grab a cup of tea now. This will be about half an hour. But when it's done you can now run the version you yourself compiled!

./src/armagetronad_main

Code Changes

I'd like to understand what's happened!

Wouldn't we all? I mean, what are we here for man? What's the meaning of life? Oh, you meant the code? Sure. Yeah. Just a sec. *cough*

This is both simple and complex. I'll explain what I've done in general and then move onto some more specific details. As I mentioned in the introduction, Voodoo ported the game's OpenGL to OpenGL ES. This was a translation of the directions of what the pictures on the screen should look like from say Italian to Spanish. Related, sure, but not quite the same thing.

That was a really great start. The work was part of a project to get Armagetron running on the iPhone. He actually succeeded, but was unable to release the game for performance and licensing issues. Apple does not like open source, but Voodoo does, so he made most of his work available, fortunately for us. I downloaded that and wrote a patch on top of it to work with OpenGL ES on the Raspberry Pi and link with the Broadcom libraries. Unfortunately for us, Voodoo did all his work on a fairly old version of 0.2.8. 5 years old from now, 2 years older than 0.2.8.3.2, which is the newer code version I had to port his OpenGL ES work as the final step to producing something I could share.

More detail

Great, but what did you actually do?

My changes can be broken down into three categories:

  • Changes so that it would compile with the Pi's implementation of OpenGL ES;
  • Bug fixes to deal with the graphics going mental under OpenGL ES; and then
  • Porting all of the OpenGL ES changes, including Voodoo's work, to the 0.2.8.3.2 code base.

The first step was to learn how to do OpenGL ES on the Pi. Documentation there is surprisingly thin on the ground, but eventually I cobbled together a simple bouncing cube program that had all the essentials. Fortunately I already knew some OpenGL from my work on Androgetron, which while not Armagetron, did use OpenGL ES under Java. The critical pieces are establishing the EGL context, initializing SDL solely for input, and re-implementing the gluPerspective function. (It isn't part of OpenGL, and is definitely not part of OpenGL ES. Hello GLU!)

After learning how OpenGL ES worked on the Pi, the next issue was transplanting that into Voodoo's Armagetron code. Fortunately I've done some Armagetron programming before so I had a rough idea of what I was doing there. gArmagetron.cpp is where the main() function is at, and it was just a matter of hacking out the normal display init function (sr_InitDisplay()) that would take place and replacing it with the OpenGL ES initialization code for the Pi. eglSwapBuffers() had to be added in with the regular OpenGL swap function so that the display would update. The resolution determination from the Pi also had to be connected to the screen resolution variables sr_screenWidth and sr_screenHeight. I also had to add the relevant headers in.

Outside of the regular code, on the automake side of things, the configure.ac file had to be edited to remove checks for OpenGL and GLU that were patently going to fail anyway. Linking to the Broadcom libraries was achieved through CPPFLAGS and LIBS environment variables to the configure script. Half an hour later for compile and voilĂ ! It worked! I almost couldn't believe it. Of course, nothing is perfect. If you've watched my video above, that's how it looks out of the box with only those code changes applied.

So it was time for bug fixing. Primarily centered around texturing. Double floor texturing causes problems, so the default is now single texturing. OpenGL ES appears to be unable to handle anything other than RGBA textures, so not only did all of the textures have alpha channels added, the code had to be hacked to stop the automatic stripping of the alpha channel that takes place to save memory. The textures also needed to be in power of 2 sizes (256, 512, 1024, etc.). OpenGL ES has these quirks... Cycle coloring was also going mental. I can't quite remember why what I did fixes it, but it does. Just for tidiness I also removed the options for changing resolution from the configuration menu. They don't do anything now (the game is full screen only) so why tempt fate.

The final step before release was porting all of this onto the 0.2.8.3.2 codebase instead of Voodoo's 2 years out of date Revision 1015 code. Fortunately this was fairly straight forward. (But it could have been awful!) I checked out a clean copy Revision 1015, ran a diff on Voodoo's+My changes to create a patch file, which I then applied to a clean 0.2.8.3.2 source tarball. Fortunately the conservative nature of the 0.2.8 branch of Armagetron code meant nothing too major happened in this period, particularly with the rendering code, letting the patch apply more or less cleanly. There were only like 3 places where I had to manually tweak the code to get everything applied. This is where the luck comes in, because this could have been really, really bad.

And there we are! End of story and the change I made. I've got two patches available to highlight the code changes:

Known Bugs

Yikes! It's supposed to do that?

Well, no. Probably not. As far as I know there are two definite bugs and potentially a third one.

  1. Sound stutters.
  2. ALSA is experiencing a buffer under-run. It tries to play sound faster than the game produces it. I think this is a combination of high CPU load from the game along with poor disk and audio performance. I'm not sure there's anything I can do about it.
  3. I can't chat.
  4. Got me there. This is a genuine bug that I'm pretty sure is soluble, I just haven't had the time. Patches welcome!
  5. FPS (maybe) drops the longer I play.
  6. The game in general is sensitive to this, but the Pi appears to be particularly so. The longer a round continues (the more walls there are) the more the FPS will drop. On the Pi I think most of the performance hit comes from CPU limits rather than rendering limits, but the latter doesn't help. Over-clocking may improve things some. The game has already been compiled with optimizations so squeezing any more performance out is a big task.