Monday, December 22, 2014

The Ultimate Way To Play OutRun

The Force Dynamics team have ported CannonBall to run on their 401cr motion simulator. It's particularly cool to see the terrain data is used to adjust the height of the simulator! 

It's fantastic to see CannonBall running on everything from Android phones through to military grade hardware! Check out the video below. 


Wednesday, November 19, 2014

Restoration - Boardset

I pulled the PCB out of the machine and connected it with my test harness to a CRT TV. After sitting in a garage unused since the 90s it was surely never going to work?


I couldn't believe my eyes - it booted up and everything seems ok. Maybe I won't need that spare PCB after all. There's a bit of an audio hiss under the sounds but that's it. I'm going to leave it running for a bit to see if it explodes. ;)

Saturday, November 15, 2014

OutRun Mini Restoration

Back in 1997, I bought an OutRun Mini cabinet. It cost £200 and had been in use in a youth club. It worked, but had been well used and seen better days.


When I left London and headed to university in 1999 the cabinet remained in my parent's garage. It's resided there for the past 15 years gathering dust.

Most of the cabinet was unwisely painted black at some point and the red side art covered. The black paint had started to flake off, taking the red stencilled side art with it; it looked pretty awful as you can see below. 


I got in touch with a chap called Rudy who has reproduced the side art. This is in the post and will serve as a nice motivational reminder of the way things should be. 


The control panel has also been painted black, the sticker ripped and the start button replaced. Everything works fine however. There are no broken cogs and the original OutRun steering wheel emblem is present. 


I have a replacement control panel in great condition, so I have a few options here for the restoration, so it should be one of the easier parts to get right. Some of the chipboard is in particularly poor condition at the base of the cabinet. 


The insides of the cabinet are dusty, but thankfully not rusty. I was quite concerned that storing the cabinet in a drafty garage for 15 years would have caused more obvious problems. 


Even the PCB shows no obvious signs of corrosion which is pleasing.  I doubt it still works, but I will check it in my test harness at some point. 


The bottom interior of the cabinet is filthy. As a bonus, I found 20p amongst the dust. Evidence below. 


It's nice to find out when the cabinet was born; 22nd July 1987. It was last serviced in 1996, a year before I bought it. 


There's a lengthy task ahead, and I will be stripping the cabinet down for a full refurbishment over the coming months. Hopefully I can restore this cabinet to its former glory and learn something along the way. 

Tuesday, November 11, 2014

CannonBall 0.3 - Widescreen Tilemaps & Freeplay

This is a version of CannonBall I meant to release a while ago, but moving house and family commitments ended up causing me to sit on it for a while. I suspect there may be some new bugs as there was a gap between coding and release, so please report anything found.

I also spoke with Colin who is going to carry on with CannonBoard work soon. Behind the scenes a lot is done and ready to go from a software point of view.

Features:
- Widescreen tilemap support for music selection screen.


- Widescreen support for map screen. The sea on the left now extends further.


- Freeplay Mode (enabled in config.xml for now)

- Optional Timing Fixes (enabled in config.xml for now)

Android

Also of note is the following project, which is a port of CannonBall to Android phones, tablets and other devices. There are some bugs and suggestions I have for the author, but overall it runs nicely!


You will need to enable the installation of APK files from unknown sources in the Settings -> Security section of your device to use it.


The author has kindly released the source code, which is available here.

Cabinet Restoration

One benefit of moving is that I finally have space for my OutRun cabinet. It needs a lot of restoration work, so I will be devoting a lot of free time to this project in the coming months as well as supporting Colin with his CannonBoard work. I'll post some pictures once I get going.

Wednesday, August 06, 2014

Sega Enhanced (formerly OutRun Enhanced Edition)

The OutRun Enhanced Edition pack has evolved and is now a multi-pack supporting additional Sega titles. Adrian Smethurst created a patch for Super Hang-On and Limited Edition Hang-On to improve free play mode.

