Playing Tomb Raider 1 on OUYA

In 1996, Tomb Raider 1 invented the category of third-person 3D action-adventure games. After nearly twentry years I wanted to play it again, but this time from the couch on TV via my OUYA android gaming console.

It turned out that the game was ported to Android in 2015 and is available in the Google Play store. I asked the Square Enix support if the game supports gamepads or joysticks, and they confirmed that it works at least with the Moga Hero Power and Moga Pro Power controllers. So basic support was there, and the rest would be button mappings - I thought :)


The Google Play store is not available on the OUYA (only the native OUYA store is supported), so I bought the game for 0,99 US dollars on a normal Android phone. Installing it on the OUYA required me to get hold of the game's package file, and I asked the support for the official .apk download URL, telling them the account email I used to buy it. They declined my request:

Unfortunately for security reasons it is not possible for us to advise you how to download the game unless you are using the Play store. If you are unable to do this then it should be possible for you to speak to them regarding a refund.

We are sorry for any disappointment that this may have caused.

Kind regards,
The Square Enix Support Centre team

I tried an APK Extractor app on the phone, which gave me an .apk file of 4 MiB while the original download was 320 MiB.

Then I went the usual route: Use mitmproxy to get hold of the URLs that are called when the phone downloads and installs the game. I used Android-x86 in VirtualBox for this since it was easier than to install the mitmproxy certificate on a real phone.

It turned out to be two files that were downloaded:

The Android package installer installed the .apk file normally, and saved the expansion file at /sdcard/Android/obb/com.squareenix.tombraider1classic/ The Tomb Raider app would show an error message if that file did not exist.


After installing .apk and .obb file I started the game. The copyright notice, then the logos of Square Enix, Core and Realtech-VR appear, and the first frame of the intro video. Then it crashed, and I was back at the launcher.

I sent the log I got via adb logcat to the support, and again got dismissed:

We are sorry to hear that you are having trouble launching Tomb Raider on your OUYA. Unfortunately we cannot provide support on this platform as the game is not distributed on or to the OUYA.

We apologise for any inconvenience this may cause.

Fixing the game


A day later I found a thread on about Tomb Raider Classic, and it gave me an important hint: You can skip the intro movie by hammering the red button on the controller. If you're quick enough and press it within the 100ms window before the movie player crashes, you'll get into the main menu!

It was cool to see the main menu, and I could even start the training session in Lara's home, as well as the normal game - if I managed to skip their intro videos.

Then the screen was filled with the button overlays, and I could use the OUYA's controller touchpad to press them. Apart from the red O button on the controller, no other button, analog stick or the digital pad worked.


So close, but so far away - still the Square Enix support had said there was controller support, and I just had to find out how to make it detect the OUYA controller.

At first I used jadx-gui to decompile the .apk file into nearly-real-java files that I could inspect. The input handling code is at com.realtechvr.v3x.input, and there are three classes:

Gamtel was only activated if your device model was R800i, the input device model contained gametel or if the default device input method class starts with com.fructel.gametel.

The HoneyComb input handler looked more promising; it had a whitelist for controllers for Android versions < 4.3:

At first I pondered how to change the input device name, but that required modifying and re-compiling the kernel, which I did not want to do again.

Then I saw that for Android 4.3 or later, every controller was accepted! The choices I had were:

For simplicity, I chose the last option :)

smali to the rescue

The java code produced by jadx cannot be compiled, so I had to resort to apktool which generates .smali files that contain a plain text version of the Android Dalvik VM byte code .

I quickly found the HoneyCombInputController::isSupported method and the API version comparison code:

    .line 133
    .local v2, "ids":[I
    sget v4, Landroid/os/Build$VERSION;->SDK_INT:I

    const/16 v5, 0x12

    if-lt v4, v5, :cond_0

    .line 135
    invoke-static {}, Lcom/realtechvr/v3x/input/HoneyCombInputController;->initBindings()V

0x12 is the Android version being compared, and I simply changed it to 0x10 (16), which is the OUYA's android version.

I re-packaged the code up with apktool, signed it and installed it via adb on the OUYA.

Then I started it, skipped the intro, and ... it worked! Finally I was able to play the game as it was meant to be! I rejoyced like a child.

Another take on the movies

Now that I knew how to fix things, I checked the movies issue again. The code told me that even when I removed the movie files from the .obb package, the movie player was still initialized and started.

I hoped that preventing the player from being initialized and started also prevented the crash. There was an if statement in the SDLActivity::playFMV method which checked if the Android version was >= 11, and I simply reversed the condition in the corresponding .smali file:

     .line 921
     sget v5, Landroid/os/Build$VERSION;->SDK_INT:I
-    if-gt v5, v6, :cond_1
+    if-lt v5, v6, :cond_1

After building, signing, zip-aligning and re-installing the game on the OUYA I could start it without any crash!


Now that all is done, I could enjoy some hours of discovering the mysteries of caves with Lara:

Tomb Raider menu Menu: Controls Menu: Start new game Tomb Raider: The game has started (without controller support) A wolf A bear Medikit 1996-style mummy A cave

Open issues

During playing I noticed several small problems:

Written by Christian Weiske.

Comments? Please send an e-mail.