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} :
- 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.
- 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).