Originally, with free play mode selected by the dip switches, the game would never enter attract mode. It immediately went to the class selection screen when a game was over. If unattended, it would time out and go to the music selection screen. If still unattended, it would time out and start a game; the game (and music) would play until the game timer expired, after which the cycle would start again at the class selection screen.

Improved free play mode DOES allow attract mode (no automatic credit is given). To begin a game in free play mode, simply press the START button whenever it is flashing. This "coins up" the game, and proceeds to the class selection screen.

In addition, the OutRun Enhanced patches can now be applied to the original Japanese rom set with the alternate track layouts.

The patches to run Enduro Racer on the Space Harrier hardware are also included for convenience.

Download the package from here

Monday, July 14, 2014

Tile Editing

One of the problems with CannonBall feature development is that many of the remaining tasks are hard to achieve. Take the music selection screen for example; it's one of the parts of the game that isn't widescreen and remains letterboxed.

Now it would be easy to simply drop in a replacement graphic at this point and bypass the original code to display it. In fact many people have sent me such an image over the last couple of years in the hope I would do just that. But that's not really true to the ethos of what CannonBall is about. The real solution is to extend the original tilemap and use the tile layer to render the screen, rather than hack in a replacement.

Unfortunately, this approach needs a full tile editing tool, which is a rather complex way of achieving something that will look no different to the end user. Nevertheless, I'm writing such a tool so that tilemaps can be edited, new tiles created and the screen finally widened.


Currently I have the ability to import the music selection tilemap, edit tile data and edit tile maps. I'm in the process of creating the new tiles to extend the image to widescreen. As you can see above, the right hand side is relatively easy to extend and I'm just starting to tackle the more complex five columns on the left hand side. 

OutRun contains plenty of unused tiles, which can be replaced for this purpose. For example, the larger Space Harrier font exists in the tileset, which is of course unused. 

Now that tiles can be edited, I can also move on to create HUD graphics for the High / Low gear change, a MPH display and so forth. The next version of CannonBall will feature these improvements. 

UPDATE: And here is the final result in CannonBall. The observant among you will notice that I've based the new tilemap on the 3DS version. 


It was a lot of work for something that looks simple. One of the complications with the System 16 tilemap format is that bits have a shared usage, that I'd previously overlooked. After all, the complications of it don't really matter when simply rendering existing data. For example a typical word of the tilemap is configured as follows:

 MSB          LSB
 ---nnnnnnnnnnnnn Tile index (0-8191)
 ---ccccccc------ Palette (0-127)
 p--------------- Priority flag
 -??------------- Unused

As the index and palette share bits, this locks tiles to certain palettes dependent on their index. Therefore the previously identified unused tiles are not usable. Instead the new tiles end up being scattered through the tilemap from location 4096 onwards. I also had to create new palette entries to map to these tiles.

This explains why Sega games have tile duplication, where the same tiles appear multiple times in the graphic roms. It enables them to be used with multiple palettes. In practice I can't help but think it would have been simpler to double the tilemap memory, thus giving the palettes their own distinct bitrange and avoiding tile duplications. I guess this may have been a cost saving measure.

Tuesday, July 08, 2014

OutRun Unidesa PCB

Here are some relatively high quality photos from the Outrun PCB manufactured under license by Sega to the Spanish company Unidesa. You can click on the images for a larger version and then right click to save a high quality version.

Close up of the top left of the CPU PCB


Manufactured 5th May 1987

The main difference with the licensed PCB is the ribbon cable used to connect the two boards, as opposed to the direct connector on the original. 


The connectors are also slightly different, although I believe they are wired the same. The black connectors below are the power connectors for the two boards. 


Here are the connectors on the video board:


Here is a picture of the top CPU PCB. I haven't separated the boards to get a shot of the Video PCB yet.


I haven't powered up the board yet, but I'm told the ROMs are identical to the standard Revision B version. More information on this version of OutRun can be found here.

Tuesday, July 01, 2014

OutRun Enhanced Edition 1.10

