Aller au contenu principal

Session 58 — VectObj : parser strict conforme ASM

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 rawTexOffset preservant 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

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *