Executioners Sprite Format
Sprite files lack a specific signature, however, they start with a UINT16LE that gives the size of the sprite headers block, which is equivalent to the number of sprite entries multiplied by 13. This value is followed by the sprite entry headers themselves, and then by the actual sprite data, which is in Executioners RLE Format.
Because of this structure, the file type can be identified by determining the index at which the sprite data starts, and then checking if it matches the format of the header blocks of the Executioners RLE format; the first byte will be 0x10, and the fourth 0xFF.
Each sprite entry has a 0-terminated 13-byte entry in the file header as follows:
|UINT16LE||DataSize||Size of compressed data block|
|UINT16LE||Frame||Sprite frame image belongs to|
|INT16LE||X-offset||X-position to draw this image relative to sprite core.|
|INT16LE||Y-offset||Y-position to draw this image relative to sprite core.|
|INT16LE||X-offset (mirr)||X-position to draw this image relative to sprite core, when the image is mirrored to face left.|
|INT16LE||Y-offset (mirr)||Y-position to draw this image relative to sprite core, when the image is mirrored to face left.|
|BYTE||Unknown||Might be some kind of Z-offset. Usually 0, sometimes 1 or 2. 1 and 2 are generally used for special boss "cutscene" frames.|
Character sprites are divided into independently animating sections such as an upper and lower half, allowing for the full sprite image to have more states. Each 'part' of a sprite occupies its own 'frame' in the level and sprite files cannot share any frames of bugs will occur. What each image 'is' is also hard-coded into the game based on its frame number, limiting how they may be used.
The images have a horizontal/vertical offset that positions them relative to the sprite's 'core' position. These values vary depending on whether the sprite is facing right or left. The mirrored values are generally predictable, though; the Y-offset never changes, and the X-offsets of both facings are generally negative values that, when added together, result in the exact negative of the image width. Some exceptions exist, though, usually in more "cutscene" sprites like the car wheel in BOSS3.VOL.
The final value appears to be a Z-offset to determine the drawing order of the sprites, or some kind of priority value. Certain boss posing/intro frames and UI elements have 1 and 2, and changing some of these values has been shown to crash the game.
Despite the format having a table of frame data at the start of the file, the actual data inside that table only contains entry lengths, not offsets, meaning the data still needs to be read sequentially.
Each image is a single Executioners RLE compressed block. The game reads each block sequentially, using the sum of the block sizes given in the header entries to tell where a new block begins.
The game cannot handle 0x0 blocks; they will corrupt the entire screen.