A new version of OutRun Enhanced Edition is out. This is the enhanced version of the original OutRun ROMs, designed to be programmed and used with the original hardware. This version includes some new features and fixes from Adrian Smethurst.

There are selectable timing system fixes; 60 seconds on the lap timer represents 60 genuine seconds in real-time and the correct time when passing the Checkpoint when EXTEND TIME is shown.
 
The timing system fixes can be toggled in the Diagnostics mode in the Dip Switch assignments screen by moving the gear stick. Your choice will be backed up when the machine is powered down.



There are improvements to high-score inital entry system. Backspace can be used over the final initial to match many other Sega titles.

The Last Wave music is also added as an option to the sound test menu.

The timing system fixes will also feature in the next version of CannonBall too for those interested. 

Tuesday, June 17, 2014

CannonBoard Hardware Update

Colin is busy at work with the latest iteration of the CannonBall hardware. He's constructed a bare bone version of CannonBoard using the new board designed, and programmed with the firmware that we prototyped on the previous Arduino setup. 

Currently it's a minimal setup, with only the essentially components soldered into place (the CPU, the RS232 level shifting chip, some debugging LEDs, the resistors and capacitors). All looks good so far. 



Thursday, May 01, 2014

Super Mario meets Super Hang-On

This is a fun hack from Adrian Smethurst. As might be expected, it turns out that the audio engines for Super Hang On and OutRun are very similar (both FM synthesis and PCM sample playing). With a lot of patience and some reference to these blog posts (which I never expected anyone to find that useful), he managed to replace one of the tunes in Super Hang-On.



He actually inputed the new music by hand - brave man! Adrian adds:
I downloaded the sheet music from mariopiano.com and set about on the most pointless 8 hours of my life!  You can get away with doing that when you're only doing one track for a bit of fun, I wouldn't recommend it for anything more than just that though!
Adrian has also been working on some fun hacks using the OutRun Enhanced tools. I'll post these at a later date once I've integrated them in the package. 

Sunday, April 27, 2014

CannonBoard Latest Hardware Design

Colin is continuing to make great progress designing the CannonBoard hardware. Below you can see the latest iteration. You'll note that the Arduino is no-more, and a CPU fully integrated with the design. So to use CannonBall in a cabinet, you'll need a PC, the CannonBoard interface, and a VGA to CGA card / Ultimarc Arcade VGA or video card with soft 15khz.

It's possible that I'll port CannonBall to something like an ODroid so that you don't even need a bulky PC but that will come later.


I've been implementing some diagnostics options in CannonBall that will make it easier to work with a real cabinet. Not particularly exciting, but certainly useful. 

The outputs, including the start lamp and brake light should also now be hooked up.




Wednesday, April 23, 2014

3DS OutRun

M2's version of OutRun for the Nintendo 3DS is out in Japan. M2 have done a fantastic job with the previous SEGA ports, so it's exciting that OutRun has finally made it. Playing these titles in 3D for the first time is an awesome experience. This is also the first new port of the original OutRun for around ten years.



Whilst I haven't tried the 3DS version yet, I've checked out the videos and information online. There's a good interview with M2 in Japanese. Part 1 and Part 2.



There are plenty of solid features: 3D graphics, 60 FPS gameplay, widescreen mode, optional car colours, car handling settings and the usual difficulty and time DIP switch options from the arcade machine.

In terms of bugs, interestingly, M2 opted to fix the timing issues that we discussed in a previous post. However, the arcade mode uses the original timing. It's a confusing way of doing things I think as it creates two separate OutRun timing systems. The sprite scaling bug is fixed and the level object issue with the broken Gateway arches also appear fixed. Regarding the audio, the corrupt PCM samples are fixed.

So, you're probably thinking - is this the best best version of OutRun ever? Unfortunately, there are a few drawbacks if you're looking for a truly faithful experience. The biggest gripe is the Ferrari substitution, an inevitability due to licensing issues.


Whilst the car is purely cosmetic, it's also THE memorable graphic from the original game. It would be disappointing to replace Sonic the Hedgehog with a blue badger for example, even if the gameplay was identical.

