Objectif
Reprise du decodage vectobj selon strictement ce qui est indique dans
objdrawhires.s (fonction draw_PolygonModel + doapoly + draw_PutInLines).
Analyse ASM des lignes cles
Structure globale du fichier (relatif a draw_StartOfObjPtr_l = fichier+2) :
+0 WORD sortIt <- move.w (a3)+, draw_SortIt_w (l.1840)
+2 WORD numPoints <- move.w (a3)+, draw_NumPoints_w (l.1847)
+4 WORD numFrames <- move.w (a3)+, d6 (l.1848)
+6 PointerTable[nf] :
WORD ptsOfs <- (a4,d5.w*4) (l.1867)
WORD angOfs <- 2(a4,d5.w*4) (l.1870)
+6+nf*4 Parts (sortKey<0 = fin) :
SWORD sortKey <- move.w (a1)+, d7 (l.2117)
WORD bodyOfs <- move.w (a1)+, d6 (l.2127)
Point data @ ptsOfs :
+0 LONG onOff_l <- move.l (a3)+, draw_ObjectOnOff_l (l.1875)
+4 BYTE[((np+1)/2)*2] pointAngles <- draw_PointAngPtr_l (l.1876-1882)
+... np x 6 bytes <- addq #6, a3 (l.1917)
Chaque point : SWORD x, SWORD y, SWORD z
Polygone @ bodyOfs (taille = N*4 + 18) :
+0 SWORD numLines (N) <- (a1)+, d7 (l.2223)
+2 WORD flags <- (a1)+, draw_PreHoles_b (l.2224)
+4..+4+N*4 N x vertex :
+0 : WORD ptIdx <- move.w (a1), d0 (l.3091)
+2 : BYTE u <- move.b 2(a1), d2 (l.3164)
+3 : BYTE v <- move.b 3(a1), d5 (l.3180)
+4+N*4 8 bytes phantom (lus par PutInLines, ignores)
+N*4+12 WORD texOffset <- (a1)+, d0 (l.2372)
bit 15 = banque secondaire (l.2375-2376)
+N*4+14 BYTE brightness <- (a1)+, d1 (l.2382)
+N*4+15 BYTE polyAngle <- (a1)+, d2 (l.2407)
+N*4+16 WORD gouraud <- 12(a1,d7*4) (l.2225)
Bug identifie et corrige : vertex ptIdx
Le parser precedent lisait :
int normalIdx = data[vOfs] & 0xFF; // soi-disant "normal index"
int ptIdx = data[vOfs + 1] & 0xFF;
Mais l’ASM (l.3091) fait move.w (a1), d0 = lecture d’un WORD complet.
Le resultat est ensuite utilise comme (a3, d0.w*4) pour indexer les points
projetes (4 bytes/point).
Pour les petits objets (numPoints < 256) le byte de poids fort vaut 0, donc
la lecture byte+byte donne le meme resultat. Mais pour les objets avec plus
de 256 points ce serait faux. Le parser lit maintenant un WORD entier
via b.getShort(vOfs) & 0xFFFF.
VectObjConverter.java — changements
- JavaDoc classe : documentation stricte avec references de lignes ASM
- readPolygons() :
- Lecture vertex par WORD (
b.getShort(vOfs) & 0xFFFF) conforme l.3091 - Extraction explicite des coordonnees U,V via bytes +2 et +3 (prepare
futur texturing, pas encore utilise pour generer de vrais UV) - Footer : calcul
rawTexOffsetpreservant bit 15 pour banque secondaire - Lecture supplementaire du WORD gouraud a N*4+16
- Tous les offsets sont commentes avec la ligne ASM d’origine
Impact
La geometrie produite pour les objets existants (blaster, passkey, switch,
etc.) est numeriquement identique car ces objets ont numPoints < 256.
Le code est maintenant correct pour tout objet potentiel (robuste).
Pipeline
./gradlew convertVectObj