.SSQ

From Gitaroo Pals
Jump to navigation Jump to search

The .SSQ file format, also known as a Stage Definition file, is used in Gitaroo Man and Gitaroo Man Lives!. This file:

  • Tells models & the camera where to go and what to do
  • Tells the player model how to react to controller inputs, damage, etc
  • Sets up sprites, such as the charge effects
  • Sets up texture animations for speaking and such

Notes:

  • only checked on PS2 version so far

Data types used in this article (all little-endian):

  • uint32: unsigned 4-byte integer
  • float32: 4-byte floating-point decimal
  • char[num]: character array aka string. Strings are null/zero-terminated, and after the null byte there maybe garbage (which is ignored).

File overview

Stage

This section encompasses the entire SSQ file.

offset size data
+0x00 0x4 Magic stamp, always 'GMSX'
+0x04 0x4 uint32 stage_header_version: always 0x1200?
+0x08 0xC all 0? Likely ignored[1]
+0x14 0x10 garbage? Likely ignored[1]
+0x24 0x4 uint32 num_xg_entries_related: Equal to num_xg_entries below.

Details: All SSQ files in the game (PS2 US, PSP US) have this value equal to num_xg_entries. Messing with this value in the PS2 version affects memory allocation somehow. When experimenting with stage 1: Especially large values would crash the game from running out of memory. Values lower than num_xg_entries did not use less memory, in fact it used slightly more. Setting this value equal to num_xg_entries used the least memory and is recommended.

+0x28 0x4 uint32: num_imx_entries
+0x2C num_imx_entries*0x20 ImxEntry[num_imx_entries]
(varies) 0x4 uint32: num_xg_entries
(varies) num_xg_entries*0x30 XgEntry[num_xg_entries]
(varies) (varies) ModelSetup[num_xg_entries]
(varies) (varies) CameraSetup
(varies) (varies) SpritesSetup

Afterwards, the following values are read only if stage_header_version >= 0x1100:

offset size data
(varies) 0x4 uint32: num_texanims
(varies) (varies) TexAnim[num_texanims]

Afterwards, the following values are read only if stage_header_version >= 0x1200 (not in the Japanese PS2 version):

offset size data
(varies) (varies) PSetup

ImxEntry

An ImxEntry refer to an IMX texture file. Often contains CHARGE_BLUE/RED.IMX—the game gets them from here specifically, seeing how those two textures aren't associated with any models. An ImxEntry may also contain a texture that is associated with a model. (In one particular case, Stage 0 has an ImxEntry containing a nonexistent texture.)

offset size data
+0x00 0x10 char[16] imxname: name of IMX file (e.g. FILENAME.IMX)
+0x10 0x4 unused (gets copied to memory, but is never used)
+0x14 0x4 unused (gets copied to memory, but value gets overwritten before game uses it)
+0x18 0x8 unused (gets copied to memory, but is never used)

XgEntry

An XgEntry refers to an XG model file and describes what type of model it is.

offset size data
+0x00 0x10 char[16] xgname: name of XG file (e.g. FILENAME.XG)
+0x10 0x4 uint32 is_clone: unused (copied to memory but not read back)