Other graphics that have been changed include the Porsche graphic, which has had the spoiler removed.


The Marlboro lookalike sign on the start banner has been altered further to differentiate it from the cigarette brand. I spotted a sign that had been edited to contain an M2 logo also. 



There appears to be a sprite clipping bug on Stage 2 with the large stone graphics. It's possible this is an optimization to help the game run faster on the 3DS, but the large stones are disabled as they get closer to the camera. It's also possible M2 forgot to update a hard-coded value in the drawing routine for this object for widescreen displays. 


The shadows also seem to be too dark, so I'm not sure what's happened there. Maybe a palette optimization with the translucency for speed purposes on the 3DS? The Saturn conversion got this right, so I'm guessing it's not an oversight.  



Regarding the extras to change the car handling, I have mixed views on their merits and will wait to see how they play. Maybe being able to bump into traffic with no ill effects, drive off-road at full speed, grip corners more tightly and drive at a higher speed will be awesome and add a new dimension to the game. Maybe these are just cheap and easy features for M2 to implement! ;) Either way, they are pretty easy additions to CannonBall if they prove to be popular and there is a genuine demand for them.

In terms of a commercial OutRun release, this is probably as good as it's ever going to get so please buy a copy when it's released in your territory and show M2 and SEGA some support.

I'll keep this post updated as I find out more information!

Monday, April 21, 2014

Time Keeping

I've been chatting to Ade recently about the timing bugs present in OutRun. We initially discussed a timing bug that another blog reader, James Pearce submitted a fix for previously. Ade writes:

I believe the lap timing code in Out Run to be incorrect and would like your opinion on it. The timers are incremented every vertical blank so that should mean that seconds should increase by 1 every 60 vertical blanks.  I've looked at the original 68000 code and also your Cannonball source and it would appear that there's a bug in the code that handles the overflow from hundredths of seconds into full seconds.

I don't need to tell you that the 68000 code that increments the timers is at 0x007f4c in main cpu address space.  Specifically the bit of code that handles the overflow of hundredths to seconds is :-

007f58: cmpi.b   #$40, ($2,A1)       ; compare hundreds with 64 (should this be 60??)
007f5e: blt   $7f90                  ; branch if less than else reset hundredths and increment full seconds

Surely if the increment timers routine is called every vertical blank then it should be checking if hundredths are less than 60 and NOT less than 64?

I confirmed that this is indeed a bug in the Sega code. Ade looked into this further: 

I've been looking more and more into the timing issues and have come to the conclusion that Out Run timing is in quite a bad way and littered with bugs!

After doing the $40 to $3c alteration at $7f5b the timer still wasn't right, if I started a game with the dips set to normal (i.e. start time of 75 seconds on stage 1) the lap timer showed 1:18:50 when time ran out.  This was in comparison with 1:13:62 without the $40/$3c fix.

So I looked deeper into it and found another bug, this time in decrement_timers (0xb736).  The 68k here is :

subq.w #1, $60864.l            ; subtract 1 from the frame_counter
bge       $b760                ; branch if greater than or equal to zero

The Cannonball source is :-

if (--ostats.frame_counter >= 0)
    return false;

This is basically saying that the routine should still return false even if the frame_counter has reached zero, this is incorrect.  This means that the next time this routine is called the frame_counter (which is already at zero) will have another 1 subtracted from it, leaving a value of $ffff at $60864.w and it will have taken 31 iterations of this routine to reduce the time_counter by 1 whereby it should be 30 iterations.  The bge instruction should be a bgt instruction.  The Cannonball source should be '> 0' NOT '>= 0'.  By fixing this ($6c to $6e @ $b73c) I was getting closer to perfection!  Now when I started a game with 75 seconds on the timer the lap timer showed exactly 1:16:00 when time ran out.  The timing was now exactly 1 second out from where it should be.

The next bug I found was also in decrement_timers.  This time at the very end of the routine.  The Cannonball source is :-

