STATIC.SPR FILE HEADER ID bytes: value ---------------------------------------- HEADER 1 4 bytes: 0, due to absence of Animation Section 2 4 bytes: 12, offset of Image Offsets 3 4 bytes: Offset of the first image IMAGE OFFSETS 406 x 4 bytes: Image offsets relative to start of image section, so the first image has offset 0. They refer to the 5 facing directions (N, NE, E, SE, S) of all 81 units. The last offset is EOF (5 x 81 + 1 = 406). The order is first all directions of the first unit, then the second unit etc. The NW, W and SW facing images are created by mirroring the images for NE, E and SE, respectively. * What happens if there are MORE or LESS offsets? IMAGES ID bytes: value ---------------------------------------- IMAGE HEADER 1 16 bytes: 0, doesn't seem to have any effect 2 4 bytes: Image width 3 4 bytes: Image height 4 4 bytes: Number of leading empty columns 5 4 bytes: Number of leading empty rows 6 4 bytes: Number of columns (i.e. width up to the last non-empty pixel) 7 4 bytes: Number of rows (i.e. height up to the last non-empty pixel) 8 1 byte : 0xFD, this controls which color is treated as transparent. This only appies to the pixels actually present in the image encoding, not the "assumed" transparent pixels outside of the image's bounding box. The first 5 bits must be 1. The last 3 bits are in the order BGR (blue, green, red) and reflect the RGB values of the transparent color. For example, if the last 3 bits are 111, the transparent color is white. If the last 3 bits are 001 the transparent color is red. The default is 101 which makes the transparent color magenta. 0xFD is 11111101 in binary. 9 4 bytes: image body size IMAGE BODY ([Image Header value 7] - [Image Header value 5] rows) 1 4 bytes: Number of empty bytes. This number of bytes corresponds to half this number of transparent pixels. That is because the image is 16-bit, so it takes 2 bytes per pixel. 2 4 bytes: Row data size: N bytes, or N/2 pixels. 3 N bytes: Row image data. This image data is in 15+1 bit format (in Big endian byte order that would be: 1-5-5-5). The first bit indicates whether the pixel's shade is changed to the civ color (1) or not (0). The other 15 bits are 5 bits each in the order R-G-B. Transparent pixels are represented by magenta (Little endian 0x1F7C or Big endian 0111110000011111). This depends on Image Header value 8. IMAGE FOOTER 1 10 bytes: 0, doesn't seem to have any effect UNITXX.SPR FILE HEADER ID bytes: value ---------------------------------------- HEADER 1 4 bytes: 12, offset of Animation Section 2 4 bytes: Offset of Image Offsets 3 4 bytes: Offset of first image ANIMATION SECTION Animation Header: 1 32 x 4 bytes: Offsets of information for each animation (8 facing directions x 4 actions = 32 animations) The actions are, in order: Attack, Die, Idle, Move. The directions start at North, continuing clockwise to end at Northwest. The offsets indicate first all directions of Attack, then the animations for Die, then Idle and Move. Unit99.spr, used for the train animation, has exactly the same header. Since its Attack and Die animations are never used their offsets always point to an empty animation. NOTE: These offsets need not necessarily be in ascending order or even different. You could let the file contain only one animation, with all actions and directions using the same one. Animation Information: 1 X x 4 bytes: For each frame in an animation... (probably one long integer "bitmasked" into separate values) 1. Points to the Nth (zero-based) image in the file. This index actually uses 10 bits! The last two bits in the second byte are also part of this index. That means two things: there can't be more than 1024 images in an animation file, and more interestingly, you can reuse frames. 2. ..1. .... "Start loop" frame .1.. .... "End loop" frame (back to last start) 1... .... Mirrors a frame (horizontally) ...x xx.. These 3 bits control transparency: 000 = fully visible ... 111 = fully transparent (used for fading out dying units) .... ..xx Part of the image index from byte 1! 3. Byte 3 is almost always 06 but doesn't seem to be used for aything. Perhaps it was originally meant for controlling animation frame rate. 4. .... ...1 End animation/Don't display frame ??? .... ..1. Loop frame .xxx xx.. Not used (?) 1... .... Not used (hangs Civ2) DISCUSSION The 01 and 02 values only seem to occur in Resource.spr. It seems as if a fade-out animation must end with the byte sequence 0000 0001. It doesn't seem to be possible to control frame rate, e.g. Die animations often have two of the same frames following each other, which makes the animation twice as "slow" as the others. Animations that start with the "start loop", end with the "end loop" and are all marked with the byte 4 value 02 will play continuously (like the oil resources). Any frame in a loop that isn't marked with 02 will not be displayed, but WILL take up time. The tile won't be refreshed though, unless something else does refresh it (e.g. the blinking cursor). What that means is, the last visible frame will remain on- screen during the invisible frames' display time, EXCEPT when the cursor is over it. In that case, the animation will really disappear for the duration of the invisible frames... Even more, the cursor is a 64x64 pixel box, aligned to the bottom-left corner of the enclosing box of the tile it's on. Anything within that box will be refreshed, so it can also (partially) affect resource animations above or below it. An animation MUST either end with [XX XX XX01] (no loop) or with [XX 40 XX 02] (continuous loop). All frames in a loop must have their 4th byte on 02. In determining what to play, Civ2 will start at the header offset and continue until the first end loop/animation (Byte 2, bit 2/Byte 4 bit 8). It will then search back to the nearest start loop (B2b3) and animate up until the next end frame. E.g. if you remove the starting frame's B2b3, you will actually get to see the animation that's stored before it in the file. It will either play that once (ends with B4b8, otherwise byte 4 is 00) or play it forever (all frames B4b7, first frame B2b3, last frame B2b2). A value of 03 for byte 4 will make the entire resource invisible, until the screen is refreshed. If the end frame of an otherwise proper loop has 01 rather than 02, the end frame is not displayed, but the animation still loops. IMAGE OFFSETS X x 4 bytes: Image offsets (from start of image section), the last one of these offsets points to the end of the file. IMAGES As in Static.spr RESOURCE.SPR This one's pretty much the same as the units sprite files. Some extra notes: If a resource doesn't have animation, the corresponding header value points it to an empty animation (hex sequence 0020 0001, 0001 probably means something to the effect of "don't display me", the 20 part is the "start loop" flag). While the unitXX.spr has the first part of the animation header nicely in ascending order of offset, the resource.spr has that section in pretty random order. Plus, a lot of the animations are empty, so the animation "summary" points all of those to a final entry in the frame information part. The first part of the animation header is obviously different from the units: 1 88 x 4 bytes: (4 maps x 11 terrain types x 2 resources) In the following order: first resources of first map (following regular terrain order from Desert through to Ocean), second resources of first map, first resources of second map etc. In fact, that's exactly the order of the resources in the rules.