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.