return (ostats.time_counter < 0);

This should be <= 0 as, in its current guise, it will still count a whole second beyond the expiration of the timer before it returns a false value.  The 68k code uses the bcs (branch if carry set) instruction to test if the sbcd instruction has caused a carry by subtracting 1 from a value of 0.  To fix it in 68k requires a little more work but can be achieved by the fact that the sbcd instruction clears the Z flag if the result of the subtract operation is non-zero, otherwise it leaves it unchanged.  If the Z flag is set immediately before the sbcd instruction then it can be tested afterwards and if it's still set then we know that the result of the subtract was zero and can return a true value to indicate this.

I came up with this fix :-

00B74A: moveq #1, D1           ; replace moveq #0, D1 and addq.w #1, D1 with this single instruction
00B74C: move.w $60860.l, D0    ; move 16-bits from $60860 into D0 (make double sure that the sbcd instruction works correctly)
00B752: moveq #0, D5           ; trash D5 to set the Z flag in the CCR (D5 is unused so this is OK)
00B754: sbcd D1, D0            ; subtract D1 from D0 and set Z flag accordingly
00B756: beq $b764              ; branch if Z flag is still set after the sbcd instruction (counter has reached zero)

The instruction at $b74c (move.w $60860.l, D0) probably isn't needed and I could probably have got away with using the original instruction (move.b $60861.l, D0) as the sbcd instruction is byte-sized, not word-sized, but I erred on the side of caution, just to be double sure.

The above works well and I finally have a situation whereby I start a game with 75 seconds on the timer and the lap timer says 1:15:00 when time runs out!

There is a slight drawback though....  When the timer expires the game engine state changes from $c (GS_INGAME) to $f (GS_INIT_GAMEOVER).  This has the side effect of not updating the countdown timer at the top left of the screen (via the HUD display routine which checks the game engine state) and so it stays on 1 instead of being updated to 0.  So I need to alter the exit condition of the decrement_timers routine to set $60860.w to be 0 and then call draw_timer1 ($8216) before the game engine state is changed to $f, to force the game engine to update the HUD timer at the top left of the screen to zero.  I haven't done this yet, that's the next task!

I know that all your resource is currently tied up in Cannonboard but I was wondering whether you'd ever consider including fixes to the timing code in a future update to the enhanced roms.  I'm obviously intending on fixing up my own roms so that the total of all 5 laps exactly equals the overall game time when I cross the finish line, which will also agree to my stopwatch!

But I'm wondering how many other people out there are as bothered about it as I am?  It's a tough one to call as, like you say, the timing is so fundamental to Out Run and it's been wrong ever since day one so why bother to fix it now when people have got used to how it is.  It's a shame there's no more unused dip switches available where you could give people the option to toggle it fixed or original.

Now, we could fix these bugs in CannonBall. However, my original thinking was that having two timing systems would be confusing. I assumed players would want to compare times with the original machine and for a time to be consistent (even if it does not reflect the actual time you took to race the course!)

The only bug I have fixed relating to timing was a display bug with the EXTEND TIME overlay. What do you all think? 

Wednesday, April 16, 2014

CannonBoard Motion Control Part 2

The CannonBoard interface is progressing really nicely. Colin sent me this video earlier of the full moving cabinet working in conjunction with CannonBall.

You can see the motor calibration code is ported which moves the cabinet left and right at startup before finally centering. The in-game motor code, which I'd originally ported for force-feedback PC based steering wheels, can now be used as originally intended - to drive the cabinet's motor!



The dream is slowly becoming a reality and it's great to see the level of care and attention Colin has been pouring in to get the hardware just right. He is continuing to work on the audio interface next. 

Wednesday, April 09, 2014

CannonBoard Motion Control

In between changing nappies, I've had a small amount of time to work on the software side of CannonBoard. We're starting to get full motion control working with the sitdown cabinet.

The below video shows Colin demonstrating his OutRun cabinet connected to the Cannonboard interface. Currently the Arduino is running a ported version of the motor calibration code. This shows the interface is working and we'll be able to control the motor hardware from a PC running CannonBall.


