TempEd - Tempest Level Editor


Technical Info

Tempest Data Structures

This document describes the data structures used by Atari's Tempest. The latest version of this document should be available from the TempEd site at http://www.thundercross.freeserve.co.uk

1 - Tempest Level Data

The information required is contained in the ROM file '136002.118'. TempEd uses the following C structure:

typedef unsigned char uint8; // Byte type
typedef signed char sint8;

typedef struct
{
    uint8 x[16][16];
    uint8 y[16][16];
    uint8 angle[16][16];

    uint8 remap[16];
    uint8 scale[16];
    uint8 y3d[16];
    uint8 y2d[16];
    sint8 y2db[16];
    uint8 open[16];
    uint8 fscale[16];
    uint8 fscale2[16];
} level_data;

The data is stored at an offset of 380 into the 2K ROM file, i.e. :

...
uint8 data[2048];
level_data *LevelData;
...
// Read '136002.118' into 'data'
...
LevelData = (level_data*)&data[380];
...

Details

x : the x-coordinates of the points in the level. x[L][P] is the x-coordinate of point P of level L.
y : the y-coordinates of the points in the level. y[L][P] is the y-coordinate of point P of level L.

x & y are in the range 0-255.
Note that the arcade game applies a y-scale of 125% to everything drawn.

angle : the angles of the sectors in the level. angle[L][S] is the angle of sector S of level L.

angle is in the range 0-15 (representing 0-360 degrees).
It proved difficult to calculate the angle in a way that exactly matched the values in Tempest's original levels. Presumably, these values were calculated by hand and possibly tweaked a little. If these values are too far out, problems arise such as flippers rotating constantly, unable to 'connect' with the next sector.

remap : the order of the levels as encountered in the game.

remap is in the range 0-15 (representing levels 1-16).
Level L is actually stored as level remap[L]. You will note that the original levels are not stored in the order in which they are played.

scale : the scale of the levels, or more accurately one-over the scale since small values give big levels.

scale is in the range 1-255, although 10-28 is the range of the original levels.

y3d : the 3D y-offset, or 'camera height' for the levels.

y3d is in the range 0-255.

y2d : 'Low' byte of 2D y-offset.
y2db : 'High' byte of 2D y-offset. This is a SIGNED value.

y2d is in the range 0-255. y2db is (usually) in the range -2 to +2.
The 2D y-offset is stored as a 16-bit value, i.e. :

yoffset = LevelData->y2db[L]*256 + LevelData->y2d[L];

open : open / closed status of the levels.

open is either 255 or 0.
A closed level has 16 sectors and is looped. An open level has 15 sectors and does not loop. If open[L] is 255, then level L is open.

fscale : 'Low' byte of flipper scale.
fscale2 : 'High' byte of flipper scale.

The 'flipper scale' is the value used to scale the flippers when they are in the act of flipping. When flippers are lying fully in a sector, they take their shape from that sector's co-ordinates. Like the level scale, small values mean big flippers.
This was the most troublesome piece of data to work out. Although it seems to be a 16-bit value, it is not stored in the usual way. Instead, fscale only represents the first 7 bits, and fscale2 the rest. So the full value is recovered as:

fs = LevelData->fscale2[L]*128 + LevelData->fscale[L];

TempEd calculates this value based on the average sector width of the level (actually, one-over the average width).

2 - Tempest Text Messages

Text messages are stored in the ROM file '136002.121', starting from an offset of 350. The string format is odd. The last character in a string is signified by having its topmost bit set. This allows strings to be stored with no terminating characters between them, although Tempest makes no use of this. The remaining bits should be divided by 2 - presumably the game uses them to index into a table of 2-byte values. 0 represents 'space', 1-10 represent the digits '0' to '9', 11-36 represent 'A' to 'Z', 38 is '-', 39 is '1/2' and 40 is the copyright symbol. 37 is unused, and appears as 'space'.

3 - Tempest Colour Data

Tempest uses a colour table to decide the colours for the level, player and enemies for a given 'cycle' (ie. set of 16 levels). Cycle 1 is the blue levels, cycle 2 the red levels etc. The table is contained in the ROM file '136002.119', at an offset of 509 bytes. The colours are stored in the following order : bullets (also explosions and 'AVOID SPIKES' message), claw (player), tankers, flippers, pulsars, spikers (also score), level, info (level number & 'SUPERZAPPER RECHARGE' message). The values are repeated for the 6 cycles, giving a table of 48 bytes.
Only the bottom 4 bits of each byte should be considered - some of the table entries have (seemingly) unused bits set in the top 4 bits. This may have been an attempt to disguise the table's purpose, or just an artefact of the game's programming. Although 16 values are available, Tempest only has 8 colours (red, green, blue, cyan, magenta, yellow, black & white). The MAME source implies some Atari vector games could display each colour at 2 intensities, but Tempest seems to lack this. Oddly, the colour table contains only one value to represent each colour as if the bottom bit has some meaning. These values are : 0 = WHITE, 3 = CYAN, 4 = YELLOW, 7 = GREEN, 8 = MAGENTA, 11 = BLUE, 12 = RED, 15 = BLACK. In MAME, a colour of 1 would also be white, but I don't know what the arcade machine would do.

(C) 2000 Simon Mills