VGFM Tileset Format

From ModdingWiki
Jump to navigation Jump to search
VGFM Tileset Format
VGFM Tileset Format.png
Format typeTileset
HardwareVGA
Max tile count65535
PaletteExternal
Tile names?No
Minimum tile size (pixels)16×16
Maximum tile size (pixels)16×16
Plane count1
Plane arrangementLinear
Transparent pixels?Yes
Hitmap pixels?No
Metadata?None
Supports sub-tilesets?No
Compressed tiles?No
Hidden data?No
Games

The VGFM Tileset Format is used by Vinyl Goddess From Mars to store the graphics used to draw game levels.

Signature

There is no signature, but careful parsing of the fields to ensure they have expected values can allow files to be detected. There is no data trailing the pixelData field, so if this field ends right at the end of the file, it is highly probable the file is in this format.

File format

The file begins with pixel data for each tile, stored in the form of lookup codes. After the last tile's data, there is a list of which lookup codes map to which pixels. The lookup codes are each two bytes long, while the pixels they map to are four bytes long.

Data type Name Description
UINT16LE count Number of tiles in the tileset
TILE[count] tile Variable length data for all tiles (see below)
UINT16LE lenPixel Length of pixel data
UINT8[lenPixel] pixelData Pixel data, lenPixel bytes long

The TILE structure is as follows:

Data type Name Description
UINT16LE lenTile Number of bytes in the tile data
UINT16LE[lenTile / 2] codes List of codes, lenTile bytes long (see below)

Each tile is fixed at 16×16 in size.

Where lenTile is 0x80, the tile is composed of 64 UINT16LE values (to make up a length of 0x80 bytes.) Each value is a code that needs to be decoded as described below. There is no mask/transparency in this tile.

Where lenTile is 0xC0 instead, there is additional information for the transparency. The tile is treated as before, but with an additional UINT8 value inserted before each UINT16LE. The lower four bits of the UINT8 control the mask for the corresponding four pixels represented by the UINT16LE code value.

Some examples: (split over multiple lines for readability)

 80 00   # Length, here 0x80
 00 00   # Code 0x0000
 05 00   # Code 0x0005
 ...
 C0 00   # Next tile, length is 0xC0 so this has a mask
 0f      # Mask byte for first four pixels on the first line
 00 00   # Code 0x0000 again
 03      # Mask byte for second four pixels on the first line
 06 00   # Code 0x0006
 ...

Only the lower four bits of the mask byte are used, and these are in opposite order - i.e. the LSB (value 1) is the pixel at x=0, the next bit (value 2) is x=1, bit value 4 is x=2, and bit value 8 is x=3. The bit is set to 1 if the pixel is opaque and 0 if it is transparent.

Decoding tiles

The tiles are stored as a list of UINT16LE values (here called "codes".) Each value is a lookup code, representing four pixels. To find the actual pixel values, this code must be looked up in the pixelData table and those values used.

For example, if the first code in a tile has a value of 0x0000, then the first four pixels in the tile are the first four bytes (0..3) in pixelData. A code of 0x0001 would represent the second lot of four bytes (4..7) in pixelData.

If the second code (target pixels y=0, x=4..7) has a value of 0x0005, then bytes 20..23 in pixelData would be copied into y=0, x=4..7 in the final image.

In the example above, the two tiles start with the same code (0x0000). This means the first four pixels of both tiles will be the same.

Credits

This file format was reverse engineered by Malvineous. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)