Details: This value is 1 if this is a clone of a model from a previous XGEntry, 0 if it is not.
Potentially used in the PSP version (haven't checked).

+0x14 0x4 uint32 clone_id: unused (copied to memory but not read back)

Details: It may be that if is_clone==1, this value is the index of the XGEntry to clone from.
Potentially used in the PSP version (haven't checked).

+0x18 0x4 unused (copied to memory but not read back)
+0x1C 0x4 uint32 model_type:
+0x20 0x04 [unused] float32, some animation length value (copied to memory but not read back)
+0x24 0x04 [unused] float32, animation speed (copied to memory but not read back)
+0x28 0x04 [unused] float32, framerate (copied to memory but not read back)
+0x2C 0x04 [unused] unknown, probably junk (copied to memory but not read back)

ModelSetup

The are 4 possible types of ModelSetup entries. The type of ModelSetup read depends on the value of the corresponding XgEntry's model_type.

NormalModelSetup

Base setup for every model to be used

offset size data
+0x00 0x4 Magic stamp, always 'GMPX'
+0x04 0x4 uint32 modelsetup_header_version: seen 0x1400, 0x1200. Any other values?
+0x08 0x4 vaguely size-related? Likely ignored[1]
+0x0C 0x8 all 0? Likely ignored[1]
+0x14 0x10 garbage? Likely ignored[1]
+0x24 0x4 uint32 numPositions
+0x28 0x4 uint32 numRotations
+0x2C 0x20*numPositions ModelPosition[numPositions]
(varies) 0x20*numRotations ModelRotation[numRotations]
(varies) 0x4 uint32 numAnims
(varies) 0x30*numAnims ModelAnim[numAnims], Only read if numAnims >= 2

Afterwards, the following values are read only if modelsetup_header_version >= 0x1100:

offset size data
(varies) 0x4 uint32 numScalars
(varies) 0x20*numScalars ModelScalar[numScalars], only read if numScalars >= 2
(varies) 0x40 a single 0x40-byte entry

ModelPosition

Model position in 3D space

offset size data
0x00 0x4 float32, frame index on global timeline
0x04 0x4 float32, number of frames before the next position value, reciprocated
0x08 0x4 float32, X-coordinate
0x0C 0x4 float32, Y-coordinate
0x00 0x4 float32, Z-coordinate
0x04 0x4 uint32, interpolation between positions - 1 if true
0x08 0x4 uint32, frame index * 160
0x0C 0x4 uint32, unknown

ModelRotation

Model rotation along the XYZ axes [2]

offset size data
0x00 0x04 float32, frame index on global timeline
0x04 0x04 float32, number of frames before the next position value, reciprocated
0x08 0x10 float32, quaternion of rotation (XYZW)
0x18 0x04 uint32, interpolation between rotations - 1 if true
0x1C 0x04 uint32, frame index * 160

ModelAnim

Handles applying model animations

offset size data
+0x00 0x4 float32, frame index on global timeline
+0x04 0x4 float32, number of frames before the next animation, reciprocated
+0x08 0x4 uint32, index of the appropriate animation (found in .XGM)
+0x0C 0x4 uint32, 0 or 1, force starting the animation from this node's frame
+0x10 0x4 uint32, determines whether to render the model, 0 if true
+0x14 0x4 uint32, animate the model based on the game's current state (only useful with model types 1 - 3 & 5 - 8)
+0x18 0x4 uint32, loop animation
+0x1C 0x4 uint32, untested
+0x20 0x4 uint32, untested
+0x24 0x4 uint32, produce a drop shadow
+0x28 0x4 uint32, unknown, possibly ignored - sometimes matches the next value
+0x2C 0x4 uint32, frame index * 160

ModelScalar

Model scaling in 3D space, rarely used

offset size data
0x00 0x4 float32, frame index on global timeline
0x04 0x4 float32, number of frames before the next scalar, reciprocated
0x08 0x4 float32, X-scalar
0x0C 0x4 float32, Y-scalar
0x00 0x4 float32, Z-scalar
0x04 0x4 uint32, unknown
0x08 0x4 uint32, interpolation between scalars - 1 if true
0x0C 0x4 uint32, unknown

PlayerModelSetup

Sets up a model tied to player or CPU control.

First it reads everything as though it were a NormalModelSetup. Then, if the PlayerModelSetup's modelsetup_header_version >= 0x1300, it also reads the following values:

offset size data
+0x00 0x4 uint32 num_controllables
+0x04 0x30*num_controllables Controllable[num_controllables]
(varies) (varies) Connections[num_controllables]
(varies) 0x4*num_controllable int32[num_controllable], event defaults, Controllable indices

If no connection matches the current state of the chosen player, the default event at the current index will get used. If the default is -1, then nothing changes.

Controllable

Contains controller/event/button flags + analog stick angles

offset size data
0x00 0x4 float32, minimum angle in radians
0x04 0x4 float32, maximum angle in radians
0x08 0x4 uint32, a descriptor of sorts - aligns with strum animations (1 - 3) and guarding (1 - 4)
0x0C 0x4 uint32, event flag - used with bitwise '&' comparisons
0x10 0x4 uint32, index of animation to use
0x14 0x4 uint32, length of time (in frames) to hold the last frame of animation for
0x18 0x4 uint32, 0 or 1, playback direction: 1 - normal; 0 - reverse
0x1C 0x4 uint32, 0 or 1, controls whether the animation can be interrupted mid-playback
0x20 0x4 uint32, unknown
0x24 0x4 uint32, 0 or 1, controls whether to choose a connected event by random
0x28 0x8 [unused] junk for padding

Connections

Provides each respective controllable with a list of events to poll for.

offset size data
0x00 0x4 uint32 num_connections
0x04 0x4*num uint32[num_connections], indices to corresponding Controllables

AtkDefModelSetup

Sets up a model to be used as an attack, damage, or guard effect.

First it reads everything as though it were a NormalModelSetup. Then if the AtkDefModelSetup's modelstup_header_version >= 0x1200, it also reads the following values:


Z-length

float32 Length value along the Z-axis used to scale attack models

offset size data
+0x00 0xC float32[3] XYZ, offset from the starting model
+0x0C 0xC float32[3] XYZ, offset from the target model
+0x18 0x10 char[16], name of model to start from
+0x28 0x10 char[16], name of model set as the target to stretch to
+0x38 0x4 [unusued?] possibly could be space saved for a 32bit pointer to the starting model's 4x4 matrix
+0x3C 0x4 [unusued?] possibly could be space saved for a 32bit pointer to the target model's 4x4 matrix

SnakeModelSetup

Sets up a model to be connected between two points. In practice, it's only used for CHAIN.XG in stage 4.

A SnakeModelSetup has the same file structure as a NormalModelSetup. In addition, the game will use some hardcoded shenanigans to connect one end to the model WOOFA_F.XG and the other end to WOOFA_B.XG.

CameraSetup

Contains camera and lighting information.

offset size data
+0x00 0x4 Magic stamp, always 'GMPX'
+0x04 0x4 uint32 camera_header_version: seen 0x1200. Any other values?
+0x08 0x4 vaguely size-related? Likely ignored[1]
+0x0C 0x8 all 0? Likely ignored[1]
+0x14 0x10 garbage? Likely ignored[1]
+0x24 0x40 BaseGlobalValues
+0x64 0x4 uint32 numPositions
+0x68 0x4 uint32 numRotations
+0x6C 0x20*numPositions CamPosition[numPositions]
(varies) 0x20*numRotations CamRotation[numRotations]
(varies) 0x4 uint32 numProjections
(varies) 0x20*numProjections Projection[numProjections], but only if numProjections >= 2
(varies) 0x4 uint32 numAmbientColors
(varies) 0x20*numAmbientColors AmbientColor[numAmbientColors], but only if numAmbientColors>= 2
(varies) 0x4 uint32 numLightSetups
(varies) (varies) LightSetup[numLightSetups]

Afterwards, the following values are read only if camera_header_version >= 0x1200:

offset size data
(varies) 0x4 uint32 num_unk4
(varies) 0x40*num_unk4 Num40[num_unk4], only read if num_unk4 >= 2

BaseGlobalValues

Contains the base values for ambient & diffuse colors along with the values used to create a projection matrix

offset size data
0x00 0x16 float32[4], RGBA distance fog color - seemingly unused in gameplay (can be seen near the end of a loading screen, at least in 16:9)
0x10 0x12 uint32[3], base RGB material ambient color - each value between 0 and 255
0x1C 0x4 uint32, signals that the following diffuse is used (maybe?) Likely ignored[1]
0x20 0x12 uint32[3], RGB material diffuse color - each value between 0 and 255
0x2C 0x4 float32, field of view
0x30 0x4 float32, aspect ratio
0x34 0x4 float32, ZNear
0x38 0x4 float32, ZFar
0x3C 0x4 uint32, unknown, causes bad rendering with values too far above 1000

CamPosition

Camera position in 3D space

offset size data
0x00 0x4 float32, frame index on global timeline
0x04 0x4 float32, number of frames before the next position value, reciprocated
0x08 0x12 float32[3], XYZ coordinate
0x14 0x4 uint32, interpolation between positions - 1 if true
0x18 0x4 uint32, frame index * 160
0x1C 0x4 uint32, unknown


CamRotation

Camera rotation along the XYZ axes

offset size data
0x00 0x4 float32, frame index on global timeline
0x04 0x4 float32, number of frames before the next position value, reciprocated
0x08 0x10 float32[4], quaternion of rotation (XYZW)
0x18 0x4 uint32, interpolation between rotations - 1 if true
0x1C 0x4 uint32, frame index * 160

Projection

Contains values used to generate a projection matrix

offset size data
0x00 0x4 float32, frame index on global timeline
0x04 0x4 float32, number of frames before the next position value, reciprocated
0x08 0x4 float32, field of view
0x0C 0x4 float32, aspect ratio
0x10 0x4 float32, ZNear
0x14 0x4 float32, ZFar
0x18 0x4 uint32, unknown, causes weird artifacts with values too far above 1000
0x1C 0x4 uint32, interpolation between projections - 1 if true

AmbientColor

Manipulates the ambient color on objects with shading-enabled materials.

offset size data
0x00 0x4 float32, frame index on global timeline
0x04 0x4 float32, number of frames before the next color value, reciprocated
0x08 0x12 float32[3], RGB color values - each value between 0 and 1
0x14 0x4 uint32, interpolation between colors - 1 if true
0x18 0x4 uint32, frame index * 160
0x1C 0x4 uint32, unknown

LightSetup

offset size data
+0x00 0x50 0x50 bytes
+0x50 0x4 Magic stamp, always 'GMLT'
+0x54 0x4 uint32 light_header_version: always 0x1000?
+0x58 0x4 vaguely size-related? Likely ignored[1]
+0x5C 0x8 always 0? Likely ignored[1]
+0x64 0x10 garbage? Likely ignored[1]
+0x74 0x4 num20_gmlt
+0x78 0x4 num30_gmlt
+0x7C 0x20*num20_gmlt Num20_gmlt[num20_gmlt] (only read if num20_gmlt >= 2)
(varies) 0x30*num30_gmlt Num30_gmlt[num30_gmlt] (only read if num30_gmlt >= 2)

SpritesSetup

offset size data
+0x00 0x4 Magic stamp, always 'GMSP'
+0x04 0x4 uint32 spritesetup_header_version: seen 0x1000. Any other values?
+0x08 0xC all 0? Likely ignored[1]
+0x14 0x10 garbage? Likely ignored[1]
+0x24 0x4 uint32 num_fixedsprites
+0x28 0x4 uint32 num_unk1sprites (always 0 in all PS2 US SSQ files)
+0x2C 0x4 uint32 num_unk2sprites (always 0 in all PS2 US SSQ files)
+0x30 0x4 unused, ignored by the game
+0x34 (varies) FixedSpritesSetup, if num_fixedsprites > 0
(varies) (varies) Unk1SpritesSetup, if num_unk1sprites >= 0 (in practice this never happens, at least in PS2 US)
(varies) (varies) Unk2SpritesSetup, if num_unk2sprites >= 0 (in practice this never happens, at least in PS2 US)

FixedSpritesSetup

offset size data
+0x00 0x4 Magic stamp, always 'GMF0'
+0x04 0x4 uint32 fixspritesetup_header_version: seen 0x1000. Any other values?
+0x08 0xC all 0? Likely ignored[1]
+0x14 0x10 garbage? Likely ignored[1]
+0x18 0x4 num_fixedsprites (presumably same as SpritesSetup's num_fixedsprites)
+0x1C 0x50 * num_fixedsprites Num50[num_fixedsprites]
(varies) (varies) FixedSprite[num_fixedsprites]

FixedSprite

offset size data
+0x00 0x4 Magic stamp, always 'GMSP'
+0x04 0x4 uint32 fixedsprite_header_version: seen 0x1000. Any other values?
+0x08 0xC all 0? Likely ignored[1]
+0x14 0x10 garbage? Likely ignored[1]
+0x24 0x40 0x40 bytes
+0x64 0x4 uint32 num_30
+0x68 0x4 uint32 numColors
+0x6C 0x4 uint32 numFrames
+0x70 0x30*num_30 Num30[num_30], only read if num_30 >= 2
(varies) 0x20*numColors ColorMultipliers[numColors], only read if numColors>= 2
(varies) 0x20*numFrames SpriteFrame[numFrames], only read if numFrames >= 2
ColorMultipliers

Handles multiplying a sprite's color values mid-stage. Can be mainly used for fading images in/out (ex: ST08's angels).

offset size data
+0x00 0x4 float32, frame index on global timeline
+0x04 0x4 float32, number of frames before the next multipliers, reciprocated
+0x08 0x10 float32[4], RGBA multipliers
+0x18 0x4 uint32, interpolation between multipliers - 1 if true
+0x1C 0x4 [unused] uint32, frame index * 160
SpriteFrame

Define the bounding boxes to cut into frames of the sprite

offset size data
+0x00 0x4 float32, frame index in the sprite sequence
+0x04 0x4 float32, number of frames before the next spriteFrame, reciprocated
+0x08 0x8 float32[2], Bottom Left XY Pixel Coordinate
+0x10 0x8 float32[2], XY Pixel offset to define the frame bounding box
+0x18 0x4 uint32, interpolation between spriteFrames - 1 if true
+0x1C 0x4 [unused] uint32, frame index * 160

TexAnim

"Animates" a texture by cutting and pasting chosen pieces from and onto said texture. Used mainly for dialogue.

offset size data
+0x00 0x4 Magic stamp, always '\0\0\0\0'?
+0x04 0x4 uint32, texanim_header_version: seen 0x1000. Any other values?
+0x08 0xC all 0?, Likely ignored[1]
+0x14 0x10 garbage?, Likely ignored[1]
+0x24 0x8 uint32[2], XY coordinate paste location (from top left corner)
+0x2C 0x18 0x18 bytes, includes name of texture to animate
+0x44 0x4 uint32, num_cut_outs
+0x48 0x10*num_cut_outs TexCutOut[num_cut_outs]
(varies) 0x4 uint32, num_tex_frames
(varies) 0x10*num_tex_frames TexFrame[num_tex_frames]

TexCutOut

Specifies the section of a texture to cut out.

  • The cut-out region includes the top and left borders (defined by the top-left coordinate), but it stops right before the bottom and right borders.
offset size data
+0x00 0x4 float32, top left corner: X coordinate
+0x04 0x4 float32, top left corner: Y coordinate
+0x08 0x4 float32, bottom right corner: X coordinate
+0x0C 0x4 float32, bottom right corner: Y coordinate

TexFrame

offset size data
+0x00 0x4 float32, frame position on the global timeline
+0x04 0x4 float32, number of frames before the next cutout, reciprocated
+0x08 0x4 uint32, index of the cutout to use
+0x0C 0x4 uint32, unknown but always 0

PSetup

PSTP may stand for "Particle Setup". Non-Japanese PS2 versions of the game mention an unused particle system not far from the code that reads this section, but more investigation is needed.

offset size data
+0x00 0x4 Magic stamp, always 'PSTP'?
+0x04 0x4 uint32 pstp_header_version: seen 0x1000. Any other values?
+0x08 0xC all 0? Likely ignored[1]
+0x14 0x10 garbage? Likely ignored[1]
+0x18 0x4 uint32 num_mystery. Always 0 in the game's SSQ files?
+0x1C (varies) if num_mystery were not 0, the game might read more stuff here.

Remarks

  1. 1.00 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21 Many of these values were tested by loading Stage 1 (US PS2 version) and seeing if the game uses these values after reading them from the file (it didn't, but who knows if other stages do).
    Sections tested this way: GMSX, a few GMPXs including U1 and camera, first GMLT, one of each kind of GMSP, GMF0, first TexAnim, PSTP
  2. Orientation of the axes for rotation may vary from most graphics programs (i.e Blender).