Probleme observe
Le dump de scene LEVEL_A montrait :
[A] DUMP zone 0 : pointIds(0)=[]
[A] DUMP overlap pointIds <-> wallVerts = 0
[A] wall vertices : total=415 leftNonZero=0 (anim=0) rightNonZero=0 (anim=0)
Malgre pointBrights correctement parse (1270 entries non-zero, 8 vraiment
animees), AUCUN sommet de mur ne retrouvait son rawWord. La fonction
wallVertexRawWord faisait un lookup globalPtId -> index dans
zone.pointIds, mais ce tableau etait systematiquement vide.
Cause racine
LevelBinaryParser.readIds avait un guard if (negOffset >= 0) return qui rejetait categoriquement tout offset positif ou nul.
new short[0]
Deux conventions coexistent dans le binaire AB3D2 :
– z_EdgeListOffset est TOUJOURS negatif (la liste precede la struct
zone, documente dans zone.h:18-30).
– z_Points peut etre positif OU negatif. Quand positif, la liste se
trouve APRES la struct zone (souvent apres les records PVS qui sont
de longueur variable). Voir newanims.s:524 ({@code add.w
ZoneT_Points_w(a0),a1}) qui ajoute la valeur signed sans contrainte
de signe, et le macro C Zone_GetPointIndexList dans
zone_inline.h:42-45 qui fait simplement {@code (byte*)zonePtr +
z_Points}.
Donc pour TOUTE zone dont z_Points > 0 (= la majorite), le parser
retournait une liste vide -> rupture de la chaine d’eclairage par-vertex.
Modification
core/level/LevelBinaryParser.java
– Renomme le parametre negOffset en offset (plus de presupposition de
signe).
– Suppression du guard precoce >= 0.
– Ajout d’une logique de bornage differenciee :
– offset < 0 : limite haute = baseOffset (debut struct), pas de cap
sur le nombre d’entries.
– offset > 0 : limite haute = raw.length, cap a 64 entries (= 4 fois
le max theorique de 20 slots par zone selon hires.s:1499 ou
muls #40,d0 indique 40 WORDs / 2 par slot).
– Ajout d’une JavaDoc detaillee documentant les deux conventions et la
reference ASM exacte.
Impact attendu
Apres re-build (./gradlew convertLevels buildScenes) le dump devrait
montrer pour les zones non-degenerees :
– pointIds(N)=[v0,v1,...] au lieu de []
– overlap pointIds <-> wallVerts > 0
– leftNonZero / rightNonZero > 0 (les sommets de murs retrouvent leur
rawWord pour le shading et l’animation).
L’animation runtime de luminosite (lampes qui pulsent, flicker) deviendra
visible sur les niveaux dans le rendu Java pour la 1ere fois.