anim.binltl Animation file format

NB. This is a description of the in-game BINARY file format for animations. You are advised not to use this format, but to contribute to the discussion on an XML format for these files.

This is some sketchy information about the anim.binltl file format. These contain the BinImageAnimation and associated structs. These are used to animate single elements in a scene. They store the description of the animation keyframes used, but not the actual item to be animated. This means a single BinImageAnimation (such as rot_1fps) can be used in multiple places.

BinImageAnimations are also used for each item animated in a movie, though in that case they're stored within the movie.binltl file.

File format

The file is unencrypted binary data, roughly corresponding to the C structs used in the game. Pointers are stored as offsets from the start of the file.

Note that when the BinImageAnimation appears within a movie file, the pointers in BinImageAnimation after relative to the start of the file, but the pointers they point to are relative to the start of the BinImageAnimation.

Simple types

float - 32-bit floating point in IEEE 754 floating-point "single format" bit layout
int - 32-bit little endian integer
char * - stored in files as a sequential list of null-terminated strings
enum = stored in the file as ints

enum TransformType {
      XFORM_SCALE = 0,
      XFORM_ROTATE = 1,
      XFORM_TRANSLATE = 2
};
 
enum InterpolationType {
      INTERPOLATION_NONE = 0,
      INTERPOLATION_LINEAR = 1
};

Complex types

struct keyframe
{
+0x00:      float x;
+0x04:      float y;
+0x08:      float angle;
+0x0c:      int alpha;
+0x10:      int color;
+0x14:      int nextFrameIndex;
+0x18:      int soundStrIdx;
+0x1c:      InterpolationType interpolation;
};
 
struct BinImageAnimation
{
+0x00:      int mHasColor;
+0x04:      int mHasAlpha;
+0x08:      int mHasSound;
+0x0c:      int mHasTransform;
+0x10:      int mNumTransforms;
+0x14:      int mNumFrames;
 
+0x18:      TransformType *mTransformTypes;
+0x1c:      float *mFrameTimes;
+0x20:      keyframe ***mXformFrames;
+0x24:      keyframe **mAlphaFrames;
+0x28:      keyframe **mColorFrames;
+0x2c:      keyframe **mSoundFrames;
+0x30:      const char *pStringTable;
};

Note that mXformFrames has an extra indirection, this is because there is one keyframe per frame per transform type (mNumTransforms).

File order

There is a single BinImageAnimation at the start of the file. All other items are referenced by "pointers" within this structure (offsets from the start of the file).

When the BinImageAnimation appears inside a BinMovie, the offsets are relative to the start of the BinImageAnimation, so you must compare them with 0 before shifting them.

Example

res\anim\rot_1rps.anim.binltl:

hasColor = false
hasAlpha = false
hasSound = false
hasTransform = true
numTransforms = 1
numFrames = 3
transformTypesOffset = 52
frameTimesOffset = 56
xformFramesOffset = 68
alphaFramesOffset = 84
colorFramesOffset = 96
soundFramesOffset = 108
stringTableOffset = 120
frameTimes[0] = 0.0
frameTimes[1] = 0.5
frameTimes[2] = 1.0
transformTypes[0] = ROTATE
frameOffset = 72
framePointer = 124
transformFrames[t=0,ROTATE][frame=0] = KeyFrame{x=-1.0, y=-1.0, angle=0.0, alpha=-1, color=-1, nextFrameIndex=1, soundStrIndex=0, interpolationType=LINEAR}
framePointer = 156
transformFrames[t=0,ROTATE][frame=1] = KeyFrame{x=-1.0, y=-1.0, angle=180.0, alpha=-1, color=-1, nextFrameIndex=2, soundStrIndex=0, interpolationType=LINEAR}
framePointer = 188
transformFrames[t=0,ROTATE][frame=2] = KeyFrame{x=-1.0, y=-1.0, angle=360.0, alpha=-1, color=-1, nextFrameIndex=-1, soundStrIndex=0, interpolationType=LINEAR}
framePointer = 0