STP is a run-length encoded VGA image format. Its name is an abbreviation of the word "stamp", which describes its intended use in drawing over an existing background with transparency. STP images are generally smaller than the full screen resolution, and it is the responsibility of the game engine to determine the on-screen coordinates at which an STP is to be drawn.
Related STP images are sometimes packed together in a simple archive that uses the ROL Format.
The file starts with a header of either four or five 16-bit words, depending on the version of the STP format being used. (J.R.R. Tolkien's Riders of Rohan uses Version 1, while Nomad uses Version 2.)
|UINT16LE unknown||STP Version 1 only. This 16-bit word is written with the value 1 in Version 1 STP files. It is absent in Version 2 files.|
|UINT16LE width||Width of the image in pixels|
|UINT16LE height||Height of the image in pixels|
|INT16LE hotspotX||Horizontal hotspot point, in pixels (i.e. X position within the image that appears at the coordinates at which the image is drawn by the game engine)|
|INT16LE hotspotY||Vertical hotspot point, in pixels (i.e. Y position within the image that appears at the coordinates at which the image is drawn by the game engine)|
Example of hotspot X,Y offsets: if the game engine is preparing to draw a stamp at 100,100 and the .STP data contains 02 00 03 00 in the bytes comprising the hotspot fields, then the stamp will actually be drawn with the upper left corner at 98,97.
Note that negative hotspot values appear to be allowed, at least by Riders of Rohan.
The STP raster image data starts at offset 0A for Version 1 files, and offset 08 for Version 2 files. Each chunk of data in the file starts with a runlength byte, which describes that chunk as being one of three types:
- Transparency: Marked by bit 7 being set (bitmask 80h). In the game engine, this simply advances the pointer in the output buffer by the number of bytes specified in the lower seven bits of this RLE byte (bitmask 7Fh). For example, B8h will advance the output pointer by 38h bytes. The effect of this is that the existing content of the output buffer will persist, making this run of pixels transparent.
- Repeat byte from input: Marked by bit 7 being clear and bit 6 being set. This loads the next byte from the input buffer, and repeats it to the output buffer the number of times specified in the lower six bits of this RLE byte (bitmask & 3Fh).
- Direct byte sequence copy from input: Marked by both bits 7 and 6 being clear. This copies the next n bytes, in sequence, from the input, where n is the value of this RLE byte.