The details of our FLC format are somewhat tricky and they are complicated by the fact that there are a few (non-fatal) bugs in the format which have been corrected in the code but not in all of the FLC files (so that the artists didn't have to re-build all of the FLCs). This is probably not the best implementation of a FLC format and I would have done some things differently had I created the format. For example, I would not have used the "reserved" area of the FLC header to store internal data -- especially since the FLC format supports user-defined chunks for just that purpose. Unfortunately, the format already existed when I started working on Civ3 so the format had already been made standard.
The name of our "custom" FLC format is FlicAnim and the header is the FlicAnimHeader. The FlicAnimHeader structure is 28 bytes long and consists of 10 fields. The remaining 12 bytes of the reserved field are set to 0:
- DWORD size: Set to the size of the FlicAnimHeader structure (currently 28 bytes or 0x001C)
- int flags: This field is used internally and by our FlicAnim creator and should be set to 0.
- WORD num_anims: This is equivalent to the number of directions stored in the FlicAnim. This value can be calculated by dividing the total number of frames in the FLC (from the FLC header) by the anim_length (see below).
- WORD anim_length: This is the number of frames in each direction. Note that each direction must have the same number of frames.
- WORD x_offset: The pixel offset from the left edge of the image to the clipped sprite (see below).
- WORD y_offset: The pixel offset from the top edge of the image to the clipped sprite (see below).
- WORD xs_orig: The pixel width of the non-clipped sprite (see below).
- WORD ys_orig: The pixel height of the non-clipped sprite (see below).
- DWORD anim_time: This is the frame rate of the animation. It can be calculated with the following formula:
anim_length * 1000 / fps
where fps is the frames per second at which the FLC is supposed to be played. The value is in milliseconds. I'm not entirely sure if this is used.
- int directions: Bit flags representing which directions are present. If a bit is set, that direction is present.
Bit 0: southwest
Bit 1: south
Bit 2: southeast
Bit 3: east
Bit 4: northeast
Bit 5: north
Bit 6: northwest
Bit 7: west
I believe this was done so that you could have an animation with 4 directions and set bits 1, 3, 5, and 7 so that you have just the cardinal directions (for example). However, I don't think this will work for units in Civ3.
Note
DWORDs are 4 BYTES and are unsigned.
WORDs are 2 BYTES and are unsigned.
ints are 4 BYTES and they are signed.
Clipping
Our FlicAnim program calculates the smallest bounding box needed to contain all of the frames of the animation. The upper-left corner of this bounding box is stored as
x_offset and
y_offset. The
xs_orig and
ys_orig are the original height and width of the image (not taking the bounding box into account). I believe all of our units are 240x240 which is why you found these fields to always be 240.
FLC header
The standard FLC header has the expected data except the following:
- The Size field should contain the total number of frames in the file (num_anims * anim_length). The actual number of frames will be Size + 1 because all FLC files contain a ring frame for looping purposes.
- The Speed field should be set to 4.
- The Creator field should be set to 0xF1F1F2F2, which desginates the FLICSPRITE_CREATOR we use to make the FlicAnims. (Note that the FLC specs state that this should be 0x464C4942 if not created by Animator Pro - I'm not sure why this info was ignored).
Palette
Most of our unit FLCs contain a bug wherein the FLI_COLOR_256 chunks contain an incorrect size. As the game knows that all of our palettes are 256 colors, it doesn't cause a problem. It does, however, cause problems in other programs that attempt to load our FlicAnims. Our most recently created units should contain the proper size information.
Compression
I'm fairly certain there is a bug in the FLI_WORD_LC (also referred to as FLI_SS2) compression used for many of the frames as well. I've read differing descriptions of the format that explain the skip count. In some descriptions, the skip count represents the number of 2-pixel words to skip while in others, it is the number of bytes to skip. Our format treats the skip count as the number of bytes to skip.
There may, in fact, be more bugs in the format than I've mentioned and haven't caught yet, so beware. Also, keep in mind that since I am still working on some of these issues, some of this could potentially change (though I don't think it's likely). It's also possible we will make tools available in the near future although the details on that are sketchy at this point.