The original Japanese release of OutRun had different track layouts to the final Western release. Overall, the game is tougher with sharper unforgiving hills, and more aggressive turns.
This selection of tracks is less polished; Coconut Beach is nowhere near as rich in terms of design and the overall difficulty curve doesn't feel as good.
However, it's great to see the evolution of the track design between versions. And Gateway has some cool twists and turns that were removed due to it becoming an easier stage in the Western version.
The next Cannonball release will optionally allow you to play both versions of the game. It needs a little more testing (i.e. playing) before it's safe to release.
Devil's Cannon is known as Walls in the Japan version. The layout and sky colour are different.
Japanese Course Map
Japanese Coconut Beach. Not as cool as the final version.
There are a lot of changes, so it's possible there are also bugs. Please report anything you find.
Music Customization
Configure Cannonball to play WAVs instead of using the inbuilt game music. Configure the name of the replacement tracks for full ingame integration!
Please note, I do not intend to support additional file formats like MP3. This is a decision to avoid bloating the codebase with third party libraries. Convert your files with a free audio editor like Audacity.
Menu System
Now you can configure Cannonball without editing the config.xml manually. Note that some options are only available in the config.xml though.
High Score Saving
Scores are saved to a human editable hiscores.xml file. Edit the high score table manually!
Control Enhancements & Gamepad Support
Digital gamepads are supported. You can even change the digital sensitivity, so you can recreate the twitchy Sega Saturn conversion experience if you desire. Be sure to connect your gamepad before starting Cannonball.
All keys and joypad buttons are fully configurable.
I will support analogue whenever I buy a controller for testing. Or if you're in a hurry you can donate me one. :)
More Options & Bug Fixes
There's an app icon, ability to toggle extra level objects, fixes to the mingw compile and more.
Whilst creating Cannonball, I uncovered a large section of unused YM2151 music data in the Z80 program code. Initially, I was excited - could this be an unreleased Hiroshi Kawaguchi classic?
Unfortunately, after hacking the code to play the data it sounded like garbage. I wasn't sure if this was a problem with MAME's emulation, so I asked Alex of the OutRun bootloader project to play the sound on hardware. He sent me the results, which you can download here as an MP3.
It still sounded wrong, so at this stage I stopped investigating. It wasn't until later that night when I randomly happened to be playing the Space Harrier soundtrack on vinyl, that I came across the following composition:
I wonder if this is the Space Harrier Wiki Jumbo track embedded, but playing incorrectly due to other modifications to the sound code? It's a shame, because otherwise we could have hacked OutRun to have an additional tune. Perhaps it's still possible with some additional work...
The play area can now be extended to widescreen. The internal resolution is set to
398x224, which is approximately a 16:9 aspect ratio. This means the
screen is 25% wider and you get to experience more of the game world. The widescreen mode can be played windowed or full-screen as normal.
There are
some things to note about this mode:
The music selection screen and course map screen still display at 4:3, due to art limitations.
The tilemap x-scroll position is different, to compensate for
tilemap wrapping. So the backdrop position will be slightly different to
the normal mode.
I've updated the source code and the Visual C++ binaries.
Hey, guess what I'm working on.... and this is just 60 minutes of work...
Still a number of bugs to be fixed and things to be figured out before I release this :)
Update: It's done. It's actually quite awesome to play OutRun like this. I'll post some binaries later this week after further testing, or you can build right now from the develop branch...
Congrats to Seb, who has ported Cannonball to the Open Pandora handheld.
Download it from the Cannonball binaries page. More details, including the source code, can be found in the thread here.
Currently, it's running at 30fps but does support the other bells and whistles. Reportedly, it's a better experience than playing OutRun under emulation on this platform. I've rolled some optimizations into the develop branch on github, which should help ports of this nature.
I apologise for the lack of updates recently. Sadly, my house got broken into so I've been busy organising personal matters lately. Some OutRun memorabilia was stolen too which was a real shame as it is probably not replaceable and will no doubt just be junked. On a positive note, I'm going to investigate a genuine wide-screen mode for Cannonball as my next endeavour.
Firstly, thanks for the kind words and interest surrounding the project. It's much appreciated. I've taken some of the initial feedback on board and released a new version.
The highlights are:
The beginnings of the configuration system. Currently, its an XML file you must edit manually, but this will eventually become a cool in-game GUI.
Full screen support
Scaling in windowed mode
FPS options. Disable the 60fps mode to recreate the original experience.
Gear options (automatic option & support for cabinets with a switch based shifter)
Configurable traffic (including the ability to disable traffic entirely)
I'm delighted to announce the release of Cannonball; a portable C++ OutRun engine. This is the product of many years of reverse engineering, hacking and debugging.
The entire OutRun codebase has been decompiled and rewritten from scratch in C++. This extends to the Z80 sound program code and therefore full audio is supported.
Not only that, but the game now runs at 60 frames per second and many bugs present in the original code are eradicated.
This is just the beginning. Future releases will include a full menu, proper control, video & audio configuration plus an array of options and game modes not present in the original game.
I'm hoping to find OutRun enthusiasts who will port Cannonball to a variety of platforms. I'd love to see Linux, Mac, Wii, Raspberry Pi and other platforms supported. I will facilitate serious offers of help. We can ensure that any changes make it into the master branch, so it's easy to keep ports up to date.
The codebase isn't perfect; the original code from 1986 can prove messy and inconsistent. Some of this is naturally carried through to the rewrite. For now, the focus has been on the accuracy of the conversion, at the expense of serious refactoring. But that's not to say this isn't a viable future goal. And I've been working on this long enough, it's time to release.
Why do this? Because I love OutRun, and no one else would have done. Thanks to those who have followed the project up to this point. Any questions - post them below!
Here's an amazing project from blog reader Alex Bartholomeus (aka deadline). It's a hardware interface, gcc based toolchain and software bootloader for the OutRun boardset. It allows you to upload and execute C or assembly based software on the original hardware.
The Hardware
The connecting hardware is veroboard/prototyping board based, and uses simple TTL buffers/inverters (74HCT04). The interface partially implements the IEEE1284 spec as the basis for communication. The hardware utilises the unused digital input pins on the port that has the start and coin inputs. There are 16 in total, and these can be read as is done in the game. Output is achieved through bits connected to the start light, brake light and external mute.
The Bootloader
The bootloader is coded in 68000 assembly and must be programmed to the master CPU eproms.It implements the protocol without using any RAM (not even the stack), so that everything can be overwritten by the uploaded code. It also forwards interrupts from ROM to the same locations in RAM, so it's transparent to build binaries for uploading or plain eprom images. The interface only supports uploading code into RAM so it's limited to 2x32kb banks, minus the actual memory one would need. So uploading a complete outrun image would be impossible. But splitting the data (if there is any) and keeping that in the upper 2x256kb of ROM would be feasible.
The Toolchain
The toolchain consists of cross-gcc (C only), some linker scripts and a basic supporting library. The bootloader source code offers a nice example of how to code a basic program to run on the hardware.
Some videos of the setup can be found here and here. Alex plans to release the package including schematics and source code at some point soon. Then we can have an oldskool demo coding competition or similar!
Edit: These instructions are now dated, but please follow the link below for the latest version and instructions.
Here's a quick and dirty tool to view sprites stored in Sega's System 16 format. I searched for something similar, but couldn't find anything, so coded my own.
To use the tool, you will need to place the appropriate sprite files in the roms subdirectory.
The easiest way to determine which rom filenames you require, is to look at the relevant MAME driver file. Here are some links:
Find the section where the sprites are loaded. You must load the files in blocks of four. Some games have multiple banks of sprites. Here's an example for OutRun:
For example, in this case, to load the first batch of sprites you would run the tool as follows:
One thing to note is that the sprite data does not contain palette information. By default the tool displays the files using a pseudo-greyscale palette.
However, for OutRun I've extracted the sprite palettes from the 68000 program files. And you can toggle through all 255 palettes by using cursor left and cursor right. Unfortunately, there is no automatic way of determining which palette goes with which sprite. This information is hardcoded by the game at runtime. Some sprites can use more than one palette.
One cool use for this tool will be to search for unused graphics in Sega titles. Please comment below and post a screenshot if you find any. For example, here is an unused start banner from OutRun that is revealed by palette switching (using palettes 41 and 42):
I will be posting the source code to this tool when I release the Cannonball source code before the end of the year. Maybe someone wants to have a go at locating and including the other palettes.
Ding Ding Round Two! This time, we're pulling Power Drift apart. A crazy game, with some amusing secret messages, that I don't think have ever been revealed.... After 20 years, it's surely time to see what the developers were smoking.
As I realised during my OutRun work, AM2's titles contain weird and wonderful content. Power Drift it no exception, and I soon found text about elephants and various smells by examining the memory in MAME.
Then it was a case of tracing through tons of code to figure out how it was used. To complicate matters, there was a nasty red herring. If you enter SEX on the high-score table, you will see the message DANGER DANGER!
I thought I'd solved the puzzle, as searching for the string 'SEX' in memory revealed the following location:
You'll notice that the first three characters spell SEX, followed by various other letters. I recognised some of these initials as belonging to the AM2 development team, so I presumed entering the other names would invoke the other messages. Unfortunately, this wasn't quite correct. The fragment of code I'd uncovered that used the above table didn't seem to be called when I entered a name.
Instead, I found a manual check against 'SEX' hard coded elsewhere. Here is some of my commented disassembly:
What was going on? By examining the code, I realised that if you held BRAKE and pressed START when entering a special name, a separate function would execute. Bingo, this was the section that read the larger initial table. And now, we can display messages regarding elephants written in somewhat dubious English:
Not only that, but for each special name entered, you generally receive a different message dependent on which gear you are in. Here are some others, that amused me:
Well, finding other messages becomes easier when you've decompiled the code. A summary of the messages follows :)
When Brake & Start Button Depressed:
SEX: DANGER !! DANGER !!
When Brake & Start Button Pressed (Select one of two messages with gear):
SEX: LAKE YOU ? ME TOO !& MACHINE T.K.G.!!
KEY: I LOVE MAKIKO. & I LOVE CYNDI.
TKG: I LOVE RAY CHAN. & I LOVE RIE CHAN.
GAK:SAKICHI !! KITARO !! & I LOVE CHISAKI !
OKA:I AM TALLER THAN T.K.G. ! & KIM SAN ISSHOU TUITE IKIMASU.
REE: HALLO !! LETS FIND ANOTHER MESSAGES. & ARE YOU M2C2 MENBER?
NAK: NIGASITA SAKANA WA DECOI.
AKI: LUCY IS MINE! & EMILY IS MINE!
MAT: DO YOU KNOW ELEPHANT SMELL??
SAD: I LOVE KAYURI CHINA & NS400 IS FARSTEST BIKE IN THE WORLD.
HIR: MUSIC DESIGN BY HIRO. & SOUND DESIGN BY MY DESHI.
Today I decompiled a portion of Afterburner II's code to investigate some unused developer text I found in the ROM.
I traced the usage of these strings back through the code, with some manual IDA work. In the end I landed on the following function which enables the related block of code:
This revealed that the text could be triggered on the Continue Play screen, providing the player hadn't already inserted a coin. On this screen you must press the cannon button (fire 1) four times, the missile button (fire 2) twice, followed by the cannon button again.
On inserting a coin and resuming the game, a (c) SEGA 1987 message will now be shown:
Message 1: (c) SEGA 1987
But what of the other text strings? Unfortunately, it appears that you can only display them using the Mame debugger. The routine to display them is present in the code, but the counter to select the message (which should increment each time you do the cheat), is broken as it resets when the Continue Play screen initializes. I think the original intention was to cycle the message each time the player entered the cheat code, but for whatever reason that never happened.
You can manually set the counter (0x3F9126) to override this behaviour. Let's take a look:
Message 2: Presented By Sega
Message 3: I Love Momoko
Message 4: Programmer Credits
What's interesting is Satoshi Mifune's name appears in the credits here, who later programmed titles including Shenmue and Virtual Striker. It's very difficult to find out the dev team members of these early AM2 titles, so great to have this proven. I wonder who Momoko was...
I also investigated Afterburner I. It contains a similar routine, but is tougher to activate. This is because after pressing fire1 x4 and fire2 x2, you must almost simultaneously coin-up and start.
Check out this issue of the Japanese magazine Gamest, that covers the 1986 Amusement Machine (AM) show, where Sega previewed OutRun. Gamest is an amazing publication although it would be even better if I understood Japanese.
I've scanned the colour pages relating to OutRun below. I love the cover advert; it's similar in style to the Japanese flyer. Click the images for a full-size version.
I'm currently implementing sound in Cannonball (the name for the cross platform OutRun engine). Much like my approach to the video hardware, the sound hardware will be emulated, whilst the actual Z80 program code is converted to readable C++.
I've implemented the SDL sound layer to output the audio, hooked up emulation of the Sega PCM chip and created the interface between the main program code and sound code. I've successfully converted enough of the Z80 code to trigger basic PCM samples. The entire Z80 rom is decompiled and commented, so progress from here should be steady.
There will (eventually) be two approaches to audio in Cannonball. The first approach will purely use the original ROMs for music and sound as discussed above. The second approach will allow players to configure audio files as replacement music tracks. This will allow you to play the game with the various remixes that have been produced over the years.
Once sound is implemented, I'll open up the source code repository to public access. This will allow everyone to play with and port the source code to new platforms for non-commercial purposes.
Let's take a look at the structured format of sound information. Here's a relatively straightforward example demonstrating the setup of the Checkpoint PCM sample.
; Voice 1, Checkpoint
ROM:6F91 data_voice1: dw data_voice1_c ; Offset to channel setup below
The sample is played through two channels simultaneously, presumably to boost its volume.
; Voice 1, Channel Setup
ROM:6F99data_voice1_c: db 2 ; Number of channels
ROM:6F9A dw data_voice1_c1 ; Address of Channel 1 Setup
ROM:6F9C dw data_voice1_c2; Address of Channel 2 Setup
This block represents the default setup for the 32 byte block mentioned in the previous post. It's not actually 32 bytes, but the remainder of the space is padding to zero by the program code. I've cut the second entry short in the interests of space as it's very similar.
ROM:6F9F db 1000110b ; Flags: Mute & Channel Index
ROM:6FA0 db 2 ; End Marker
ROM:6FA1 dw 0
ROM:6FA3 dw 1
ROM:6FA5 dw data_voice1_c1p; Address of commands
ROM:6FA7 db 0
ROM:6FA8 db 20h ; Offset for positioning information
ROM:6FA9 db 0
ROM:6FAA db 0
ROM:6FAB db 0
; Voice 1, Checkpoint (PCM Samples: Channel 2)
ROM:6FACdata_voice1_c2: db 80h
; Snip: Similar to the above block
ROM:6FB9 db 0
Here's where things gets a little interesting; what follows is a series of commands that correspond to a particular z80 routine, along with their arguments.
; Voice 1, Checkpoint (PCM Properties)
ROM:6FBAdata_voice1_c1p:db 93 ; 93 = Command: PCM Set Pitch
ROM:6FBB db 48h ; value = pitch
ROM:6FBC db 82h ; 82 = Command: PCM Sample Volumes
ROM:6FBD db 17h ; value = left channel vol
ROM:6FBE db 2Eh ; value = right channel vol
ROM:6FBF db 0DCh ; DC = Command: Sample Index
ROM:6FC0 db 28h ; value = checkpoint
ROM:6FC1 db 99h ; 99 = Command: PCM Finalize
ROM:6FC2data_voice1_c2p:db 93h ; 93 = Command: PCM Set Pitch
ROM:6FC3 db 48h ; value = pitch
ROM:6FC4 db 82h ; 82 = Command: PCM Sample Volumes
ROM:6FC5 db 2Eh ; value = left channel vol
ROM:6FC6 db 17h ; value = right channel vol
ROM:6FC7 db 0DCh ; DC = Command: Sample Index
ROM:6FC8 db 28h ; value = checkpoint
ROM:6FC9 db 99h ; 99 = Command: PCM Finalize
These commands index a table of routines which is as follows. Not all of these routines are used, as I imagine this area of the code is used across other Sega titles. I've highlighted in red the entries used by the above sample.
ROM:0B93 BigRoutineTable: ROM:0B93 dw YM_Dec_Pos ; YM: Decrement Position In Sequence (80) ROM:0B95 dw YM_SetEndMarker ; YM: Set End Marker. ROM:0B97 dw PCM_SetVol ; PCM: Set Volume (Left & Right Channels) (82) ROM:0B99 dw YM_Dec_Pos ; YM: Decrement Position In Sequence (80) ROM:0B9B dw YM_Finalize ; YM: End (84) ROM:0B9D dw YM_SetNoise ; YM: Enable Noise Channel (85) ROM:0B9F dw loc_409 ; Unused? ROM:0BA1 dw YM_SetModTab ; YM: Enable/Disable Modulation table ROM:0BA3 dw WriteSeqAddr ROM:0BA5 dw SetSeqAddr ; Set Next Sequence Address ROM:0BA7 dw YM_GetLoopAdr ; de = new YM loop address ROM:0BA9 dw YM_SetNoteOffset ; YM: Set Note/Octave Offset (8B) ROM:0BAB dw YM_DoLoop ; YM: Loop Sequence Of Commands (8C) ROM:0BAD dw loc_46B ; Unused? ROM:0BAF dw loc_471 ; Unused? ROM:0BB1 dw YM_Enable_Correspnd ; YM: (Unused) Enable corresponding channel (8F) ROM:0BB3 dw YM_Disable_Correspnd ; YM: (Unused) Disable corresponding channel (90) ROM:0BB5 dw YM_SetBlock ; YM: Set Block - Called First When Setting Up (91) ROM:0BB7 dw YM_DisableNoise ; YM: Disable Noise Channel (92) ROM:0BB9 dw PCM_SetPitch ; PCM: Set Pitch (93) ROM:0BBB dw YM_MarkerData ; FM: End Marker - Do not calculate, use value from data (94) ROM:0BBD dw YM_MarkerHigh ; FM: End Marker - Set High Byte From Data (95) ROM:0BBF dw YM_ConnectRight ; FM: Connect Channel to Right Speaker (96) ROM:0BC1 dw YM_ConnectLeft ; FM: Connect Channel to Left Speaker (97) ROM:0BC3 dw YM_ConnectCentre ; FM: Connect Channel to Both Speaker (98) ROM:0BC5 dw PCM_Finalize ; Write Commands to PCM Channel (99) In case you were wondering the 0xDC command which is not shown in the table above triggers a separate piece of code, which also triggers drum samples and so forth in the music tracks. Anyway, let's take a look at a simple routine - setting the pitch of a PCM sample.
ROM:03C4PCM_SetPitch: ROM:03C4 bit 6, (ix+1) ; If channel is muted, don't set pitch ROM:03C8 jp nz, set_pitch ROM:03CB ld a, a ROM:03CC ret ROM:03CDset_pitch: ROM:03CD ld a, (de) ; a = New pitch (read from setup table in rom) ROM:03CE ld (ix+16h), a ; Set relevant area in 32 byte block that controls pitch ROM:03D1 ret
The music tracks work in a similar way, but with a much longer and more complex series of commands.
Originally, I thought the Z80 might be used in a 'dumb' manner and simply stream preformatted audio data to the various chips. But its usage is much more sophisticated as demonstrated above.
I've almost finished decompiling OutRun's Z80 program code, so I'll be providing high level information regarding its workings over a series of posts.
The Z80 processor controls two pieces of sound hardware; a custom Sega PCM controller and a Yamaha YM2151 FM sound chip. This was a fairlystandard configuration for Sega boardsets at the time. As you'd expect, some of the Z80 program code is in fact shared with other games of the era. However, most of the code is unique and written solely with OutRun in mind.
Commands are sent to the Z80 from the master 68000 program code. The Z80's interrupt routine reads from port 0x40 and places the values received into a sequential set of locations in RAM. Commands are high level and consist of a byte corresponding to a Z80 routine. So sending 0x81 plays the 'Passing Breeze' music, whereas 0x9d triggers the 'Checkpoint' PCM sample. From the 68000's point of view, playing a sound is simple and the complexity is nicely masked.
In addition to these commands, the 68000 sends data relating to the volume and pitch of the Ferrari's engine tone. It also sends volume and panning information relating to the passing traffic. This ensures that when you drive past a vehicle, the volume of its engine is proportional to the y distance from your Ferrari and the stereo panning corresponds to the x difference.
The core loop to achieve everything is as follows:
ROM:0039main_loop: ROM:0039 call DoFMTimerA ; Wait for timer on YM2151 chip ROM:003C call ProcessCommand ; Process Command sent by 68000 ROM:003F call ProcessChannels ; Run logic on individual sound channel (both YM & PCM channels) ROM:0042 call ProcessEngines ; Ferrari Engine Tone & Traffic Noise ROM:0045 call ProcessTraffic ; Traffic Volume, Panning, Pitch ROM:0048 jp main_loop
The Z80 maps the 16 channels of the PCM chip to various uses. 6 are reserved for the music's drum samples, 4 are used for sampled sound effects and the remainder are used for the Ferrari's engine sound and passing traffic. Each channel is allocated a 32 byte area of RAM by the Z80 program code, which stores its current state. This concept is extended to include the channels from the YM chip which are also allocated to these areas of RAM.
The usage of the 32 byte area of RAM differs dependent on whether it represents a YM or PCM channel. The area contains everything from basics including volume and pitch for PCM samples through to complex YM configuration including positional information within the current block of audio commands, section loop counters and the address of the next data block. This 32 byte block is used as a starting point to configure the separate PCM RAM area, which has a different format and to program the YM's registers.
Next time, I'll explain the interpreted language stored within the Z80 code. This is used by the Z80 to program the sound hardware. And you'll see how the music and sound effects are actually stored as an interpreted sequence of commands that call functions within the code.
Here's a screenshot of the OutRun engine running on a Raspberry Pi. The display is being output on X11 via SSH. It hasn't been tried on the native Pi display yet.
I've decided to name the OutRun engine Cannonball, after the 1981 Cannonball Run film that Yu Suzuki was inspired by.
Thanks to everyone who tried the recent Visual Studio based build for Windows. The plan is to ensure this becomes a true cross platform project, not tied to a particular operating system or architecture. I like to think of it as "OutRun Everywhere", making the world a better place ;) Thanks to some work from a friend, who knows far more about this sort of thing than me, this is close to becoming a reality.
The code now successfully compiles and runs on both a Mac with XCode IDE support and the Windows MinGW compiler. Other platforms will shortly follow, including Linux and the Raspberry PI if performance allows.
We're using CMake, the cross platform, open-source build system. This automates the creation of build files for a whole range of target platforms. We're able to generate builds for a whole host of platforms and configurations.
The C++ libraries have been switched to Boost. This provides an open-source cross platform alternative to facilitate portability.
I can't take credit for the above, but I have started decompilation work on the Z80 code that controls the sound hardware (both the custom Sega PCM sample player and the Yamaha YM2151). This is my main area of focus and will take some time. So far, I've commented the code that triggers the PCM samples. Ultimately, I'd love to give players the choice of emulating the original sound hardware or streaming audio from disk, similar to the approach used by the Sega Saturn conversion.
At last, here's a new demo of the OutRun engine. The entire game is ported, aside from sound and the service mode.
In terms of functionality, this release is bare bones. There is no menu system yet, all options are hardcoded and you have to play the game windowed.
It would be great if you could report bugs (and I'm sure there will be plenty) in the comments below. Please verify any subtleties against MAME for reference.
Stats:
Conversion time from decompiled code: 1 year 10 months.
Estimated ratio of time spent coding vs. debugging: 1:5
Road rendering code: 1500 lines
Ferrari handling & rendering: 1680 lines
Code to render level objects: 1050 lines
General sprite handling code: 890 lines
Traffic handling code: 675 lines
Code to handle crash routines: 1450 lines
Keys:
Cursors: Steering
Z: Accelerate
X: Brake
Space: Gear Change
5: Insert Coin
1: Start
F1: Pause
F2: Advance a frame when paused (useful for observing visual problems)
F3: Toggle/Freeze timers. (i.e. infinite time)
In a future revision, there will be options to custom the controls and the analogue sensitivity. I find MAME's default setup too twitchy, so you'll find the steering a little more heavy in comparison.
Enhancements over original:
60 frames a second. The original game runs at 30fps.
In a future revision, enhancements will be optional and there will be a menu toggle to enable/disable them.
Requirements:
OutRun Revision B ROMs. They must be named correctly and placed in the roms subdirectory. No other set will work. Although you can use the patched set from OutRun Enhanced Edition. I would recommend running the demo from the console to see any error messages.
Here's another bug in the original game; the leftmost two end sequences have a palette issue which causes the male sprite to suddenly change in appearance. In the screenshot below, we're approaching the goal banner.
Then, as if by magic, the colour of the man's top changes to light blue!
But don't worry, on reaching the finish line it's back to dark blue again.
The game code swaps to an animation playing routine at the point of the colour change. It should be seamless. But it seems as if 2 of the 5 end routines are configured incorrectly.
Why am I noticing such trivial details? Because the engine is now complete (minus sound and test mode). Expect a test release in the next week!
It's been nearly two years since I started rewriting OutRun, and three years since I begun decompilation work. This is, and feels like, a long time. According to Yu Suzuki, the original game took four programmers between eight and ten months to complete, so I'll take some reconciliation from the fact this was only a part-time project.
Following the success of the decompilation work, I expected the rewrite to be plain sailing. In fact, the rewrite proved tough - really tough! The size and complexity of the codebase meant I spent an inordinate length of time debugging. Writing your own code from scratch is comparitively easy; your intentions are clear and tracking errors is straight forward. Finding the source of a bug in thousands of lines of ported assembler can be a nightmare.
Debugging ultimately became a case of stepping through the suspected area of code line-by-line and comparing results with the MAME debugger. I invoked crazy tactics along the way; I coded routines to utilise MAME memory dumps for the road layer to quickly determine whether bugs were caused by erroneous code or if data in memory was at fault. This also enabled me to compare the original with my port from an identical starting point.
The other complication was the way in which the original codebase was designed and structured. The style of code varies dependent on who was working on it and by god, they produced a lot of it. The hardware specifications were insane by 1986 standards, and the coding team appear to have approached the project with the view that space and clarity were not a primary concern. There is a huge amount of code duplication and multiple routines that perform similar tasks with minor modifications. Despite evidence of code reuse at Sega, there should be no doubt that this is disposable code, not a reusable game engine. In fairness, the programming team would have been under considerable time pressure.
So what's next? I'm going to port the final chunk of code to handle the game completion sequence. This consists of a big switch table to manually send commands to the sub CPU handling the road layer (similar to the road split, but not quite the same), code to control the Ferrari AI during this period (similar to attract mode, but not quite the same), code to blit the timing information to the screen (similar to other digit blitting routines but not quite the same) and code to handle the animation sequences (similar to the start line intro sequence but not quite the same). Now, you're beginning to understand the OutRun codebase!
Once this is complete, I will release a new build for testing purposes. I was going to release sooner, but I'm so close in terms of porting the entire core engine I'm going to hold back. This build will run at 60fps and feature a selection of other minor improvements not in the original game. From this point onwards, the fun begins and we can start to include extra functionality and enhancements. It will also be a good point to port the code to a variety of platforms. I will be looking for help once I tidy up the codebase a little further.
I hope that explains where the project is, feel free to comment below if you have questions.
UPDATE: Tantalisingly close... bonus points code done, bonus sequence AI done, bonus track control done. Just the animation sequences now.
Nothing interesting to report. Since returning from holiday I've converted the high-score entry code and course map screen. When I used to develop games professionally, I didn't enjoy working on these elements and I can't say the feeling has changed much!
Next I'll move onto some of the remaining attract mode code. Once I've tied up some loose ends, I'll release a playable tech demo in order to gather bug reports. And that will be a little more interesting.
Update:
The core game engine is now ported, apart from the end sequences, test mode and sound code. We're getting close...
My ported OutRun engine now runs at 60 FPS, as opposed to the standard 30 FPS of the original arcade machine. It's beautiful and smooth. Although you can easily switch back to 30 FPS if desired.
The game was intended to run at 60 FPS originally, but reduced to 30 FPS for performance reasons. You can tell this by studying at the game code. The vertical interrupt code, including the routine to increment the timer, is intended to be called 60 times a second. Whereas the game engine is intended to be ticked 30 times a second.
The Sega Saturn version is the only other version to support 60 FPS mode. However, I can probably increase the frame rate further still... let's see!
Aside from that, I ported the the HUD and related logic (including the 'Extend Time' code between stages). The intro sequence with the Ferrari driving in and flag waving is also complete.
I will release a new tech demo in around 6 weeks so you can give it a spin and report any bugs.
Update: Tonight I recoded the engine to run at a ridiculous 120 FPS. Then I realised my LCD monitor doesn't even support this refresh rate - doh! The code becomes a little more hacky to support such a frame-rate causing a few minor bugs to surface. For this reason, I probably won't support 120 FPS. Still - it was a fun experiment, sort of...
Chase HQ is one of my favourite Spectrum games. It is a fantastic conversion, pushing the 3.5Mhz processor to its limit. A racing game boasting tunnels, road forks, destructible scenery, fantastic graphics, sampled speech, and a healthy frame rate. All this on a machine that didn't have a hardware multiply instruction or meaningful graphics hardware.
As an artist for Ocean software, Bill Harbison was part of the Chase HQ team and I'm delighted he agreed to be interviewed for this blog.
Let’s go back to 1988! Thatcher’s still in power, the Berlin wall is about to crumble and computer games are delivered on cassette tape. What encouraged you to join Ocean over the other software houses?
Honestly? Ocean were my last choice. At that time their track record wasn't great: Knight Rider and Street Hawk. After rejections from everywhere else I thought, "why not? They can only say no as well."
Little did I know that Gary Bracey [Ocean's Software Manager] was building a fresh team of people to work in-house just at the time when I decided to apply. It wasn't even a formal application, it was just a handwritten letter with a cassette of my work enclosed. Amazingly I got a call back and I moved to Manchester from Scotland to work on Daley Thompson's Olympic Challenge.
In Retrogamer, you mentioned that you hadn’t played Chase HQ before being offered the conversion. Once you’d tried the original, were you excited about the project, or was it just another job at the time?
I didn't get much of a chance to go to arcades at that time so I lost touch of what new games were out there. I had just finished work on WEC Le Mans so I thought, "oh great, another racing game!" (sarcasm) We got the arcade machine delivered to the studio and it looked a lot more interesting than the usual racing title.
Chase HQ - Arcade Version
How did you team up with John O’Brien [Chase HQ programmer] and what was he like to work with?
That's an easy one. He had just started work there a few weeks earlier and I was told I would be working with him after my previous programmer left.
Chase HQ - Spectrum Version
It was the early days of the games industry, so did either John or yourself effectively assume the role of producer and/or designer? How were design decisions on Chase HQ made?
There were no such things as producers back then. We were just given the game and told to make it work on the Spectrum. Any graphical work was left to me and the game mechanics or gameplay was mainly Jon. It was quite a joint effort, occasionally other people would chip in with suggestions and we could decide to either do them or ditch them.
One of the admirable aspects of your conversion is the attention to detail. This runs throughout the conversion, from the multiple logo animations on the start screen through to the animated end sequence. You clearly went beyond what was expected or necessary. Can you tell us a little about what motivated you to push the boundaries at a time when many arcade conversions were rushed and uninspired?
Jon was such an efficient programmer that when the game was finished he had loads of memory left over and I think he felt a bit guilty about that. We had to think of things we could add to the game, they were mainly graphical additions like the game ending and the bouncing title graphics.
What resources did Taito and Ocean provide in order to convert Chase HQ? Did you receive the original art or source code?
We got the arcade machine that you could sit in to play, it was free to play which was great and very useful.
You worked on both the Spectrum and CPC ports. Did Ocean attempt to coordinate the conversion teams?
The Amstrad version was done afterwards because I think the code could be ported across with adjustments made, the graphics however had to be done from scratch. I had done Amstrad graphics before on Daley Thompson’s Olympic Challenge and I enjoyed working with all those lovely colours.
Chase HQ - Amstrad CPC Version
What hardware and software packages did you use to create the artwork? Can you tell us a little about the process you followed?
We had no means to rip the graphics from the arcade board so I had to sit at the arcade machine and make sketches on paper of the graphics and animation frames. I later drew the sprites and animation on the Atari ST with a remarkably good in-house sprite editor written by John Brandwood. The only thing it couldn’t do was scale graphics up or down which meant that all the smaller frames of the cars and roadside objects had to be drawn from scratch. Any background elements that required colour attributes were drawn on the Spectrum with my own copy of Artist 2, the software with which I did my portfolio work a couple of years previously.
The Artist II - Spectrum Graphics Package
How long did the conversion take and what were the main challenges you faced?
I think the conversion probably took about 6 to 8 months to do both the Spectrum and Amstrad versions. There weren’t really any challenges to overcome in the project, we both knew what we were doing and we managed to get all the gameplay elements completed ahead of schedule. This left us time to show off and add as much extra content as we could think of. We didn’t really have to clear it with anyone, Taito didn’t really seem interested in what we were doing, we never had any contact with them. The only person I suppose we answered to was Gary Bracey [Ocean's Software Director] and if he didn’t like what we were doing he would be quick to tell us. He obviously did like what we were doing because he kept us together to work on a similar driving game in Batman The Movie for the Atari ST and Amiga.
C&VG rightly described Chase HQ as “the best ever Spectrum arcade conversion” and “the most astounding Spectrum game for years”. They were clearly more excited about the Spectrum conversion than the 16-bit conversions. Were you expecting this response and how did you feel when you first read the reviews?
There were a few decent racing titles out already and I knew that our conversion was better than Out Run, I just wanted our game to be better than my favourite, Enduro Racer. We were very pleased with the reaction of the reviewers but I was more touched when we received a hand-written letter from someone who had spent their own money on the game and felt compelled to thank us for doing such a good job. Whoever you were, it was greatly appreciated.
Were any features cut from the final version of the game due to technical or time constraints?
No, as I mentioned earlier we added extra content to the game. The animated title sequence came from Jon’s conversation with some of the other programmers either Paul Hughes or James Higgins. I don’t think Jon had intended to animate the titles letters and I think some gentle teasing and reverse psychology may have been implemented to see if he could do it. He not only did it but did it exceptionally well.
Why did Ocean assign a different team for Chase HQ II? Was the original game engine reused?
We were already working on Batman The Movie which was a massive license for the company and I don’t think it was seen as as important. I was a bit disappointed that I didn’t get to work on the sequel, I’m sure there are things that we could have improved on.
Finally, what are you working on now and is there anything you’d like to plug? :)
I’m working at Devil’s Details in Sheffield and I’ve just finished work on Table Top Tanks for the PSVita which is doing very well. It’s an Augmented Reality game, check it out!