Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
 
(19 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[Gotcha Force | ← Gotcha Force]]
[[Gotcha Force | ← Gotcha Force]]


<div style="text-align: center;">
{{Research | 2| Researches on headers / bodies structures are partially achieved. }}
<div style="color: rgb(241, 196, 15);">Cette section est en cours de rédaction.</div>
<div style="color: rgb(241, 196, 15); text-align: center;">Des recherches sont encore nécessaires et certains paragraphes peuvent être faux.</div>
</div>


== Modèles Gotcha Force ==
== Gotcha Force Models ==


Les modèles Gotcha Force fonctionnent comme ceux du jeu Super Smash Bros Melee (SSBM) investigué par sa [https://smashboards.com/threads/melee-dat-format.292603/ communauté].
Gotcha Force models work as those from the game Super Smash Bros Melee (SSBM) investigated by its [https://smashboards.com/threads/melee-dat-format.292603/ community].


Un modèle est un format de fichier organisant des objets et des ressources sérialisés pour être utilisés par la librairie '''H'''al '''S'''ys'''D'''olphin ('''HSD'''), une librairie utilisée dans plusieurs jeux par Capcom. Ce sont des ressources graphiques structurées de manière hiérarchique. La présence de certaines images dans les modèles montrent à priori l'utilisation de la technique [https://learn.foundry.com/modo/901/content/help/pages/shading_lighting/shader_items/matcap.html matcap].
A model is a file format that organizes objects and resources serialized to be used by the '''H'''al '''S'''ys'''D'''olphin ('''HSD''') library. The HSD library is used in several Capcom games. These are graphic materials structured in a hierarchical way. Some pictures present in the models seem to indicate the use of [https://learn.foundry.com/modo/901/content/help/pages/shading_lighting/shader_items/matcap.html matcap] technic. This library uses Dolphin SDK functions like GX / MTX and so on.
Par ailleurs, la librairie prendrait ses sources sur le SDK Dolphin, tel que GX ou encore MTX.


=== Fichiers concernés ===
=== Affected files ===
L'ensemble des fichiers ayant dans leur titre '''_mdl''' sont des fichiers modèles correspondant au format décrit dans cette page. On notera les fichiers [[ARZ (Gotcha Force)|.arz]] qui sont des modèles compressés. Le fichier collision.arc et les fichiers tdc00.arc à tdc09.arc sont aussi des modèles.
All files in the AFS having '''_mdl''' in their names are models described in this page. We notice also [[ARZ (Gotcha Force)|.arz]] which are compressed models. collision.arc and tdc00.arc to tdc09.arc are also models.


Les fichiers modèles se retrouvent aussi dans les pzz des borgs (plxxxx.pzz) en position 004 à 009.
Model files are also found in the borgs' pzz (plxxxx.pzz) at positions 004 to 009.


=== HSDRaw ===
=== HSDRaw ===
HSDRaw, un éditeur 3D dotnet de ce format est instable sur mon Windows (algoflash). Il est cependant prouvé qu'un edit des _mdl pour commencer à l'offset 0x100 - après le préambule - permet de visualiser le fichier sur HSDRaw et d'avoir le rendu 3D du Borg (click sur le premier dossier JOBJ - puis le JOBJ dedans et double click sur le nœud en violet). Cela devrait aussi permettre d'éditer certaines propriétés ?
HSDRaw, a dotnet 3D editor for this format, is unstable on my Windows (algoflash). However, it has been proven that editing the _mdl starting at offset 0x100 - after the preamble - allows visualizing the file on HSDRaw and obtaining the 3D rendering of the Borg (click on the first JOBJ folder - then the JOBJ inside and double-click on the violet node). This should also allow editing certain properties?


== Structure générale ==
== General Structure ==
Le format des modèles se découpe en plusieurs blocks. Le préambule fait 0x100 octets au tout début du fichier. Il est souvent absent. Toutes les valeurs sont en unsigned big endian, et le pad est en Nulls bytes (\x00). Les offsets trouvés après le début du Data Block (DB) sont relatifs au début du DB. La table de relocs est un tableau d'offsets de 4 octets (relatif au DB) permettant de traduire en adressage absolu les offsets des structures lors du chargement mémoire. La table de reloc permet par exemple de délimiter les structures du fait qu'il est peu probable qu'un offset pointe au milieu d'une structure.
The model format is divided into several blocks. The preamble is 0x100 bytes at the very beginning of the file. It is often absent. All values are in unsigned big endian, and the pad is in Null bytes (\x00). Offsets found after the beginning of the Data Block (DB) are relative to the beginning of the DB. The relocation table is an array of 4-byte offsets (relative to the DB) used to translate the offsets of structures into absolute addressing during memory loading. The relocation table, for example, helps delimit the structures because it is unlikely that an offset points in the middle of a structure.


L'ensemble des fichiers répondant à ce format on un seul root_node de type SObj (Scene data).
All files following this format have a single root_node of type SObj (Scene data).


=== '''Préambule''' : (0x100 octets / 0 octets) ===
=== '''Preamble''': (0x100 bytes / 0 bytes) ===
* 4 octets - hsd_header_offset=0x100 (toujours)
{| class="wikitable"
* 4 octets - bones_flags_table_offset=0x20 (toujours) - offset de la liste des flags des armatures
|-
* 4 octets - bones_table_offset=0xC0 (toujours) - offset de la liste des armatures
! Position !! Size !! Description !! Observations
* 20 octets - Pad - (toujours)
|-
* 4 octets [32] - Inconnu (flags des armatures ?) 1 octet par flag ?
| 0x0 || 4 bytes || HSD Header offset ||
* 32 octets - Pad - (toujours)
|-
* 32 octets - armatures ?
| 0x4 || 4 bytes || Joints relation table offset || Offset of the relationship joints
* 32 octets - Pad - (toujours)
|-
=== '''HSD Header''' - (0x20 octets) ===
| 0x8 || 4 bytes || Joints array position || Position of the joint in the array
* 4 octets - Taille totale du fichier
|-
* 4 octets - Taille du Data block
| 0xC || 20 bytes || Pad ||
* 4 octets - Nombre d'entrée dans la Table de relocs
|-
* 4 octets - root0_count
| 0x20 || 4 bytes [32] || Joints relation table ||
* 4 octets - root1_count
|-
* 12 octets - Pad - (toujours)
| 0x70 || 32 bytes || Pad ||
=== '''Data block''' : ===
|-
* JOBJ, etc. -> Ces structures sont détaillée plus loin ci-dessous.
| 0xC0 || 32 bytes || Joints array position ||
=== '''Relocation Table''' : ===
|-
* Tableau d'offsets de 4 octets - Offsets des structures dans le DB.
| 0xE0 || 32 bytes || Pad ||
=== '''Root Nodes (2)''' : ===
|}
* Tableau de taille 8 * root0_count
** 4 octets - root_offset - relatif au DB
** 4 octets - string_table_offset - relatif à la StringTable
* Tableau de taille 8 * root1_count
** 4 octets - root_offset - relatif au DB
** 4 octets - string_table_offset - relatif à la StringTable
=== '''String Table''' : ===
* Suite de strings terminées par Null au nombre de root0_count + root1_count


== Structures rencontrées dans le DB ==
=== '''HSD Header''' - (0x20 bytes) ===
Note : l'arborescence est cumulative sur les transformations pour les relations parents->enfants
* 4 bytes - Total file size
* 4 bytes - Data block size
* 4 bytes - Number of entries in the Relocation Table
* 4 bytes - root0_count
* 4 bytes - root1_count
* 12 bytes - Pad - (always)
=== '''Data block''': ===
* JOBJ, etc. -> These structures are detailed below.
=== '''Relocation Table''': ===
* Array of 4-byte offsets - Offsets of structures in the DB.
=== '''Root Nodes (2)''': ===
* Array of size 8 * root0_count
** 4 bytes - root_offset - relative to DB
** 4 bytes - string_table_offset - relative to StringTable
* Array of size 8 * root1_count
** 4 bytes - root_offset - relative to DB
** 4 bytes - string_table_offset - relative to StringTable
=== '''String Table''': ===
* Series of strings terminated by Null, the number of root0_count + root1_count


Les Noeuds Racine qui ont pour nom "scene_data" pointent sur un SObj :
== Structures encountered in the DB ==
=== '''SObj''' : (0x10 octets) ===
Note: The hierarchy is cumulative on transformations for parent->child relationships
* 4 octets - JObjDescs_offsets_list_offset
* 4 octets - Cameras_list_offset
* 4 octets - Lights_list_offset
* 4 octets - Fog


"scene_data" == nom du nœud racine
Root Nodes with the name "scene_data" point to an SObj:
JObjDescs_offsets_list_offset, cameras.. pointent sur une liste d'offsets terminée par 4 octets à 0x00.
=== '''SObj''': (0x10 bytes) ===
lights_list_offset pointe sur des couples (4 octets - LObj_offset ; 4 octets - light_anim_pointer_offset)
* 4 bytes - JObjDescs_offsets_list_offset
* 4 bytes - Cameras_list_offset
* 4 bytes - Lights_list_offset
* 4 bytes - Fog


=== '''JObjDesc''' : (0x10 octets) ===
"scene_data" == name of the root node
* 4 octets - root_joint_offset - JObj
JObjDescs_offsets_list_offset, cameras... point to a list of offsets terminated by 4 bytes at 0x00.
* 4 octets - joint_animations_offset - ?
lights_list_offset points to pairs (4 bytes - LObj_offset; 4 bytes - light_anim_pointer_offset)
* 4 octets - material_animations_offset - ?
* 4 octets - shape_animations_offset - ?


=== '''CObj''' : (0x38 octets) ===
=== '''JObjDesc''': (0x10 bytes) ===
* 4 octets - flags
* 4 bytes - root_joint_offset - JObj
* 4 octets - projection_type - ProjectionTypeEnum
* 4 bytes - joint_animations_offset - ?
* 2 octets - viewport_left
* 4 bytes - material_animations_offset - ?
* 2 octets - viewport_right
* 4 bytes - shape_animations_offset - ?
* 2 octets - viewport_top
 
* 2 octets - viewport_bottom
=== '''CObj''': (0x38 bytes) ===
* 4 octets - proj_width
* 4 bytes - flags
* 4 octets - proj_height
* 4 bytes - projection_type - ProjectionTypeEnum
* 4 octets - eye_offset - WObj
* 2 bytes - viewport_left
* 4 octets - target_offset - WObj
* 2 bytes - viewport_right
* 4 octets - roll
* 2 bytes - viewport_top
* 4 octets - Inconnu
* 2 bytes - viewport_bottom
* 4 octets - float - near_clip
* 4 bytes - proj_width
* 4 octets - float - far_clip
* 4 bytes - proj_height
* 4 octets - float - field_of_view
* 4 bytes - eye_offset - WObj
* 4 octets - float - aspect
* 4 bytes - target_offset - WObj
Camera object. Note : pour frustrum ou ortho, la structure est différente.
* 4 bytes - roll
* 4 bytes - up - Vec3
* 4 bytes - float - near_clip
* 4 bytes - float - far_clip
* 4 bytes - float - field_of_view
* 4 bytes - float - aspect
Camera object. Note: for frustrum or ortho, the structure is different.


* '''ProjectionTypeEnum''':
* '''ProjectionTypeEnum''':
Line 100: Line 109:
** ORTHO = 3
** ORTHO = 3


=== '''WObj''': (0x14 octets) ===
=== '''WObj''': (0x14 bytes) ===
* 4 octets - Inconnu
* 4 bytes - Unknown
* 4 octets - float - v1
* 4 bytes - float - v1
* 4 octets - float - v2
* 4 bytes - float - v2
* 4 octets - float - v3
* 4 bytes - float - v3
* 4 octets - Inconnu
* 4 bytes - Unknown


eye / target
eye / target


=== '''LObj''' : (0x1c octets) ===
=== '''LObj''': (0x1c bytes) ===
* 4 octets - class_name
* 4 bytes - class_name
* 4 octets - next_offset
* 4 bytes - next_offset
* 2 octets - flags - LObjFlagsEnum
* 2 bytes - flags - LObjFlagsEnum
* 2 octets - attenuation_flags - LObjAttenuationFlagsEnum
* 2 bytes - attenuation_flags - LObjAttenuationFlagsEnum
* 1 octet - color_r
* 1 byte - color_r
* 1 octet - color_g
* 1 byte - color_g
* 1 octet - color_b
* 1 byte - color_b
* 1 octet - color_alpha
* 1 byte - color_alpha
* 4 octets - lobj_point_offset - position
* 4 bytes - lobj_point_offset - position
* 4 octets - infinite_data
* 4 bytes - infinite_data
* 4 octets - point_spot_data
* 4 bytes - point_spot_data
light
light


* '''LObjFlagsEnum''' :
'''LObjFlagsEnum''' :
** LOBJ_AMBIANT = 00 00
** LOBJ_AMBIANT = 00 00
** LOBJ_INFINITE = 00 01
** LOBJ_INFINITE = 00 01
Line 136: Line 145:
** LOBJ_SPEC_DIRTY = 01 00
** LOBJ_SPEC_DIRTY = 01 00


* '''LObjAttenuationFlagsEnum''' :
'''LObjAttenuationFlagsEnum''' :
** LOBJ_LIGHT_ATTN_NONE = 00 00
** LOBJ_LIGHT_ATTN_NONE = 00 00
** LOBJ_LIGHT_ATTN = 00 01
** LOBJ_LIGHT_ATTN = 00 01


=== '''LObjPoint''' : (0x14 octets) ===
=== '''LObjPoint''' : (0x14 bytes) ===
* 4 octets - class_name
4 bytes - class_name
* 4 octets - float - x
4 bytes - float - x
* 4 octets - float - y
4 bytes - float - y
* 4 octets - float - z
4 bytes - float - z
* 4 octets - Inconnu
4 bytes - Unknown
 
=== '''LightAnimPointer''' : (0x10 bytes) ===
=== '''LightAnimPointer''' : (0x10 octets) ===
** 4 bytes - next_offset - (LightAnimPointer)
** 4 octets - next_offset - (LightAnimPointer)
** 4 bytes - light_anim - ?
** 4 octets - light_anim - ?
** 4 bytes - position_anim - ?
** 4 octets - position_anim - ?
** 4 bytes - interst_anim - ?
** 4 octets - interst_anim - ?
Bugs in HSDRaw - to be tested
Bugs dans HSDRaw - à tester
 
=== '''JObj''' : (0x40 octets) ===
* 4 octets - Inconnu
* 4 octets - flags
* 4 octets - child_offset (JObj)
* 4 octets - next_offset (JObj)
* 4 octets - dobj_offset (DObj)
* 4 octets [3] - float3 - rotation_xyz
* 4 octets [3] - float3 - scale_xyz
* 4 octets [3] - float3 - translation_xyz
* 4 octets - inverse_world_transform_offset (inverse world transform = Matrice de 4x3)
* 4 octets - robj_offset


Pointé par les listes dans Root Node scene_data.
=== '''JObj''' : (0x40 bytes) ===
4 bytes - Unknown
4 bytes - flags
4 bytes - child_offset (JObj)
4 bytes - next_offset (JObj)
4 bytes - dobj_offset (DObj)
4 bytes [3] - float3 - rotation_xyz
4 bytes [3] - float3 - scale_xyz
4 bytes [3] - float3 - translation_xyz
4 bytes - inverse_world_transform_offset (inverse world transform = 4x3 matrix)
4 bytes - robj_offset
Pointed by the lists in Root Node scene_data.


* '''JObjFlagsEnum''' : (peuvent se cumuler)
'''JObjFlagsEnum''' : (can be cumulative)
** NULL = 00 00 00 00
** NULL = 00 00 00 00
** SKELETON = 00 00 00 01
** SKELETON = 00 00 00 01
Line 203: Line 210:
** ROOT_TEXEDGE = 40 00 00 00
** ROOT_TEXEDGE = 40 00 00 00


=== '''InverseWorldTransform''' : (0x30 octets) ===
=== '''InverseWorldTransform''' : (0x30 bytes) ===
* 4 octets - float - M11
4 bytes - float - M11
* 4 octets - float - M12
4 bytes - float - M12
* 4 octets - float - M13
4 bytes - float - M13
* 4 octets - float - M14
4 bytes - float - M14
* 4 octets - float - M21
4 bytes - float - M21
* 4 octets - float - M22
4 bytes - float - M22
* 4 octets - float - M23
4 bytes - float - M23
* 4 octets - float - M24
4 bytes - float - M24
* 4 octets - float - M31
4 bytes - float - M31
* 4 octets - float - M32
4 bytes - float - M32
* 4 octets - float - M33
4 bytes - float - M33
* 4 octets - float - M34
4 bytes - float - M34


=== '''DObj''' : (0x10 octets) ===
=== '''DObj''' : (0x10 bytes) ===
* 4 octets - Inconnu
4 bytes - Unknown
* 4 octets - next_offset - prochain DOBJ
4 bytes - next_offset - next DOBJ
* 4 octets - mobj_offset - material offset
4 bytes - mobj_offset - material offset
* 4 octets - pobj_offset - mesh offset
4 bytes - pobj_offset - mesh offset
Liste chaînée qui permet de récupérer l'ensemble des materials & mesh pour le JObj auquel il est lié.
Linked list that allows retrieving all materials & meshes for the associated JObj.


=== '''MObj''' : (0x18 bytes) ===
4 bytes - Unknown
4 bytes - render_flags - RenderFlagsEnum
4 bytes - tobj_offset - texture offset - may be invalid if there is no texture for the material
4 bytes - material_offset - material colors?
8 bytes - PEDesc?
Contains textures & information about material colors.


=== '''MObj''' : (0x18 octets) ===
'''RenderFlagsEnum''' : (cumulative)
* 4 octets - Inconnu
* 4 octets - render_flags - RenderFlagsEnum
* 4 octets - tobj_offset - offset de texture - peut être invalide s'il n'y a pas de texture pour le material
* 4 octets - material_offset - couleurs des materials ?
* 8 octets - PEDesc ?
 
Contient les textures & informations sur les couleurs des Materials.
 
* '''RenderFlagsEnum''' : (se cumulent)
** USER = 80 00 00 00
** USER = 80 00 00 00
** CONSTANT = 00 00 00 01
** CONSTANT = 00 00 00 01
Line 262: Line 267:


=== '''TObj''' : (0x5c octets) ===
=== '''TObj''' : (0x5c octets) ===
* 4 octets - ?
* 4 bytes - ?
* 4 octets - ?
* 4 bytes - ?
* 4 octets - tex_map_id - TexMapIdEnum
* 4 bytes - tex_map_id - TexMapIdEnum
* 4 octets - gx_tex_gen_src - GXTexGenSrcEnum
* 4 bytes - gx_tex_gen_src - GXTexGenSrcEnum
* 4 octets - float - rx
* 4 bytes - float - rx
* 4 octets - float - ry
* 4 bytes - float - ry
* 4 octets - float - rz
* 4 bytes - float - rz
* 4 octets - float - sx
* 4 bytes - float - sx
* 4 octets - float - sy
* 4 bytes - float - sy
* 4 octets - float - sz
* 4 bytes - float - sz
* 4 octets - float - tx
* 4 bytes - float - tx
* 4 octets - float - ty
* 4 bytes - float - ty
* 4 octets - float - tz
* 4 bytes - float - tz
* 4 octets - wrap_s - WrapEnum
* 4 bytes - wrap_s - WrapEnum
* 4 octets - wrap_t - WrapEnum
* 4 bytes - wrap_t - WrapEnum
* 1 octet - w_scale
* 1 byte- w_scale
* 1 octet - h_scale
* 1 byte- h_scale
* 2 octets - ?
* 2 bytes - ?
* 1 octets - bump_map - (False = 00 ; True = 01)
1 byte - bump_map - (False = 00 ; True = 01)
* 4 bits - alpha_operation - AlphaOperationEnum
4 bits - alpha_operation - AlphaOperationEnum
* 4 bits - color_operation - ColorOperationEnum
4 bits - color_operation - ColorOperationEnum
* 1 octet - shadow_lightmap - (False = 00 ; True = 01) (2 octets avec une Enum lightmap limite)
1 byte - shadow_lightmap - (False = 00 ; True = 01) (2 bytes with a lightmap limit Enum)
* 1 bit - ext_lightmap - (False = 0 ; True = 1)
1 bit - ext_lightmap - (False = 0 ; True = 1)
* 1 bit - ambiant_lightmap - (False = 0 ; True = 1)  
1 bit - ambient_lightmap - (False = 0 ; True = 1)
* 1 bit - specular_lightmap - (False = 0 ; True = 1)
1 bit - specular_lightmap - (False = 0 ; True = 1)
* 1 bit - diffuse_lightmap (False = 0 ; True = 1)
1 bit - diffuse_lightmap - (False = 0 ; True = 1)
* 4 bits - coord_type - CoordTypeEnum
4 bits - coord_type - CoordTypeEnum
* 4 octets - float - blending - utilisé quand color_operation ou alpha_operation == BLEND
4 bytes - float - blending - used when color_operation or alpha_operation == BLEND
* 4 octets - mag_filter - MagFilterEnum
4 bytes - mag_filter - MagFilterEnum
* 4 octets - ?
* 4 bytes - ?
* 4 octets - ?
* 4 bytes - ?
* 4 octets - ?
* 4 bytes - ?
* 4 octets - ?
* 4 bytes - ?
Informations de Textures. Le TObj contient des informations sur les paramètres d'environnement de textures utilisés pour le rendu graphique ainsi que les offset de l'image et des données de la palette utilisés pour cette texture. Le plus important ici, c'est l'offset d'image et la palette/tlut - si l'image n'est pas indexée (RGBA, CMPR, etc.) alors la structure de description palette/tlut n'est pas utilisée.
Texture Information: The TObj contains information about texture environment parameters used for graphic rendering, as well as the offsets of the image and palette data used for this texture. The most important aspects here are the image offset and the palette/TLUT (Texture Look-Up Table) - if the image is not indexed (RGBA, CMPR, etc.), then the palette/TLUT description structure is not used.


* '''TexMapIdEnum''' :
* '''TexMapIdEnum''' :
Line 376: Line 381:


=== '''Material''' : (0x14 octets) ===
=== '''Material''' : (0x14 octets) ===
* 1 octets - AMB_R - (ambient)
* 1 byte - AMB_R - (ambient)
* 1 octets - AMB_G
* 1 byte - AMB_G
* 1 octets - AMB_B
* 1 byte - AMB_B
* 1 octets - AMB_A
* 1 byte - AMB_A
* 1 octets - DIF_R - (diffuse)
* 1 byte - DIF_R - (diffuse)
* 1 octets - DIF_G
* 1 byte - DIF_G
* 1 octets - DIF_B
* 1 byte - DIF_B
* 1 octets - DIF_A
* 1 byte - DIF_A
* 1 octets - SPC_R - (specular)
* 1 byte - SPC_R - (specular)
* 1 octets - SPC_G
* 1 byte - SPC_G
* 1 octets - SPC_B
* 1 byte - SPC_B
* 1 octets - SPC_A
* 1 byte - SPC_A
* 4 octets - float - alpha
* 4 bytes - float - alpha
* 4 octets - float - shininess
* 4 bytes - float - shininess


=== '''PObj''' : (0x18 octets) ===
=== '''PObj''' : (0x18 octets) ===
* 4 octets - Inconnu
* 4 bytes - Inconnu
* 4 octets - next_offset - pobj
* 4 bytes - next_offset - pobj
* 4 octets - vertex_attr_list_offset
* 4 bytes - vertex_attr_list_offset
* 2 octets - Flags - PObjFlagsEnum
* 2 bytes  - Flags - PObjFlagsEnum
* 2 octets - display_list_size - number of 0x20 (32) byte blocks occupied by display list data
* 2 bytes - display_list_size - number of 0x20 (32) byte blocks occupied by display list data
* 4 octets - display_list_offset
* 4 bytes - display_list_offset
* 4 octets - weight_list_offset - ? verifier qu'on retrouve bien le tableau d'envelope_weights à cet offset
*4 bytes - weight_list_offset - ? Verify that the envelope_weights array is indeed found at this offset.


Comme l'indique next_offset, il s'agit d'une liste de meshs à afficher pour un material donné référencé par un dobj. PObj contient les offsets de vertex attributes / display list / joint weight list ce qui suffit et permet d’interpréter et traiter les coordonnées de vertices, normals & textures.
As indicated by next_offset, it is a list of meshes to be displayed for a given material referenced by a dobj. PObj contains the offsets of vertex attributes / display list / joint weight list, which is sufficient and allows interpreting and processing vertex, normal, and texture coordinates.


Les attributs vertex sont les plus important - les parametres specifiés contrôlent tout : du format, de la taille des données de chaque vertex, normal et coordonnées de textures et comment ces valeurs sont dimensionnées (scaled) par rapport à la présence et la taille de chaque valeur d'index qui apparaît dans la display list information.
Vertex attributes are the most important - the specified parameters control everything: from the format to the size of the data for each vertex, normal, and texture coordinates, and how these values are dimensioned (scaled) based on the presence and size of each index value appearing in the display list information.


* '''PObjFlagsEnum''' :
* '''PObjFlagsEnum''' :
** Inconnu0 = 00 01
Unknown0 = 00 01
** Inconnu1 = 00 02
Unknown1 = 00 02
** ANIM = 00 08
** ANIM = 00 08
** SHAPE_ANIM = 10 00
** SHAPE_ANIM = 10 00
Line 414: Line 419:


=== EnvelopeWeights : (0x? octets) ===
=== EnvelopeWeights : (0x? octets) ===
* 4 octets - envelope_count
* 4 bytes - envelope_count
* [envelope_count]:
* [envelope_count]:
** 4 octets - float - weight
** 4 bytes - float - weight
** 4 octets - pad ?
** 4 bytes - pad ?
* 4 octets - jobj_list_offset
* 4 bytes - jobj_list_offset


=== not verified yet ===
=== not verified yet ===
Line 425: Line 430:


* '''IMAGE_HEADER''' :
* '''IMAGE_HEADER''' :
** 4 octets - image_offset - image data
** 4 bytes - image_offset - image data
** 2 octets - width
** 2 bytes - width
** 2 octets - height
** 2 bytes - height
** 4 octets - image_format
** 4 bytes - image_format


* '''PALETTE_HEADER''' : (0x10)
'''PALETTE_HEADER''' : (0x10 bytes)
** 4 octets - palette_offset - palette data
** 4 bytes - palette_offset - palette data
** 4 octets - palette_format
** 4 bytes - palette_format
** 4 octets - Inconnu
** 4 bytes - Unknown
** 2 octets - color_count
** 2 bytes - color_count
** 2 octets - Inconnu
** 2 bytes - Unknown
The image_offset and palette_offset are often shared by several textures. Knowing this allows you to find all the information about the textures' image data (width, height, format), as well as the format and the number of colors in the palette/TLUT.


image_offset et palette_offset sont souvent partagés par plusieurs textures - savoir ça permet de retrouver toutes les informations sur les images des textures (largeur, hauteur, format), ainsi que le format et le nombre de couleurs de la palette/tlut.
The image format does not determine the total number of colors in the palette it uses. For example, an 8-bit indexed image would have a maximum of 256 colors, but only 136 or 221 colors may be currently used. In this way, the palette will not use the total size it should use.


Le format d'image ne détermine pas le nombre total de couleurs de la palette qu'elle utilisent. Par exemple, une image indexée sur 8 bits aurait un maximum de 256 couleurs mais seulement 136 ou 221 couleurs sont actuellement utilisées. De la sorte, la palette n'utilisera pas la taille totale qu'elle devrait utiliser.
Images follow the structure generally used by the GameCube:
 
Les images suivent la structure généralement utilisée par la GameCube :


IMAGE FORMATS :
IMAGE FORMATS :
Line 456: Line 460:
* case 0xe: //s3tc1
* case 0xe: //s3tc1


Les formats indexés utilisent aussi les informations de palettes/tlut et les données peuvent apparaître en plusieurs formats :
The indexed formats also use palette/TLUT information, and the data can appear in various formats:


PALETTE FORMATS :
PALETTE FORMATS :
Line 465: Line 469:
---> "Joint Data - Accessing Geometry, Mesh, and Vertex Attributes" https://smashboards.com/threads/melee-dat-format.292603/
---> "Joint Data - Accessing Geometry, Mesh, and Vertex Attributes" https://smashboards.com/threads/melee-dat-format.292603/


 
// Declaration of a vertex and attribute information
trad a revoir à partir de là, il faut investiguer le rendu 3D sur GameCube pour mieux comprendre
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// déclaration d'un vertex et attribute information
// attr, type, cnt, data_type, flags?, file_offset
// attr, type, cnt, data_type, flags?, file_offset
* ATTR_DATA
* ATTR_DATA
** 4 octets - GXAttr    vtx_attr_offset - attr
** 4 bytes - GXAttr    vtx_attr_offset - attr
** 4 octets - GXAttrType vtx_attr_type  - index_type
** 4 bytes - GXAttrType vtx_attr_type  - index_type
** 4 octets - GXCompCnt  comp_cnt        - cnt
** 4 bytes - GXCompCnt  comp_cnt        - cnt
** 4 octets - GXCompType comp_type      - data_type
** 4 bytes - GXCompType comp_type      - data_type
** 1 octets - scale
** 1 bytes - scale
** 1 octets - Inconnu
** 1 bytes - unknown
** 2 octets - vtx_stride
** 2 bytes - vtx_stride
** 2 octets - data_offset
** 2 bytes - data_offset


vertex_attr_offset pointe sur une liste d'attributs de vertex. Leur nombre n'est pas donné. Les données dans cette structure suivent les informations et les types conçus par l'architecture GameCube/WII et son API. La liste est terminée par une valeur spécifique de vtx_attr qui signale la fin de cette liste. Avec un accès à la doku SDK, il serait fortement conseillé de lire la section à propos des "vertex attributes and other specifications".
vertex_attr_offset points to a list of vertex attributes. The number of these attributes is not provided. The data in this structure follows the information and types designed by the GameCube/WII architecture and its API. The list is terminated by a specific value of vtx_attr signaling the end of this list. With access to the SDK documentation, it is strongly recommended to read the section about "vertex attributes and other specifications."


La valeur de vtx_attr determine le type de donnée que cet attribut désigne et peut indiquer un nombre de types natifs utilisés utilisés pour passer les données entre les interfaces logicielles et matérielles.
The value of vtx_attr determines the type of data that this attribute represents and can indicate a number of native types used for passing data between software and hardware interfaces.


Les valeures possibles sont les suivantes :
The possible values are as follows:
* enum GXAttr (4 octets)
enum GXAttr (4 bytes)
** GX_VA_PNMTXIDX = 0,   // position/normal matrix index
** GX_VA_PNMTXIDX = 0, // position/normal matrix index
** GX_VA_TEX0MTXIDX,     // texture 0 matrix index
** GX_VA_TEX0MTXIDX, // texture 0 matrix index
** GX_VA_TEX1MTXIDX,     // texture 1 matrix index
** GX_VA_TEX1MTXIDX, // texture 1 matrix index
** GX_VA_TEX2MTXIDX,     // texture 2 matrix index
** GX_VA_TEX2MTXIDX, // texture 2 matrix index
** GX_VA_TEX3MTXIDX,     // texture 3 matrix index
** GX_VA_TEX3MTXIDX, // texture 3 matrix index
** GX_VA_TEX4MTXIDX,     // texture 4 matrix index
** GX_VA_TEX4MTXIDX, // texture 4 matrix index
** GX_VA_TEX5MTXIDX,     // texture 5 matrix index
** GX_VA_TEX5MTXIDX, // texture 5 matrix index
** GX_VA_TEX6MTXIDX,     // texture 6 matrix index
** GX_VA_TEX6MTXIDX, // texture 6 matrix index
** GX_VA_TEX7MTXIDX,     // texture 7 matrix index
** GX_VA_TEX7MTXIDX, // texture 7 matrix index
** GX_VA_POS     = 9,   // position
** GX_VA_POS = 9, // position
** GX_VA_NRM,             // normal
** GX_VA_NRM, // normal
** GX_VA_CLR0,           // color 0
** GX_VA_CLR0, // color 0
** GX_VA_CLR1,           // color 1
** GX_VA_CLR1, // color 1
** GX_VA_TEX0,           // input texture coordinate 0
** GX_VA_TEX0, // input texture coordinate 0
** GX_VA_TEX1,           // input texture coordinate 1
** GX_VA_TEX1, // input texture coordinate 1
** GX_VA_TEX2,           // input texture coordinate 2
** GX_VA_TEX2, // input texture coordinate 2
** GX_VA_TEX3,           // input texture coordinate 3
** GX_VA_TEX3, // input texture coordinate 3
** GX_VA_TEX4,           // input texture coordinate 4
** GX_VA_TEX4, // input texture coordinate 4
** GX_VA_TEX5,           // input texture coordinate 5
** GX_VA_TEX5, // input texture coordinate 5
** GX_VA_TEX6,           // input texture coordinate 6
** GX_VA_TEX6, // input texture coordinate 6
** GX_VA_TEX7,           // input texture coordinate 7
** GX_VA_TEX7, // input texture coordinate 7


** GX_POS_MTX_ARRAY,     // position matrix array pointer
** GX_POS_MTX_ARRAY, // position matrix array pointer
** GX_NRM_MTX_ARRAY,     // normal matrix array pointer
** GX_NRM_MTX_ARRAY, // normal matrix array pointer
** GX_TEX_MTX_ARRAY,     // texture matrix array pointer
** GX_TEX_MTX_ARRAY, // texture matrix array pointer
** GX_LIGHT_ARRAY,       // light parameter array pointer
** GX_LIGHT_ARRAY, // light parameter array pointer
** GX_VA_NBT,             // normal, bi-normal, tangent  
** GX_VA_NBT, // normal, bi-normal, tangent
** GX_VA_MAX_ATTR,       // maximum number of vertex attributes
** GX_VA_MAX_ATTR, // maximum number of vertex attributes


** GX_VA_NULL     = 0xff // NULL attribute (to mark end of lists)
** GX_VA_NULL = 0xff // NULL attribute (to mark the end of lists)


Toutes les données nécessaires pour représenter un mesh peuvent être spécifiées et indexées d'une manière ou d'une autre. De même, GX_VA_TEX0MTXIDX, GX_VA_CLR0, et autres sont aussi possibles - les valeurs les plus fréquentes dans les données SSBM sont : GX_VA_PNMTXIDX, GX_VA_POS, GX_VA_NRM, et GX_VA_TEX0. Which is to be expected as joint matrices, vertex positions/normals, and texture coordinates respectively are probably the most basic of elements needed to display a texture mesh, whether static or animated.
All the necessary data to represent a mesh can be specified and indexed in one way or another. Similarly, GX_VA_TEX0MTXIDX, GX_VA_CLR0, and others are also possible - the most frequent values in the SSBM data are: GX_VA_PNMTXIDX, GX_VA_POS, GX_VA_NRM, and GX_VA_TEX0. This is to be expected as joint matrices, vertex positions/normals, and texture coordinates respectively are probably the most basic elements needed to display a textured mesh, whether static or animated.


When the value of vtx_attr == GX_VA_NULL (0xFF), the end of the vertex attribute array has been reached.
When the value of vtx_attr == GX_VA_NULL (0xFF), the end of the vertex attribute array has been reached.
Line 540: Line 525:
The vtx_attr_type values is actually associated with how the value is indexed, and can thus also determine the size of the index value within the display list data.
The vtx_attr_type values is actually associated with how the value is indexed, and can thus also determine the size of the index value within the display list data.


* 4 octets - enum GXAttrType
* 4 bytes - enum GXAttrType
** GX_NONE    = 0,
** GX_NONE    = 0,
** GX_DIRECT,
** GX_DIRECT,
Line 546: Line 531:
** GX_INDEX16
** GX_INDEX16


 
* Structures COLL_DATA : (collision data)
 
** 4 bytes - vertex_offset (2 floats per entry corresponding to probably 2D data)
 
** 4 bytes - vertex_count
* Structures COLL_DATA : (données de collisions)
** 4 bytes - index_offset
** 4 octets - vertex_offset (2 float par entrée correspondant à des données 2D probablement)
** 4 bytes - index_count
** 4 octets - vertex_count
** 4 bytes [5] - Unknown
** 4 octets - index_offset
*** 2 bytes - index_start
** 4 octets - index_count
*** 2 bytes - index_count
** 4 octets [5] - tableau inconnu
** 4 bytes - Unknown
*** 2 octets - index_start
** 4 bytes - Unknown
*** 2 octets - index_count
** 4 octets - Inconnu
** 4 octets - Inconnu


[[Category:Implementations]]
[[Category:Implementations]]
[[Category:Gotcha Force]]
[[Category:Gotcha Force]]

Latest revision as of 10:01, 23 April 2024

← Gotcha Force


This file format needs more research.
Researches on headers / bodies structures are partially achieved.


Gotcha Force Models

Gotcha Force models work as those from the game Super Smash Bros Melee (SSBM) investigated by its community.

A model is a file format that organizes objects and resources serialized to be used by the Hal SysDolphin (HSD) library. The HSD library is used in several Capcom games. These are graphic materials structured in a hierarchical way. Some pictures present in the models seem to indicate the use of matcap technic. This library uses Dolphin SDK functions like GX / MTX and so on.

Affected files

All files in the AFS having _mdl in their names are models described in this page. We notice also .arz which are compressed models. collision.arc and tdc00.arc to tdc09.arc are also models.

Model files are also found in the borgs' pzz (plxxxx.pzz) at positions 004 to 009.

HSDRaw

HSDRaw, a dotnet 3D editor for this format, is unstable on my Windows (algoflash). However, it has been proven that editing the _mdl starting at offset 0x100 - after the preamble - allows visualizing the file on HSDRaw and obtaining the 3D rendering of the Borg (click on the first JOBJ folder - then the JOBJ inside and double-click on the violet node). This should also allow editing certain properties?

General Structure

The model format is divided into several blocks. The preamble is 0x100 bytes at the very beginning of the file. It is often absent. All values are in unsigned big endian, and the pad is in Null bytes (\x00). Offsets found after the beginning of the Data Block (DB) are relative to the beginning of the DB. The relocation table is an array of 4-byte offsets (relative to the DB) used to translate the offsets of structures into absolute addressing during memory loading. The relocation table, for example, helps delimit the structures because it is unlikely that an offset points in the middle of a structure.

All files following this format have a single root_node of type SObj (Scene data).

Preamble: (0x100 bytes / 0 bytes)

Position Size Description Observations
0x0 4 bytes HSD Header offset
0x4 4 bytes Joints relation table offset Offset of the relationship joints
0x8 4 bytes Joints array position Position of the joint in the array
0xC 20 bytes Pad
0x20 4 bytes [32] Joints relation table
0x70 32 bytes Pad
0xC0 32 bytes Joints array position
0xE0 32 bytes Pad

HSD Header - (0x20 bytes)

  • 4 bytes - Total file size
  • 4 bytes - Data block size
  • 4 bytes - Number of entries in the Relocation Table
  • 4 bytes - root0_count
  • 4 bytes - root1_count
  • 12 bytes - Pad - (always)

Data block:

  • JOBJ, etc. -> These structures are detailed below.

Relocation Table:

  • Array of 4-byte offsets - Offsets of structures in the DB.

Root Nodes (2):

  • Array of size 8 * root0_count
    • 4 bytes - root_offset - relative to DB
    • 4 bytes - string_table_offset - relative to StringTable
  • Array of size 8 * root1_count
    • 4 bytes - root_offset - relative to DB
    • 4 bytes - string_table_offset - relative to StringTable

String Table:

  • Series of strings terminated by Null, the number of root0_count + root1_count

Structures encountered in the DB

Note: The hierarchy is cumulative on transformations for parent->child relationships

Root Nodes with the name "scene_data" point to an SObj:

SObj: (0x10 bytes)

  • 4 bytes - JObjDescs_offsets_list_offset
  • 4 bytes - Cameras_list_offset
  • 4 bytes - Lights_list_offset
  • 4 bytes - Fog

"scene_data" == name of the root node JObjDescs_offsets_list_offset, cameras... point to a list of offsets terminated by 4 bytes at 0x00. lights_list_offset points to pairs (4 bytes - LObj_offset; 4 bytes - light_anim_pointer_offset)

JObjDesc: (0x10 bytes)

  • 4 bytes - root_joint_offset - JObj
  • 4 bytes - joint_animations_offset - ?
  • 4 bytes - material_animations_offset - ?
  • 4 bytes - shape_animations_offset - ?

CObj: (0x38 bytes)

  • 4 bytes - flags
  • 4 bytes - projection_type - ProjectionTypeEnum
  • 2 bytes - viewport_left
  • 2 bytes - viewport_right
  • 2 bytes - viewport_top
  • 2 bytes - viewport_bottom
  • 4 bytes - proj_width
  • 4 bytes - proj_height
  • 4 bytes - eye_offset - WObj
  • 4 bytes - target_offset - WObj
  • 4 bytes - roll
  • 4 bytes - up - Vec3
  • 4 bytes - float - near_clip
  • 4 bytes - float - far_clip
  • 4 bytes - float - field_of_view
  • 4 bytes - float - aspect

Camera object. Note: for frustrum or ortho, the structure is different.

  • ProjectionTypeEnum:
    • PERSPECTIVE = 1
    • FRUSTRUM = 2
    • ORTHO = 3

WObj: (0x14 bytes)

  • 4 bytes - Unknown
  • 4 bytes - float - v1
  • 4 bytes - float - v2
  • 4 bytes - float - v3
  • 4 bytes - Unknown

eye / target

LObj: (0x1c bytes)

  • 4 bytes - class_name
  • 4 bytes - next_offset
  • 2 bytes - flags - LObjFlagsEnum
  • 2 bytes - attenuation_flags - LObjAttenuationFlagsEnum
  • 1 byte - color_r
  • 1 byte - color_g
  • 1 byte - color_b
  • 1 byte - color_alpha
  • 4 bytes - lobj_point_offset - position
  • 4 bytes - infinite_data
  • 4 bytes - point_spot_data

light

LObjFlagsEnum :

    • LOBJ_AMBIANT = 00 00
    • LOBJ_INFINITE = 00 01
    • LOBJ_POINT = 00 02
    • LOBJ_SPOT = 00 03
    • LOBJ_DIFFUSE = 00 04
    • LOBJ_SPECULAR = 00 08
    • LOBJ_ALPHA = 00 10
    • LOBJ_HIDDEN = 00 20
    • LOBJ_RAW_PARAM = 00 40
    • LOBJ_DIFF_DIRTY = 00 80
    • LOBJ_SPEC_DIRTY = 01 00

LObjAttenuationFlagsEnum :

    • LOBJ_LIGHT_ATTN_NONE = 00 00
    • LOBJ_LIGHT_ATTN = 00 01

LObjPoint : (0x14 bytes)

4 bytes - class_name 4 bytes - float - x 4 bytes - float - y 4 bytes - float - z 4 bytes - Unknown

LightAnimPointer : (0x10 bytes)

    • 4 bytes - next_offset - (LightAnimPointer)
    • 4 bytes - light_anim - ?
    • 4 bytes - position_anim - ?
    • 4 bytes - interst_anim - ?

Bugs in HSDRaw - to be tested

JObj : (0x40 bytes)

4 bytes - Unknown 4 bytes - flags 4 bytes - child_offset (JObj) 4 bytes - next_offset (JObj) 4 bytes - dobj_offset (DObj) 4 bytes [3] - float3 - rotation_xyz 4 bytes [3] - float3 - scale_xyz 4 bytes [3] - float3 - translation_xyz 4 bytes - inverse_world_transform_offset (inverse world transform = 4x3 matrix) 4 bytes - robj_offset Pointed by the lists in Root Node scene_data.

JObjFlagsEnum : (can be cumulative)

    • NULL = 00 00 00 00
    • SKELETON = 00 00 00 01
    • SKELETON_ROOT = 00 00 00 02
    • ENVELOPE_MODEL = 00 00 00 04
    • CLASSICAL_SCALING = 00 00 00 08
    • HIDDEN = 00 00 00 10
    • PTCL = 00 00 00 20
    • MTX_DIRTY = 00 00 00 40
    • LIGHTING = 00 00 00 80
    • TEXGEN = 00 00 01 00
    • BILLBOARD = 00 00 02 00
    • VBILLBOARD = 00 00 04 00
    • HBILLBOARD = 00 00 06 00
    • RBILLBOARD = 00 00 08 00
    • INSTANCE = 00 00 10 00
    • PBILLBOARD = 00 00 20 00
    • SPLINE = 00 00 40 00
    • FLIP_IK = 00 00 80 00
    • SPECULAR = 00 01 00 00
    • USE_QUATERNION = 00 02 00 00
    • OPA = 00 04 00 00
    • XLU = 00 08 00 00
    • TEXEDGE = 00 10 00 00
    • JOINT1 = 00 20 00 00
    • JOINT2 = 00 40 00 00
    • EFFECTOR = 00 60 00 00
    • USER_DEFINED_MTX = 00 80 00 00
    • MTX_INDEPEND_PARENT = 01 00 00 00
    • MTX_INDEPEND_SRT = 02 00 00 00
    • MTX_SCALE_COMPENSATE = 04 00 00 00
    • ROOT_OPA = 10 00 00 00
    • ROOT_XLU = 20 00 00 00
    • ROOT_TEXEDGE = 40 00 00 00

InverseWorldTransform : (0x30 bytes)

4 bytes - float - M11 4 bytes - float - M12 4 bytes - float - M13 4 bytes - float - M14 4 bytes - float - M21 4 bytes - float - M22 4 bytes - float - M23 4 bytes - float - M24 4 bytes - float - M31 4 bytes - float - M32 4 bytes - float - M33 4 bytes - float - M34

DObj : (0x10 bytes)

4 bytes - Unknown 4 bytes - next_offset - next DOBJ 4 bytes - mobj_offset - material offset 4 bytes - pobj_offset - mesh offset Linked list that allows retrieving all materials & meshes for the associated JObj.

MObj : (0x18 bytes)

4 bytes - Unknown 4 bytes - render_flags - RenderFlagsEnum 4 bytes - tobj_offset - texture offset - may be invalid if there is no texture for the material 4 bytes - material_offset - material colors? 8 bytes - PEDesc? Contains textures & information about material colors.

RenderFlagsEnum : (cumulative)

    • USER = 80 00 00 00
    • CONSTANT = 00 00 00 01
    • VERTEX = 00 00 00 02
    • BOTH = 00 00 00 03
    • DIFFUSE = 00 00 00 04
    • SPECULAR = 00 00 00 08
    • TEX0 = 00 00 00 10
    • TEX1 = 00 00 00 20
    • TEX2 = 00 00 00 40
    • TEX3 = 00 00 00 80
    • TEX4 = 00 00 01 00
    • TEX5 = 00 00 02 00
    • TEX6 = 00 00 04 00
    • TEX7 = 00 00 08 00
    • TOON = 00 00 10 00
    • ALPHA_MAT = 00 00 20 00
    • ALPHA_VTX = 00 00 40 00
    • ALPHA_BOTH = 00 00 60 00
    • ZOFST = 01 00 00 00
    • EFFECT = 02 00 00 00
    • SHADOW = 04 00 00 00
    • ZMODE_ALWAYS = 08 00 00 00
    • DF_ALL = 10 00 00 00
    • NO_ZUPDATE = 20 00 00 00
    • XLU = 40 00 00 00

TObj : (0x5c octets)

  • 4 bytes - ?
  • 4 bytes - ?
  • 4 bytes - tex_map_id - TexMapIdEnum
  • 4 bytes - gx_tex_gen_src - GXTexGenSrcEnum
  • 4 bytes - float - rx
  • 4 bytes - float - ry
  • 4 bytes - float - rz
  • 4 bytes - float - sx
  • 4 bytes - float - sy
  • 4 bytes - float - sz
  • 4 bytes - float - tx
  • 4 bytes - float - ty
  • 4 bytes - float - tz
  • 4 bytes - wrap_s - WrapEnum
  • 4 bytes - wrap_t - WrapEnum
  • 1 byte- w_scale
  • 1 byte- h_scale
  • 2 bytes - ?

1 byte - bump_map - (False = 00 ; True = 01) 4 bits - alpha_operation - AlphaOperationEnum 4 bits - color_operation - ColorOperationEnum 1 byte - shadow_lightmap - (False = 00 ; True = 01) (2 bytes with a lightmap limit Enum) 1 bit - ext_lightmap - (False = 0 ; True = 1) 1 bit - ambient_lightmap - (False = 0 ; True = 1) 1 bit - specular_lightmap - (False = 0 ; True = 1) 1 bit - diffuse_lightmap - (False = 0 ; True = 1) 4 bits - coord_type - CoordTypeEnum 4 bytes - float - blending - used when color_operation or alpha_operation == BLEND 4 bytes - mag_filter - MagFilterEnum

  • 4 bytes - ?
  • 4 bytes - ?
  • 4 bytes - ?
  • 4 bytes - ?

Texture Information: The TObj contains information about texture environment parameters used for graphic rendering, as well as the offsets of the image and palette data used for this texture. The most important aspects here are the image offset and the palette/TLUT (Texture Look-Up Table) - if the image is not indexed (RGBA, CMPR, etc.), then the palette/TLUT description structure is not used.

  • TexMapIdEnum :
    • GX_TEXMAP0 = 00 00 00 00
    • GX_TEXMAP1 = 00 00 00 01
    • GX_TEXMAP2 = 00 00 00 02
    • GX_TEXMAP3 = 00 00 00 03
    • GX_TEXMAP4 = 00 00 00 04
    • GX_TEXMAP5 = 00 00 00 05
    • GX_TEXMAP6 = 00 00 00 06
    • GX_TEXMAP7 = 00 00 00 07
    • GX_MAX_TEXMAP = 00 00 00 08
    • GX_TEXMAP_NULL = 00 00 00 09
    • GX_TEXMAP_DISABLE = 00 00 00 0A
  • GXTexGenSrcEnum :
    • GX_TG_POS = 00 00 00 00
    • GX_TG_NRM = 00 00 00 01
    • GX_TG_BINRM = 00 00 00 02
    • GX_TG_TANGENT = 00 00 00 03
    • GX_TG_TEX0 = 00 00 00 04
    • GX_TG_TEX1 = 00 00 00 05
    • GX_TG_TEX2 = 00 00 00 06
    • GX_TG_TEX3 = 00 00 00 07
    • GX_TG_TEX4 = 00 00 00 08
    • GX_TG_TEX5 = 00 00 00 09
    • GX_TG_TEX6 = 00 00 00 0A
    • GX_TG_TEX7 = 00 00 00 0B
    • GX_TG_TEXCOORD0 = 00 00 00 0C
    • GX_TG_TEXCOORD1 = 00 00 00 0D
    • GX_TG_TEXCOORD2 = 00 00 00 0E
    • GX_TG_TEXCOORD3 = 00 00 00 0F
    • GX_TG_TEXCOORD4 = 00 00 00 10
    • GX_TG_TEXCOORD5 = 00 00 00 11
    • GX_TG_TEXCOORD6 = 00 00 00 12
    • GX_TG_COLOR0 = 00 00 00 13
    • GX_TG_COLOR1 = 00 00 00 14
  • AlphaOperationEnum:
    • NONE = 0X
    • ALPHAMASK = 1X
    • BLEND = 2X
    • MODULATE = 3X
    • REPLACE = 4X
    • PASS = 5X
    • ADD = 6X
    • SUB = 7X
  • ColorOperationEnum:
    • NONE = X0
    • ALPHA_MASK = X1
    • RGB_MASK = X2
    • BLEND = X3
    • MODULATE = X4
    • REPLACE = X5
    • PASS = X6
    • ADD = X7
    • SUB = X8
  • CoordTypeEnum:
    • UV = X0
    • REFLECTION = X1
    • HILIGHT = X2
    • SHADOW = X3
    • TOON = X4
    • GRADATION = X5
  • MagFilterEnum:
    • GX_NEAR = 00 00 00 00
    • GX_LINEAR = 00 00 00 01
    • GX_NEAR_MIP_NEAR = 00 00 00 02
    • GX_LIN_MIP_NEAR = 00 00 00 03
    • GX_NEAR_MIP_LIN = 00 00 00 04
    • GX_LIN_MIP_LIN = 00 00 00 05
  • WrapEnum:
    • CLAMP = 00 00 00 00
    • REPEAT = 00 00 00 01
    • MIRROR = 00 00 00 02

Material : (0x14 octets)

  • 1 byte - AMB_R - (ambient)
  • 1 byte - AMB_G
  • 1 byte - AMB_B
  • 1 byte - AMB_A
  • 1 byte - DIF_R - (diffuse)
  • 1 byte - DIF_G
  • 1 byte - DIF_B
  • 1 byte - DIF_A
  • 1 byte - SPC_R - (specular)
  • 1 byte - SPC_G
  • 1 byte - SPC_B
  • 1 byte - SPC_A
  • 4 bytes - float - alpha
  • 4 bytes - float - shininess

PObj : (0x18 octets)

  • 4 bytes - Inconnu
  • 4 bytes - next_offset - pobj
  • 4 bytes - vertex_attr_list_offset
  • 2 bytes - Flags - PObjFlagsEnum
  • 2 bytes - display_list_size - number of 0x20 (32) byte blocks occupied by display list data
  • 4 bytes - display_list_offset
  • 4 bytes - weight_list_offset - ? Verify that the envelope_weights array is indeed found at this offset.

As indicated by next_offset, it is a list of meshes to be displayed for a given material referenced by a dobj. PObj contains the offsets of vertex attributes / display list / joint weight list, which is sufficient and allows interpreting and processing vertex, normal, and texture coordinates.

Vertex attributes are the most important - the specified parameters control everything: from the format to the size of the data for each vertex, normal, and texture coordinates, and how these values are dimensioned (scaled) based on the presence and size of each index value appearing in the display list information.

  • PObjFlagsEnum :

Unknown0 = 00 01 Unknown1 = 00 02

    • ANIM = 00 08
    • SHAPE_ANIM = 10 00
    • ENVELOPE = 20 00
    • CULLBACK = 40 00
    • CULLFRONT = 80 00

EnvelopeWeights : (0x? octets)

  • 4 bytes - envelope_count
  • [envelope_count]:
    • 4 bytes - float - weight
    • 4 bytes - pad ?
  • 4 bytes - jobj_list_offset

not verified yet

  • IMAGE_HEADER :
    • 4 bytes - image_offset - image data
    • 2 bytes - width
    • 2 bytes - height
    • 4 bytes - image_format

PALETTE_HEADER : (0x10 bytes)

    • 4 bytes - palette_offset - palette data
    • 4 bytes - palette_format
    • 4 bytes - Unknown
    • 2 bytes - color_count
    • 2 bytes - Unknown

The image_offset and palette_offset are often shared by several textures. Knowing this allows you to find all the information about the textures' image data (width, height, format), as well as the format and the number of colors in the palette/TLUT.

The image format does not determine the total number of colors in the palette it uses. For example, an 8-bit indexed image would have a maximum of 256 colors, but only 136 or 221 colors may be currently used. In this way, the palette will not use the total size it should use.

Images follow the structure generally used by the GameCube:

IMAGE FORMATS :

  • case 0: //i4
  • case 1: //i8
  • case 2: //i4a4
  • case 3: //i8a8
  • case 4: //r5g6b5
  • case 5: //rgb5a3
  • case 6: //r8g8b8a8
  • case 8: //index4
  • case 9: //index8
  • case 0xa: //index14x2
  • case 0xe: //s3tc1

The indexed formats also use palette/TLUT information, and the data can appear in various formats:

PALETTE FORMATS :

  • case 0: //ia8
  • case 1: //r5g6b5
  • case 2: //rgb5a3

---> "Joint Data - Accessing Geometry, Mesh, and Vertex Attributes" https://smashboards.com/threads/melee-dat-format.292603/

// Declaration of a vertex and attribute information // attr, type, cnt, data_type, flags?, file_offset

  • ATTR_DATA
    • 4 bytes - GXAttr vtx_attr_offset - attr
    • 4 bytes - GXAttrType vtx_attr_type - index_type
    • 4 bytes - GXCompCnt comp_cnt - cnt
    • 4 bytes - GXCompType comp_type - data_type
    • 1 bytes - scale
    • 1 bytes - unknown
    • 2 bytes - vtx_stride
    • 2 bytes - data_offset

vertex_attr_offset points to a list of vertex attributes. The number of these attributes is not provided. The data in this structure follows the information and types designed by the GameCube/WII architecture and its API. The list is terminated by a specific value of vtx_attr signaling the end of this list. With access to the SDK documentation, it is strongly recommended to read the section about "vertex attributes and other specifications."

The value of vtx_attr determines the type of data that this attribute represents and can indicate a number of native types used for passing data between software and hardware interfaces.

The possible values are as follows: enum GXAttr (4 bytes)

    • GX_VA_PNMTXIDX = 0, // position/normal matrix index
    • GX_VA_TEX0MTXIDX, // texture 0 matrix index
    • GX_VA_TEX1MTXIDX, // texture 1 matrix index
    • GX_VA_TEX2MTXIDX, // texture 2 matrix index
    • GX_VA_TEX3MTXIDX, // texture 3 matrix index
    • GX_VA_TEX4MTXIDX, // texture 4 matrix index
    • GX_VA_TEX5MTXIDX, // texture 5 matrix index
    • GX_VA_TEX6MTXIDX, // texture 6 matrix index
    • GX_VA_TEX7MTXIDX, // texture 7 matrix index
    • GX_VA_POS = 9, // position
    • GX_VA_NRM, // normal
    • GX_VA_CLR0, // color 0
    • GX_VA_CLR1, // color 1
    • GX_VA_TEX0, // input texture coordinate 0
    • GX_VA_TEX1, // input texture coordinate 1
    • GX_VA_TEX2, // input texture coordinate 2
    • GX_VA_TEX3, // input texture coordinate 3
    • GX_VA_TEX4, // input texture coordinate 4
    • GX_VA_TEX5, // input texture coordinate 5
    • GX_VA_TEX6, // input texture coordinate 6
    • GX_VA_TEX7, // input texture coordinate 7
    • GX_POS_MTX_ARRAY, // position matrix array pointer
    • GX_NRM_MTX_ARRAY, // normal matrix array pointer
    • GX_TEX_MTX_ARRAY, // texture matrix array pointer
    • GX_LIGHT_ARRAY, // light parameter array pointer
    • GX_VA_NBT, // normal, bi-normal, tangent
    • GX_VA_MAX_ATTR, // maximum number of vertex attributes
    • GX_VA_NULL = 0xff // NULL attribute (to mark the end of lists)

All the necessary data to represent a mesh can be specified and indexed in one way or another. Similarly, GX_VA_TEX0MTXIDX, GX_VA_CLR0, and others are also possible - the most frequent values in the SSBM data are: GX_VA_PNMTXIDX, GX_VA_POS, GX_VA_NRM, and GX_VA_TEX0. This is to be expected as joint matrices, vertex positions/normals, and texture coordinates respectively are probably the most basic elements needed to display a textured mesh, whether static or animated.

When the value of vtx_attr == GX_VA_NULL (0xFF), the end of the vertex attribute array has been reached.


The vtx_attr_type values is actually associated with how the value is indexed, and can thus also determine the size of the index value within the display list data.

  • 4 bytes - enum GXAttrType
    • GX_NONE = 0,
    • GX_DIRECT,
    • GX_INDEX8,
    • GX_INDEX16
  • Structures COLL_DATA : (collision data)
    • 4 bytes - vertex_offset (2 floats per entry corresponding to probably 2D data)
    • 4 bytes - vertex_count
    • 4 bytes - index_offset
    • 4 bytes - index_count
    • 4 bytes [5] - Unknown
      • 2 bytes - index_start
      • 2 bytes - index_count
    • 4 bytes - Unknown
    • 4 bytes - Unknown