In addition to this, we've verified that the previous work on the controls works via the original cabinet. It's a bit tricky to demonstrate though as the monitor output is to the PC currently.


My next steps are to finish the in-game motion control code and ensure the cabinet is moving correctly with the interface. Then controls and movement will be proven.

Colin is working on a version of the interface that removes the Arduino entirely. He is also working on the cabinet audio hardware interface. 

Saturday, March 15, 2014

CannonBoard First Steps

As a reminder CannonBoard is a project to enable OutRun machines to be cleanly swapped to a PC running CannonBall. A modern PC connects to an Arduino which in turn is connected to the CannonBoard hardware. The OutRun controls then plug directly into the CannonBoard hardware.

Colin posted me a prototype CannonBoard PCB last week. Click the images for a larger version.


Here's a shot from the back so you can see how it connects to the Arduino.


Here it is connected up to my chaotic test harness with the original OutRun connectors:


To make testing simpler, I'm using my hacked together OutRun controls. I normally attach these to an original OutRun PCB, but they're perfect for testing this setup.


Some LOL wiring here. It all works though. Note the stylish shoebox. 

CannonBall is currently working with the controls, which means there's no reason this shouldn't work with the original controls in a proper cabinet now. I've sent a test version back to Colin to play around with. In the meantime, I'm just pleased to have my name on a PCB.


I have another project in the pipeline - Project Baby. It's due to start any day now and will likely consume a fair chunk of time ;) Aside from that, I'll be working on the CannonBoard interface mostly during my moments of spare time. I'm looking forward to getting the motor outputs hooked up among other things.

Monday, January 27, 2014

CannonBall 0.22a - Continuous Mode

This release features a number of new features, important fixes and other changes.

Features:
  • Continuous Mode
    Play all 15 stages sequentially. This mode features its own high-score table.
  • Ability to toggle the fixed audio rom in the settings menu. It should be named opr-10188.71f and be placed in the roms directory. The fixed rom can be generated using bspatch and the relevant patch file from the enhanced edition pack
  • Fixed split axis support. XBox 360 pads should now work.
    The FAQ has some basic configuration advice. Thanks to baritonomarchetto for donating the pad. Rumble will also be supported in the future, but it means I'll have to upgrade the project to SDL 2. So it's a little more work than might be expected.

Core Engine Fixes:

  • Fixed a vehicle sprite bug that affected the angle of certain traffic sprites. Info here
  • Fixed two audio bugs that caused traffic noise to stutter under some circumstances, or not play correctly.
  • Corrected the pitch of PCM samples, they were played too quickly before. 

Other Minor Enhancements:
  • Ability to use controllers on other ports. This is configured in config.xml.
  • Support for arcade cabinets with a separate switch for high and low gear. This can be enabled in the gear options. 
  • The High Score table can display longer times to support Continuous Mode.
  • Added two handy game modes to toggle between 'original arcade' and 'enhanced' presets.

Quite a lot of code ended up changing to support Continuous Mode, so let me know if I broke anything in the process. Feel free to discuss the release on the forum

Download it here.

Update: Fixed the reported crash in continuous mode. This was a nasty bug that only materialized on a single level, when the code was compiled in release mode. 

Tuesday, January 14, 2014

CannonBoard Hardware Update

Colin Davies has been making solid progress on the CannonBoard project. This is the plug and play hardware interface that allows you to cleanly swap a modern PC into an original OutRun cabinet and run CannonBall.

"The audio is now hooked up to the original connectors. There is also a power supply input and dummy experimental load resistors to keep the Outrun PSU happy as it requires a minimum load (about 1 amp / 5 watts). This is important to balance the 5v for reliability and for the rest of the electronics on board to function. It will be optional whether the board runs from the Outrun 5v or the Arduino 5v."

The analog inputs still need to be hooked up; you can see the I/O layout below.



Soon we'll be at a point where we can start running some tests with CannonBall.