Cette section est en cours de rédaction.
Des recherches sont encore nécessaires et certains paragraphes peuvent être faux.
Modèle Gotcha Force
Les modèles Gotcha force fonctionnent comme ceux du jeu Smash Bros investigué par sa communauté.
Les modèles sont des fichiers HSD de la library Hal SysDolphin.
Header
Le header ce compose de la position du fichier HSD puis contient une location de suite de flags et la liste des armatures.
En 0x0 on retrouve l'offset 0x100 menant au fichier HSD.
En 0x4 on retrouve l'offset 0x20 menant à la liste des flags des armatures. Flags qui sont Inconnu à ce jour. Les flags sont en u8 pouvant aller de 00 à FF.
En 0x8 on retrouve l'offset 0xC0 menant à la liste des armatures.
Les fichiers _mdl se retrouvent dans les pzz des borgs (plxxxx.pzz) en position 004 à 009 ainsi que les fichiers pl*_mdl.arc. Il s'agit d'un format de fichier relatif au fonctionnement de la lib HSD utilisé dans plusieurs jeux par Capcom. L'usage d'un script est nécessaire pour référencer les fichiers éligibles au format _mdl dans l'ensemble de l'AFS data et dans les sous fichiers des pzz.
Pour commencer, il s'agit de synthétiser les investigations de la commu Super Mario Smash Melee et de les traduire. HSDRaw, un éditeur 3D dotnet de ce format est instable sur mon Windows (segfaults même sur SSBM -> fichiers spécifiés comme bien géré dans la dernière release des sources - sans pouvoir investiguer plus) et ne permet pas d'éditer les fichiers. Par contre, il est prouvé qu'un edit des _mdl pour commencer à l'offset 0x100 (celui ou on a la taille totale du fichier en big endian) 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 noeud en violet.
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.
Le format dat/usd sur ssbm se découpe en plusieurs blocks :
- Header - 0x20 octets - unsigned big endian
- 4 octets - Taille totale du fichier
- 4 octets - Taille du Data block
- 4 octets - Nombre d'entrée dans la Table de relocs
- 4 octets - root0_count
- 4 octets - root1_count
- 12 octets - Pad ? à voir de manière scripté si des valeurs apparaissent à ces offsets
- Data block : (JOBJ, COLL_DATA, ?)
- Ces structures sont détaillée plus loin ci-dessous.
- Relocation Table :
- Tableau d'offsets de 4 octets - Offsets des structures dans le DB.
- 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
- Tableau de taille 8 * root0_count
- String Table :
- Suite de strings terminées par Null au nombre de root0_count + root1_count
Structures rencontrées dans le DB :
- Structures JOBJ pointées par les listes dans Root Nodes (0x40 octets)
- 4 octets - Inconnu
- 4 octets - flags
- 4 octets - child_offset (JOBJ)
- 4 octets - next_offset (JOBJ)
- 4 octets - dobj_offset (DOBJ)
- float3 - rotation_xyz (taille en octets d'un float à déterminer)
- float3 - scale_xyz
- float3 - translation_xyz
- 4 octets - transform_offset (inverse transform = méthode de nombres aléatoires ? mouvement ?)
- 4 octets - Inconnu
Note : l'arborescence est cumulative sur les transformations pour les relations parents->enfants
- DOBJ_DATA : liste chaînée qui permet de récupérer l'ensemble des materials & mesh pour le JOBJ auquel il est lié
- 4 octets - Inconnu
- 4 octets - next_offset - prochain DOBJ
- 4 octets - mobj_offset - material ?
- 4 octets - pobj_offset - mesh ?
- MOBJ_DATA : Contient les textures & informations sur les couleurs des Materials
- 4 octets - Inconnu
- 4 octets - Flags Inconnus
- 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 - Inconnu
- MATERIAL_COLORS : (material_offset)
- 4 octets - Couleur Inconnue - diffuse?
- 4 octets - Couleur Inconnue - ambient?
- 4 octets - Couleur Inconnue - specular?
- float - Inconnu
- float - Inconnu
- TOBJ_DATA : Informations de Textures (0x5c)
- 19 * 4 octets - Inconnu [19]
- 4 octets - image_offset - image header information
- 4 octets - palette_offset - palette header information
- 2 * 4 octets - Inconnu
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.
- IMAGE_HEADER :
- 4 octets - image_offset - image data
- 2 octets - width
- 2 octets - height
- 4 octets - image_format
- PALETTE_HEADER : (0x10)
- 4 octets - palette_offset - palette data
- 4 octets - palette_format
- 4 octets - Inconnu
- 2 octets - color_count
- 2 octets - Inconnu
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.
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.
Les images suivent la structure généralement utilisée par la 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
Les formats indexés utilisent aussi les informations de palettes/tlut et les données peuvent apparaître en plusieurs 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/
trad a revoir à partir de là, il faut investiguer le rendu 3D sur GameCube pour mieux comprendre
- POBJ_DATA :
- 4 octets - Inconnu
- 4 octets - next_offset
- 4 octets - vertex_attr_array_offset - vertex attribute list
- 2 octets - Flags Inconnus
- 2 octets - display_list_size - number of 0x20 (32) byte blocks occupied by display list data
- 4 octets - display_list_offset - display list
- 4 octets - weight_list_offset - joint weight info
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_DATA 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.
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.
// déclaration d'un vertex et attribute information // attr, type, cnt, data_type, flags?, file_offset
- ATTR_DATA
- 4 octets - GXAttr vtx_attr_offset - attr
- 4 octets - GXAttrType vtx_attr_type - index_type
- 4 octets - GXCompCnt comp_cnt - cnt
- 4 octets - GXCompType comp_type - data_type
- 1 octets - scale
- 1 octets - Inconnu
- 2 octets - vtx_stride
- 2 octets - 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".
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.
Les valeures possibles sont les suivantes :
- enum GXAttr (4 octets)
- 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 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.
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 octets - enum GXAttrType
- GX_NONE = 0,
- GX_DIRECT,
- GX_INDEX8,
- GX_INDEX16
- Structures COLL_DATA : (données de collisions)
- 4 octets - vertex_offset (2 float par entrée correspondant à des données 2D probablement)
- 4 octets - vertex_count
- 4 octets - index_offset
- 4 octets - index_count
- 20 octets - tableau inconnu (x5)
- 2 octets - index_start
- 2 octets - index_count
- 4 octets - Inconnu
- 4 octets - Inconnu