Tuesday, April 23, 2013

Sprite Outtakes

You might think that after years of pulling OutRun apart I would have exhausted the hidden extras. Not quite yet! Here are a few unused sprites that are in the game.

Firstly, here's a motorbike that didn't make the final cut. The above is a mock-up to show what it would look like in-game. There is a preliminary data structure to hook the bike up in the game code, and that data structure is similar to the existing traffic entries so we can assume this was an early attempt to include other forms of traffic. However, the final higher level data structure is missing, which would include the palette information. So I've just used a random palette here.

Here's an extra frame from the end sequence with the genie. I guess there was originally concern that it wouldn't be clear who the genie was, so the extra frame on the left was made.

Finally here's another end sequence idea that was dropped. The existing sequence sees the guy kissed by the girl awarding the trophy, before flexing his muscles. It looks like the original plan was to also have him fall over. You can see the extra frames below:

You can use my quick and dirty sprite viewer to browse sprite data in other Sega titles. 

Monday, April 22, 2013

LayOut - WIP Video

Here's a quick video showing the latest progress with LayOut. You will want to view this full-screen to see the detail and turn the quality level up. As a bonus, there's some dodgy narration from myself, so turn the sound on. 

Current Features:
  • Edit Road path, width and height.
  • Import existing OutRun levels for editing and refinement. 
  • Export to Cannonball. Levels are fully playable.

I'm quite pleased with the ability to import existing levels. The import function generates the entire track path using nothing but the Curve Info value and direction that was discussed in a previous blogpost. So the large amount of data specifying the x,y of each road segment is completely redundant.

As you can see from the video, creating a playable level literally takes minutes. However, for the final release it will be important to quickly edit/preview sections of each level. I will be making additional changes to Cannonball to support that.

I must stress this is very much a work in progress; it's ugly, but it works!

Friday, April 12, 2013

Height Map Hell

One of the more complex areas of road data is the way in which setting the road height is handled. Each OutRun stage has 1948 positions that correspond to the path the level takes. We previously saw how a series of tables reference these positions to control aspects like the road width. This same table is also used to configure the height.

One of the entries in the table denotes whether the entry relates to a width change or a height change. Height changes are more complex than width changes. Each height change points to an entry in a separate table of 225 height maps.

So for example, on Coconut Beach at road position 1 the table references height map 211. In the diagram below, taken from my recent work on LayOut, you can see the data contained in this segment and a crude visualisation of the height map on the right.

The interesting thing is exactly how these maps correspond to a position in the level. We know when they are applied and therefore the start position of each height section, but how long do they last for? If the above map starts at road position 1, where does it end? 

The answer is relatively complex, as the height data you can see in the above table varies in length depending on the step adjust and multiplier values. Changing these values can either compress or expand the duration of the same height map. The road data isn't fixed to a particular road position increment. In fact in this example, changes in height are parsed through different multipliers to the straight sections and the end result would look something like this, presuming a start of road position 0. 

So here you can see the length of each data section in this single map and the road position it corresponds to at the bottom. I won't delve into the algorithms that map this data here, as it will probably confuse matters. I haven't yet visualized this in the editor itself. But we're starting to understand how these values correspond to a particular road position. 

Think of the actual values (0, 576 and -576) as the angle or steepness of the height section. And then the length pretty much specifies how high or how long that section of slope lasts for. 

To make things more complex there are four distinct types of height map in OutRun. Each type is rendered with a completely separate customized routine executed by the sub CPU that handles the road layer. Type 1 is the most common and shown above. 

Type 2 is more simple and used to create very long hills. It pretty much sets an angle and specifies a length or delay value. This is used at the point of the sharp chicane in Coconut Beach.

Now with Type 2, actually mapping this accurately to the road position gets interesting. Due to some quirks in the game code, the length of these sections actually depend on how fast you're driving. OK, you're not really going to notice this at normal speeds. But if you drive slowly, you can exploit a bug that pretty much elongates these sections way beyond where they should be. 

Here we are elongating the climb at the end of the Chicane. I'm driving slowly, and admittedly I've frozen the game timer. If we drive slow enough the hill can pretty much last right through to the end of the level:

OK, this is slightly silly stuff. But the point is that there is not a direct mapping between level position and the height map data. It's rather loose. So creating an editor where we can definitely say "the hill definitely ends here" or "this peak is exactly in line with this sign" simply isn't possible. The game code doesn't work in that way and there will always be ambiguity in some cases.  

Type 3 is a combination of Type 1 and Type 2. It's essentially some normal height data with a delayed section in the middle. The length of the section is handled differently again but is hard coded this time. Quite why, I don't really know. Typically a height entry will correspond to 8 road positions. This section isn't commonly used. 

Type 4 performs horizon y position changes. This can be seen at the start of Gateway, when the horizons level is raised. The only data attached to these entries is the new horizon position and the speed at which the change should happen.

It should be pointed out that the original assembler for this area of the game is horrendous and mildy terrifying.Therefore nailing all this detail down took a while, and unfortunately came at a time when things have been pretty busy for me. So apologies for the lack of exciting updates lately. 

In addition to this, I needed to expand my QT knowledge significantly to visualize this effectively in the LayOut editor. I implemented the ability to import the existing OutRun height map into the editor and display it in a logical tree format. 

There is still more work to be done, including basics like editing and creating new height map entries, although for a casual user, the existing maps should suffice. Once this is done, it will be time to move onto the fun stuff - adding level objects!

On Cannonball, a couple of people have kindly submitted changes that I will look into including in the future. The first is some control improvements from James and there is also some initial OpenGL rendering work from Legooolas, which will enable faster screen stretching/resizing than the current software approach. I'm holding off on Cannonball work for now and the next release is likely to be in conjunction with LayOut.