Thursday, September 30, 2010

Binary Translation, Emulation and Decompilation

Here's a link to an interesting article outlining the choice between binary translation and emulation. It might help convey why I'm taking a radical approach in porting OutRun and not automating binary translation. As mentioned, binary translation certainly has its uses in producing code that can be hand optimised and altered. However, it ultimately results in code that is also unwieldy and in hard to decipher.

Even in cases where the original source code is available and can be translated by a tool, the results are often no better. I've worked with C code, automatically translated from 68k assembler, for a number of games during my days as a mobile developer. Often the output from such tools didn't resemble the target programming language in a meaningful manner.

Although decompiling and manually rewriting OutRun is a massive task, hopefully the end results will yield code that is understandable, portable and easy to enhance. By the end of the year, I will have completed the decompilation phase and commented an estimated tens of the thousands of lines of assembler. Maybe the end results will be superior to the original source code in areas. It's hard to say, as I don't have access to it!

One of the more gruelling aspects of the decompilation is the sheer amount of code. For example, I'm currently commenting code that controls the animation relating to smoke, dirt and other debris emitted from the Ferrari's wheels. The animation format and code to handle these routines differs yet again from all previous examples. I've lost count of how many animation formats the game contains.

One of the reasons the code is so bulky is that the programmers have seemingly reinvented the wheel for various aspects of the game. It wouldn't be difficult to code a generalised animation system, at the expense of a small amount of speed. As it is, many high-level features share little in terms of code or design despite relying on the same low-level routines. This results in a lot of code duplication.


bluepillnation said...

This is really cool information. All I can imagine is that because OutRun was quite an early game on this particular hardware set, the focus was on getting it out the door rather than optimising it to the Nth degree.

Also, you've already shown that code from other games (Space Harrier) has definitely ended up in the OutRun codebase. It's possible that a programmer had something that worked and so they reused where possible, but still wrote new code if they couldn't find something that would work with what they were trying to achieve.

Although the game is not as much fun, I note that the scaling in Turbo Outrun seems somewhat smoother than the original by comparison, so maybe by 1988 they had mastered the hardware a little more.

yt said...

I think the most underused feature of the OutRun hardware, from a gameplay point of view, was the road splitting.

Would have been awesome for the road to split and rejoin at multiple points of the level.

Also a shame there weren't more wider stages like Coconut Beach - as these are a lot more fun to drive down that the more confined later stages.

Reason for the lack for splits is the fact that they had to be hardcoded and weren't encoded into the level format!

bluepillnation said...

The Autobahn and Alps stages are as wide in places as Coconut Beach - though I guess their motivation was to make Coconut Beach a relatively easy stage to let the player get used to the controls... Though having said that they do throw in that evil S-bend just before the final corner leading to the checkpoint split.

Said S-bend caused me to utter words that should not have really come from the mouth of an 11 year old back at the holiday camp where I first tried to master it!

bluepillnation said...

...and come to think of it, I could swear that the Autobahn stage does indeed split and rejoin at multiple points...

JetSetSkippy said...

The comments echo my sentiments.

Would it be fair to judge the code in such contrasted depth considering the foresight and technological standpoint we have to form criticism?

I would agree getting it out the door was a priority though.

yt said...

@bluepillnation: You're right about Autobahn, I hadn't noticed that.

I quickly replaced Stage 2 with Autobahn, and then made attract mode AI play the game (was too lazy to play).

Now the interesting thing is: the attract mode code can't handle the lane split in the level! On the straights it's fine, but as soon as there's a bend - it crashes into the central reservation.

Normally, the attract mode code is fixed to never choose the Autobahn route (this is hard coded), so this isn't apparent to the user.

I wonder if this had anything to do with the decision?

yt said...

Oh, and just to clarify, it seems that Coconut Beach was fudged to work around this limitation...

bluepillnation said...

Ooh - fudged how? (if you don't mind me asking)

Very intriguing that the attract mode is hard-coded to avoid Autobahn - wonder if it's the same in the JP version (Autobahn being a different part of the course there)?

yt said...

@bluepillnation. OK, I've looked into the Japanese version code and I can confirm the same AI route choices are made (in terms of turning left and right at the fork).

These are:
Stage 1: Turn Left [Wheat Field]
Stage 2: Turn Right [Alps]
Stage 3: Turn Right [Gateway]
Stage 4: Turn Left [Desolation Hill]

By fudge, I really just mean that there is no specific AI code to handle the road split. Coconut Beach just doesn't trip the AI up.

bluepillnation said...

So it's possible that the AI path wasn't designed to avoid Autobahn as such... Let's face it, the graphics were pretty sumptuous by 1986 standards and had significant "wow" factor even if the player's Testarossa kept stacking it into the central reservation! ;)

Couple of things I think I remember, though - but it may be my memory playing tricks on me:

- A collision with a non-player car at the point where the road forked could sometimes send the AI down a route other than that which was intended

- When the AI route circled back around to Coconut Beach, thus starting the player car at a different X point on the road from where it starts in the game, the player car could indeed crash into the central reservation at the start of Coconut Beach

Like I say, these may be completely erroneous recollections, but I did spend a lot of time around the coin-op that particular summer - making it a nemesis of sorts!