Aller au contenu principal

Session 118 — Audit twolev.bin : ajout PointBrights et ZoneBorderPoints

Demande

Verifier que le parsing/export de {@code twolev.bin} extrait toutes les
donnees presentes dans le format binaire original, et ajouter ce qui manque.

Methodologie

Comparaison ligne par ligne entre :
– {@code defs.i} (TLBT, ZoneT, EdgeT, PVST, ObjT, EntT) — structures officielles
– {@code hires.s:330-430} — sequence de chargement du fichier
– {@code LevelBinaryParser.java} — implementation Java actuelle

Trouvailles

Header TLBT (54 bytes apres 1600 bytes de messages) : tous les champs sont
lus correctement en Java.

Structures referencees par offsets :
– {@code TLBT_PointsOffset_l} : Points table → OK
– {@code TLBT_FloorLineOffset_l} : Edges → OK (avec exitZoneId a -2)
– {@code TLBT_ObjectDataOffset_l} : ObjT/EntT → OK
– {@code TLBT_ObjectPointsOffset_l} : ObjectPoints → OK
– {@code TLBT_ShotDataOffset_l} : buffers projectiles runtime (donnees nulles
dans le fichier, juste reservation memoire) → pas pertinent a exporter
– {@code TLBT_AlienShotDataOffset_l} : idem → pas pertinent
– {@code TLBT_Plr1ObjectOffset_l}, {@code TLBT_Plr2ObjectOffset_l} : pointent
vers des ObjT pre-construits pour les joueurs ; les positions de depart
sont deja dans le header TLBT → doublons

Structures NON referencees par TLBT mais lues par {@code hires.s} :

  1. PointBrights — lue a {@code pointsOffset + numPoints*4 + 4}, taille
    {@code numZones * 80} bytes ({@code numZones * 40} WORDs).
    Reference : {@code hires.s:351} :
    asm
    lea 4(a2,d0.w*4),a2 ; a2 = points_end + 4 (padding)
    move.l a2,PointBrightsPtr_l

    Format de chaque WORD ({@code hires.s:1502-1543}) :
    – Byte BAS : luminosite de base (signed)
    – Byte HAUT (si != 0) : animation lumiere

    • bits 0-3 du byte haut : index dans {@code Anim_BrightTable_vw}
    • bits 4-7 : amplitude/phase d’oscillation

Critique pour le rendu : sans cette table, l’eclairage dynamique des
zones (lampes pulsantes, transitions de luminosite) ne peut pas etre
reproduit fidelement.

  1. ZoneBorderPoints — lue a {@code PointBrights + numZones*80}, taille
    variable, jusqu’a {@code floorLineOffset – 2}.
    Reference : {@code hires.s:359-361} et {@code newanims.s:119-131}.
    Format : 10 WORDs reserves par zone (point indices), terminees par WORD
    {@code -1} si la liste est plus courte que 10. Utilisee par le moteur
    pour la propagation de lumiere d’une zone a ses voisines via le PVS
    (eclairage radial autour des sources lumineuses).

Implementation

LevelBinaryParser.BinData : ajout de 2 champs avec javadoc detaillant
le format binaire et la semantique :
– {@code short[][] pointBrights} : indexed par {@code [zoneIdx][i]} avec
{@code i ∈ [0..39]}
– {@code short[][] zoneBorderPoints} : tableau de listes variables par zone,
troncature a la premiere occurrence de {@code -1}

LevelBinaryParser.parseBin() : nouvelle section apres la lecture des
Points qui calcule les offsets {@code pointBrightsOffset} et
{@code zoneBorderOffset} et lit les 2 tables. Les 2 lectures sont gardees
separement avec validation d’offsets pour eviter d’echouer sur des fichiers
legèrement non conformes.

LevelJsonExporter : ajout de 2 sections JSON entre {@code points} et
{@code edges} :

"pointBrights": [
  [v0, v1, ..., v39],   // zone 0
  [v0, v1, ..., v39],   // zone 1
  ...
],
"zoneBorderPoints": [
  [pt0, pt1, pt2],      // zone 0 : 3 points jusqu'au -1
  [pt0, ..., pt9],      // zone 1 : 10 points pleins
  ...
]

Les valeurs de {@code pointBrights} sont stockees comme entiers non-signes
(0..65535) car le byte haut peut activer l’animation. Les indices de
{@code zoneBorderPoints} sont signes mais doivent etre {@code >= 0} (les
valeurs negatives sont des terminators tronques par le parser).

Champs deliberement non exportes

Champs runtime dans ObjT/EntT (initialises a 0 ou non significatifs dans
le fichier) : {@code SeePlayer}, {@code DamageTaken}, {@code CurrentMode},
{@code CurrentSpeed}, {@code EnemyFlags}, {@code Timer2}, {@code ImpactX/Y/Z},
{@code VelocityY}.

Buffers de projectiles ({@code ShotData}, {@code AlienShotData}) :
zones de memoire reservees au runtime, contenu null dans le fichier.

Plr1ObjectOffset / Plr2ObjectOffset : pointent vers des structures ObjT
preconfigurees pour les joueurs, mais les positions de depart sont deja
exposees via {@code player1} et {@code player2} dans le JSON. Aucune autre
donnee unique.

Validation attendue

Apres re-export par {@code ./gradlew convertLevels} (ou autre task qui
lance {@code LevelJsonExporter}) :

INFO  PointBrights : 134 zones x 40 WORDs depuis 0xXXXX
INFO  ZoneBorderPoints : 134 zones depuis 0xXXXX (XXXX bytes total, ...)

Dans {@code level_A.json}, presence des cles {@code pointBrights} et
{@code zoneBorderPoints} avec respectivement 134 entrees (1 par zone). Le
total du fichier passe d’environ 200 KB a environ 250-300 KB (selon la
densite des ZoneBorderPoints).

Laisser un commentaire

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