Understanding Tot Sprite File Format ------------------------------------- Tot comes with three kinds of SPR files: Resource.spr (contains resource animations) UnitXX.spr (contains units animations) Static.spr (used to disable units animations but to keep different unit facing images) It's clear that SPR files are simply a collection of images, not necessary a collection of animations; Static.spr doesn't contain animations but simply different images for the same unit. Different SPR files have also a slightly different structure: UnitXX.spr contains several animations for a single unit (the unit number XX) while Static.spr contains still images for ALL units in the game. The Static.spr for the original game starts with: 00000000 0000 0000 0C00 0000 6406 0000 0000 0000 ........d....... 00000010 C705 0000 000B 0000 E50E 0000 1413 0000 ................ While in the Unit00.spr and Unit01.spr we have: (Unit00.spr) 00000000 0C00 0000 6C06 0000 E408 0000 8C00 0000 ....l........... 00000010 9C00 0000 AC00 0000 BC00 0000 CC00 0000 ................ (Unit01.spr) 00000000 0C00 0000 2C05 0000 8807 0000 8C00 0000 ....,........... 00000010 A000 0000 B400 0000 C800 0000 DC00 0000 ................ It seems clear (or at least highly probable) that Static.spr have an empty DWORD (0000 0000) preceding the normal SPR header (starting with 0C00) The rest of this header is greatly regular, we will find several blocks characterized by a sequence of (VALUE 0Y00) such as 0520 0600 (address 0xA0 of Unit01.spr) i'll call a block of this kind a "V/n" block, so a V/6 block represent a block such as VALUE1 0600 VALUE2 0600 etc. So, obviously, the first part of each *.spr files is a V/0 block but this is the only thing they have in common: UnitXX.spr after the V/0 shows a (discontinuous) V/6 block, followed by a short V/0 block. After it you'll find respectively a V/1, a V/2 and a V/3 block with a total size not fixed (it changes from spr to spr file) The first two elements of the V/0 block (addresses 0x4 and 0x8) are pointers, the first pointer (in reverse notation it is 0x66C in Unit00.spr) points to the end of V/6 block while the second pointer (in reverse notation 0x8e4 in Unit00.spr) points to the end of the V/3 block. Exactly 0x10 bytes after the end of V/3 block we will find an interesting pattern (4000 0000 4000 0000) that we will analyze soon. Static.spr is different: after the V/0 block it shows a V/1,V/2,V/3,V/4,V/5,V/6,V/7,V/8,V/9,V/A,V/B,V/C block and nothing else. The first element of the V/0 block (address 0x8) is a pointer, in reverse notation it is 0x664 and at address 0x664 of the static.spr we will find the end of V/C block, the end of what i think is the header. Exactly 0x10 bytes after the end of V/C block we will find the same pattern found before (4000 0000 4000 0000) that we will analyze soon. Analyzing UnitXX.spr is difficult because it's impossible to say how much images are stored for each animations, and it's difficult also to guess how much animations they'll contain (one for unit moving in each direction, one for unit waiting facing at each direction, one for unit attacking for each direction, and probably something else i'm forgetting). Static.spr analysis, instead, should be easy: Static.spr should contain a single image for each direction and for each unit in the game, so, the number of images should be easy to calculate. Looking at Tot running a game with static.spr we also discover that Tot simply flips unit image when this is possible (a unit facing left is obtained simply flipping the image of the unit facing right), so, even if in an isometric game as Tot the number of directions is 8, we need only 5 images for each unit (unit facing north, south, north-east, east, south-east). Looking at Units.bmp we will discover that Tot have 81 units (Units.bmp shows a grid of 9x9 units) and this give us a predicted value of 81*5=405 images contained in the static.spr I said that exactly 0x10 bytes after the end of headers (in static.spr AND in UnitXX.spr) we find the same pattern (4000 0000 4000 0000), this is interesting also because, even if the header size is different from spr to spr, thanks to the pointer at address 0x8, computer si always able to find the first (4000 0000 4000 0000) pattern. It seems that this pattern is written very often in the file, and preceed a chaotic sequence of bytes (probably the image). I decided to count the number of (4000 0000 4000 0000) patterns in static.spr and, guess what, the pattern seems to appear 406 times! (i counted it by hand so probably i double-counted a pattern, but i don't want to count them again, so, if you're curious, count them and make me know) I took the first block (which i'll call the image block, notice that probably the true image block starts before 4000 pattern, probably it starts 0x10 bytes before, keep this in mind) and placed a sequence of FFFF in it, sometimes this crashed Tot, sometimes the settler image showed a white row when i moved the settler north (so the first image block contains the image of the first unit facing north). After analyzing the block i discovered the following things: after 4000 0000 4000 0000 block we'll find a structured block (probably an header of some sort) which lasts for 0x17 bytes. after (starting, in original static.spr file,from address 0x691) we will find a sequence of small structures, each one representing a row of the image, with the first structure representing the top line of the image (only the top not-trasparent line) while the last structure will show the bottom line of the image (only the bottom not-trasparent line) This line structure is a bit strange to me (and this means there is still a lot to do before fully understanding this structure): the first byte represent the offset of the row (if you set it to 00 or FF the row is invisible, my guess is that doing so you pull the line out of view, too far on the right or to the left), values around 0x30 till 0x50 shows the line and 0x40 usually make the row starting from the middle of the image. After this (pretty strange) offset-byte you find an empty WORD (0000) followed by a WORD containing the nr of elements (pixels?) of the row not-trasparent, after this we have three (3?!) bytes empty and then we have a number of bytes representing the elements of the row not-trasparent, at this point the next line-structure will start. So, the rows structure is: AA 0000 00BB 0000 00CC CCCC ... CCCC / AA 0000 00BB 0000 00CC CCCC ... CC |-- BB bytes --| where AA is the offset-byte BB is the size of C block CC is the C block, each byte seems to represent a pixel on the row When the image block ends? Well, it's not clear, the size of the image block is not recorded in the spr file (at least i was unable to find it), anyway, i noticed that, after the last row-block there are always 5 empty WORDs (0000 0000 0000 0000 0000) probably this represent a row-block of size 0 even if i'm not sure. Coming back to the header i noticed that 0x40 is equal to 64 decimal and 64x64 is exactly the size of unit image in units.bmp, so probably the header 4000 0000 4000 0000 simply represents the size of the image. It's clear that this explanation is not satisfactory because the single byte which seems to represent a pixel in a row is not enough: if units are 24-bit bitmaps we need 3 bytes to represent a pixel and this is not possible in our representation, anyway i think it's a starting point to fully understand Tot SPR format. Let's try to understand something else: It's clear that the assumption that a byte represents a pixel is not true, in fact: Let's place a lot of 0C between address 0x853 to 0x087D (excluded), this will draw a blue row in settler image. if (for example) i set the WORD at address 0x864 to 0xFFFF i obtain two adjacent pixels of different colors (one is gray and the other is blue), while, if i set the DWORD at 0x864 to FFFF FFFF i have always a gray pixel followed by a blue pixel but between them i found two white pixels! My guess is that each pixel depends from preceding pixel and following pixel in a way i still miss to understand. Thinking back to Possidente's days in Tot forum i remember he once told that the SPR format was developed not to be obscure, but just for having an easy an useful way to store animations so my guess is that the image format is stored in some well-known standard image format, but i was unable to find a single format similar to the one described above, the only one which could be defined loosely similar is GIF (and DracoOmega once told us images were stored as GIF) but this puzzles me a bit, why MicroProse gave use 24-bit Units.bmp if they decided to keep GIF for animations, limiting our animations palette to 256 colors? Anyway, in the PNG specifications i discovered that many image formats, to increase compression ratio of an image, use some filters such as Cross-Filter or Sub-Filter. In the Sub-Filter, for example, the actual value of a pixel is calculated also on the value of preceding pixel using a predefined formula: Here's the description of the sub-filter implemented in PNG: " For each pixel, output the difference between that pixel and the previous pixel, modulo the range possible in that bit depth. For instance, for a bit depth of 8, if the previous pixel was 16 and the current pixel is 64, store 48. If the previous pixel was 255 and the current pixel is 20, store 25. Note that unsigned addition is used. IMPORTANT: At the start of each line, consider the previous pixel value to be zero. " The Cross-Filter instead depends on color values of preceding and following rows color but in SPR file it seems that each row is independent from each other so i think the best guess is a sort of sub-filter. I've not implemented the sub-filter algorithm, so i can't say SPR file is not using the algorithm described above, but i think it would be better to understand the standard graphic format Microprose used instead of rewriting filters by hand.