.XGM
The .XGM file format is used in Gitaroo Man to store .IMX textures and .XG models. It also defines the models' animations, grouping their keyframes into separate animations.
Data types used in this document (all little-endian):
- uint32: unsigned 4-byte integer
- float32: 4-byte floating-point decimal
- char[num]: null-terminated ascii string, of length num
Header
offset | size | data |
---|---|---|
+0x00 | 0x4 | uint32: number of texture entries |
+0x04 | 0x4 | uint32: number of model entries |
+0x08 | (varies) | texture entries |
(varies) | (varies) | model entries |
Texture entry
offset | size | data |
---|---|---|
+0x00 | 0x100 | [UNUSED] char[0x100]: texture's original path + filename |
+0x100 | 0x10 | char[0x10]: texture's filename This is how the game looks up textures for models, sprites, interface, etc. |
+0x110 | 0x4 | [UNUSED] uint32: index (0 for first texture, 1 for second, etc.) |
+0x114 | 0x4 | uint32: texture file's size |
+0x118 | 0x4 | [UNUSED] uint32: the sum of all textures' file sizes so far, not including the current one |
+0x11C | 0x4 | [UNUSED] uint32: unknown, 0 or 1
In practice, this value tends to be 1 for textures that are used for non-model purposes (e.g. HUD/interface, sprites, shadow, ST02 sky background). However, a texture can be used as both a sprite and a model texture at the same time, and this value won't tell you anything about the latter. |
+0x120 | 0x4 | [UNUSED] uint32: unknown, 0 or 1 |
+0x124 | 0xC | [UNUSED] garbage |
+0x130 | (varies) | texture file's contents (.IMX file) |
Model entry
offset | size | data |
---|---|---|
+0x00 | 0x100 | [UNUSED] char[0x100]: path and filename |
+0x100 | 0x10 | char[0x10]: model's filename This is how the game looks up which models to use. |
+0x110 | 0x4 | [UNUSED] uint32: index (0 for first model, 1 for second, etc.) |
+0x114 | 0x4 | uint32: model's file size |
+0x118 | 0x4 | uint32 num_anims: number of animation entries. (Even models without animations get 1 animation entry; not sure if that's an actual requirement.) |
+0x11C | 0x4 | [UNUSED] always 0? |
+0x120 | 0x20*num_anims | animation entries |
(varies) | (varies) | model (.XG file) |
Animation Entry
The animation entries take the model's one long animation and divide it into individual animations. Each animation entry represents an individual animation.
offset | size | data |
---|---|---|
+0x00 | 0x4 |
float32 playback_length: length of the animation in playback frames. It is possible for playback_length to be longer than the keyframes provided by the XG model (e.g. BGK1_FUSUMA.XG). In this case, the animation reaches the end of its keyframes, then freezes in place on the last frame of the animation until it reaches the end of playback_length. |
+0x04 | 0x4 | float32 keyframe_interval: number of playback frames from each keyframe to the next one. For example, if keyframe_interval==4, it is 4 playback frames until the next keyframe. That is, after playing a keyframe, it will play 3 interpolated frames and then 1 keyframe. |
+0x08 | 0x4 | [UNUSED] float32: always 60.0 |
+0x0C | 0x4 | float32 start_keyframe: the index of the keyframe this animation starts on. (Starts from zero. For example, if start_keyframe==0, this animation starts on the first keyframe in the XG file) |
+0x10 | 0x4 | uint32 speed_mode:
|
+0x14 | 0x4 | [UNUSED] always 0? |
+0x18 | 0x4 | [UNUSED] always 0? |
+0x1C | 0x4 | [UNUSED] always 0? |