Differences between the standard Silverstone track and the extra track files
The extra track files in the Revs 4 Tracks expansion pack are designed to be drop-in replacements for the original game's Silverstone track file. The expansion pack doesn't actually include Revs itself - it just includes the four extra track files, plus a simple menu program that loads one of the new tracks into memory before running the game from the original disc or cassette. The only difference when driving Brands Hatch instead of Silverstone is the track data file; the game itself is exactly the same.
You might assume, then, that the extra track files are simply variants of the Silverstone file format, with different data for the new tracks, but it turns out that the majority of the content in the extra track files is completely different to Silverstone. The extra tracks aren't variants of the original format, they are a major redesign.
For an introduction to the differences in the extra tracks, see the deep dive on secrets of the extra tracks. In this article we're going to take a closer look at the structure of the extra track files, when compared to the original.
Comparing the track files
Below, you can see a breakdown of the structure of the extra track files, compared with the Silverstone track file (I've chosen to compare the Donington Park track with Silverstone, as it contains the most differences, but all the extra track files are broadly similar). The two file formats are the same size, with 1,849 bytes of data for each track, though the extra track files are padded out to be 2,000 bytes long, and include a block of unused memory at the end. This extra block is ignored and has no effect on the game, so for now we're just going to concentrate on the data (though see below for an analysis of these extra bytes, as they don't just contain random noise).
Once the loading process has finished (as described in the deep dive on the jigsaw puzzle binary), the track file can be found at address &5300, with the final entry being the CallTrackHook routine. The track data files also contain the track's checksum and name, but these are discarded once the track has been loaded and verified.
It's worth noting that all of the labels in the Silverstone track also appear in the extra track file, though some of them are in different places. In the table below, asterisks (*) denote labels that are only used while the extra track is loading; once the track has loaded, these labels are discarded, and are replaced by the labels from the Silverstone side. So, once the extra track has finished loading, xTrackSegmentI will be at &5400, yTrackSegmentI will be at &5500, and so on, just like in the Silverstone track.
As with the Silverstone track, data names that start with "track" (or, in the case of axis-based coordinates or vectors, with "xTrack", "yTrack" or "zTrack") denote read-only data, so the new data block at trackSubCount in the extra tracks is read-only, for example. However, this convention no longer applies to the segment vector tables in xTrackSegmentI, yTrackSegmentI, zTrackSegmentI, xTrackSegmentO and zTrackSegmentO, as in the extra tracks these are dynamically generated rather than being hard-coded; I've left the variable names as they are, to avoid confusion.
Here is the comparison of the two different file structures:
Donington Park Address Silverstone -------------- ------- ----------- Track section data (Part 1 of 2) &5300 Track section data (Part 1 of 2) Multiply80Percent &53D0 xTrackSignVector HookFlipAbsolute &53D7 HookJoystick (Part 3 of 3) &53DC &53E0 zTrackSignVector HookForward &53E9 &53F0 yTrackSignVector ModifyGameCode (Part 4 of 4) &53F3 subSection &53FA trackSubCount &53FB yawAngleLo &53FC yawAngleHi &53FD segmentSlope &53FE subSectionSegment &53FF * modifyAddressLo &5400 xTrackSegmentI * modifyAddressHi &5414 trackYawDeltaHi &5428 trackSignData &5462 CalcSegmentVector &5472 Multiply8x8Signed &54EB HookDataPointers &54EF * newContentLo &5500 yTrackSegmentI * newContentHi &5514 trackYawDeltaLo &5528 xTrackSignVector &5562 HookSegmentVector &5572 MoveToNextVector &557F UpdateDataPointers &5582 HookMoveBack &55BD SetSegmentVector &55C4 * ModifyGameCode (Part 3 of 4) &5600 zTrackSegmentI trackSlopeDelta &5628 yTrackSignVector &5662 HookSectionFrom &5672 HookUpdateHorizon &56AF HookFieldOfView &56BC HookFlattenHills &56C8 * ModifyGameCode (Part 1 of 4) &5700 xTrackSegmentO trackSubSize &5728 zTrackSignVector &5762 HookFixHorizon &5772 HookJoystick (Part 1 of 3) &5779 Hook80Percent &57B6 xTrackCurve &57BF * ModifyGameCode (Part 2 of 4) &5800 zTrackSegmentO trackSlope &5828 trackYawAngleLo &5846 trackYawAngleHi &5864 trackSubConfig &5882 trackSteering &58A0 zTrackCurve &58BF Track section data (Part 2 of 2) &5900 Track section data (Part 2 of 2) HookSlopeJump &59C9 &59D0 trackSteering HookJoystick (Part 2 of 3) &59D8 &59EA trackSignData HookBackground &59ED trackSectionCount &59FA trackSectionCount trackVectorCount &59FB trackVectorCount trackLength &59FC trackLength trackStartLine &59FE trackStartLine trackLapTimeSec &5A00 trackLapTimeSec trackLapTimeMin &5A03 trackLapTimeMin trackGearRatio &5A06 trackGearRatio trackGearPower &5A0D trackGearPower trackBaseSpeed &5A14 trackBaseSpeed trackStartPosition &5A17 trackStartPosition trackCarSpacing &5A18 trackCarSpacing trackTimerAdjust &5A19 trackTimerAdjust trackRaceSlowdown &5A1A trackRaceSlowdown HookFirstSegment &5A1B CallTrackHook &5A22 CallTrackHook trackChecksum &7800 trackChecksum trackGameName &7804 trackGameName trackName &7808 trackName
To summarise the differences between the file structures:
- The following data are unchanged between the two formats: the two blocks of track section data, all the data from trackSectionCount to trackRaceSlowdown, the CallTrackHook routine, and the track's checksum and names.
- The following data have moved in the extra track file: xTrackSignVector, yTrackSignVector, zTrackSignVector, trackSteering and trackSignData.
- The segment vector blocks at xTrackSegmentI, yTrackSegmentI, zTrackSegmentI, xTrackSegmentO and zTrackSegmentO contain 256 bytes each in Silverstone, but only 40 bytes each in the extra tracks (and in the latter they are dynamically generated rather than hard-coded).
- Everything else in the extra track data file is new and does not appear in the Silverstone track.
For information on the entries in the Silverstone track, see the deep dive on the track data file format, while for details of the variables and routines in the extra tracks, see the deep dive on secrets of the extra tracks.
Source code clues in the extra track files
As is often the case with BBC Micro assembly programs, Revs contains snippets of "background noise", left over from the compilation process. There's a great example of this in Aviator, Geoff Crammond's previous game - you can read all about this, and the concept of noise, in this deep dive in my Aviator project.
Unfortunately, the main game binary in Revs doesn't contain any interesting source code clues, but the extra tracks do contain a tiny snippet of interest, bolted on to the end of the file. This extra content is ignored and is presumably only there because the extra track files were saved out to be exactly 2,000 bytes long (of which only 1,849 bytes is data). It does, however, contain a bit of BBC BASIC code, in tokenised form, which we can expand to the following:
DATA " BRANDS HATCH"," DONINGTON PARK"," OULTON PARK "," SNETTERTON " DATA"" REM Programs on the disc or tape DATAB ,D ,O ,S DATA""
I haven't converted the tokenised line numbers, as that's a really fiddly process, but this is still a genuine snippet of Geoff Crammond's original source code. It's clearly something to do with the Revs 4 Tracks expansion, and it doesn't tell us an awful lot, but it's still interesting to see a genuine artefact from the development process, however small.