NeoLemmix Graphic Set Format

From NeoLemmix V1.31n onwards, an entirely new graphic set format is the standard, although the old format is still supported. This new format is not based on a fixed structure, but rather a variable one, which allows any amount of content.

The graphic set file is a single DAT file, which contains two sections. The first section is the metadata section, the second section is the data section. The metadata section must be interpreted first, as it tells where in the data section to find each image or sound. There is only a single data section which contains both terrain and object graphics, unlike the old format which split those into two seperate sections. Additionally, it can also contain sound effects for custom objects. The NeoLemmix Graphic Set Tool always puts terrain images first, then objects, then sounds, but this is not a requirement of the format (it's simply how that specific program builds its output files).

The metadata section can be thought of as further divided into sub-sections. Each section starts with a marker to define which kind of section it is. This marker is always a byte 0xFF followed by another byte; this second byte determines the type of section. The NeoLemmix Graphic Set Tool always starts with a comment, then the header, then the terrains, then the objects; but this too is not a requirement of the format; the sections may be in any order (though it is recommended that the header come before any other section that isn't a comment).

A VGASPEC file can also be created by simply making a graphic set with no objects. In this case, the first terrain piece will be the graphic of the level, while the second and third pieces are masks, for steel and one-way-walls respectively (the latter is equivalent to marking a terrain piece as one-way-capable; it doesn't automatically apply a one way wall to it).



0xFF00 - End of file
The combination 0xFF00 marks the end of the metadata file. Anything past this should be ignored; it may be data for use by other programs.



0xFF01 - Comment
The combination 0xFF01 marks a comment. Generally this will be plaintext, but it could be anything as long as it doesn't contain another 0xFF. There is no fixed length for a comment, nor is there anything to indicate its length; just keep reading until the next 0xFF.



0xFF02 - Header
0xFF02 marks the header, which contains information about the graphic set. The header has a fixed structure and is always 48 bytes.
AddressFunction
0x00File format version number. Currently, this should be 0x01.
0x01Graphic set resolution. This is used so that higher (or lower) resolution graphics can be stored losslessly. 0x08 is standard NeoLemmix resolution; any graphic set with a resolution of 0x08 will not have its images resized. 0x10 is standard SuperLemmini resolution; so any graphic set with that setting will have its image sizes cut exactly in half.
0x02 ~ 0x0FUnused bytes. Leave them as zero.
0x10 ~ ~Eight colors, which are used for explosion particles; the first one is also used for builder bricks and the minimap. These are all 32-bit colors (8 bits per chanel) in ARGB format. Note that the alpha can generally be ignored; even NeoLemmix itself ignores it.

The header should be the first non-comment section in the graphic set; though NeoLemmix (and the NeoLemmix Graphic Set Tool) will handle graphic sets perfectly fine whether the header is the first non-comment section or not; just as long as there is a header somewhere in the file.



0xFF03 - Object
0xFF03 marks an object data entry. Object entries are 40 bytes and follow a specific format:
AddressFunction
0x00 ~ 0x01Object flags. This is a bitwise value, and currently only Bit0 is used; if this is on, the object only animates if triggered. This should be set on for objects such as teleporters, triggered traps, splitters, etc, and off for objects that constantly animate such as fire, water or one-way arrows. The one special case is pickup skills; even though they don't constantly animate, this flag should be set off.
0x02 ~ 0x03The number of animation frames the object has.
0x04 ~ 0x05The animation frame number to use on the preview screen. Note that unlike in the old graphic set format, this is a frame number, not the address of a graphic. Also note that, just as in the old format, certain object types will ignore this, such as pickup skills or locked exits.
0x06 ~ 0x07The "key" frame number. This has the same function it did before; the primary use of it is to define which frame of a teleporter's animation the corresponding receiver should begin animating at, or which frame of a receiver's animation the lemming should be released at.
0x08 ~ 0x0BThe address in the data section of the first frame of the object's animation.
0x0CThe type of the object. The values for object types are the same as in the old format.
0x0DThe sound effect number for the object. Like the object type, the values are unchanged from the old format.
0x0E ~ 0x0FThe object's trigger area's X coordinate (relative to the top-left corner of the object). This is a signed value.
0x10 ~ 0x11Trigger area Y coordinate. Signed.
0x12 ~ 0x13Trigger area width.
0x14 ~ 0x15Trigger area height.
0x16 ~ 0x17Currently unused. Leave them as zero.
0x18 ~ 0x19Secondary trigger area X coordinate. Some objects (such as two-way teleporters) need this second trigger area. This is a signed value.
0x1A ~ 0x1BSecondary trigger area Y coordinate. Signed.
0x1C ~ 0x1DSecondary trigger area width.
0x1E ~ 0x1FSecondary trigger area height.
0x20 ~ 0x28Currently unused. Leave them as zero.

You may notice that the dimensions of the object are not specified here. They're specified in the image data instead. If different frames are of differing sizes, NeoLemmix pads them out with blank space to all match the size of the largest frame.



0xFF04 - Terrain Piece
0xFF04 marks a terrain piece data entry. Terrain entries are 16 bytes and follow a specific format:
AddressFunction
0x00 ~ 0x01Terrain flags. This is a bitwise value, and currently only Bit0 is used; if it is on, the terrain piece is a steel piece.
0x02 ~ 0x05The address in the data section of the terrain piece's image.
0x06 ~ 0x0FCurrently unused. Leave them as zero.



0xFF05 - Sound Effect
AddressFunction
0x00Sound effect ID. This is the sound effect number to replace with this sound. 23 onwards are unused by system sounds (but can be used for custom objects).
0x01 ~ 0x04The address in the data section of the sound file data.




The graphics format in the second section is a lot simpler than the planar bitmaps in the old format. Additionally, widths no longer have to be padded to multiples of 8. There is no specific marker that says "an image's data begins here", so you must get the addresses from the metadata section.

An image's data starts with two four-byte values; the first is the width and the second the height of the image. After this is the actual image data. Each pixel is simply 32-bit (8 bit per channel) data, in ARGB order. However, there is one catch - if a pixel's alpha value is zero, then no RGB values for that pixel are present, and instead the next byte skips directly to the next pixel's alpha value.

For example:

0xFF 60 40 20 00 80 FF FF FF

The first byte is FF, so the first pixel has an alpha value of 255. The next three bytes are that pixel's red (0x60), green (0x40) and blue (0x20) components.
The next byte after this, which is the next pixel's alpha value, is 00. Because the alpha is zero, there are no RGB values for this pixel.
Thus, the following 80 is the following pixel's alpha value. This is not zero, so the next three bytes are it's R, G and B values, which are all FF.


Sound data in the second section simply consists of a four-byte value which states the size of the sound effect data, followed by the sound effect data itself in WAV format (just an exact copy of the WAV file).