Symptomes
-
Vitesse identique pour toutes les portes : les portes s’ouvraient et
se fermaient toutes au meme rythme, beaucoup trop rapidement. Les valeurs
zl_OpeningSpeed/zl_ClosingSpeedduZLiftableetaient ignorees, le
code utilisait des constantes en dur (DEFAULT_OPEN_SPEED=2.0f,
DEFAULT_CLOSE_SPEED=1.2f). -
Texture des portes animees incorrecte : toutes les faces d’une meme
porte portaient la texture du PREMIER pan rencontre. Les portes a plusieurs
segments (ex. zone 30 de level A avec 6 pans) affichaient une texture
uniforme au lieu des textures differentes prevues par l’original.
Diagnostic
Vitesse : les champs zl_OpeningSpeed / zl_ClosingSpeed du ZLiftable
(cf. zone_liftable.h) sont exprimes en unites-editeur Amiga par frame a
25 fps. Notre code ne les lisait meme pas depuis le JSON – LevelSceneBuilder
stockait openDuration et les conditions d’ouverture en UserData mais jamais
openSpeed / closeSpeed.
Textures : le computeIfAbsent sur DoorAccum figeait les donnees
texture (clipIdx, fromTile) du PREMIER segment rencontre, puis les
appliquait a TOUS les segments. Or chaque pan de porte a son propre
WallRenderEntry avec ses propres clipIdx/fromTile/yOffset dans le
graphe du niveau – il suffisait de les conserver par-segment au lieu de
les mutualiser.
Fix
LevelSceneBuilder.java :
– DoorAccum restructure : chaque segment stocke ses propres
[x0, z0, x1, z1, texIdx, fromTile, yOffset] au lieu d’un texIdx global.
Le constructeur devient DoorAccum(yTop, yBot, doorZoneId) et
addSeg(x0, z0, x1, z1, texIdx, fromTile, yOffset) accepte les 3 donnees
texture du segment.
– parseWalls lit maintenant aussi le champ yOffset du JSON (w[7] =
VO = (-floor) & 0xFF).
– Boucle de detection des portes : passe clipIdx, fromTile,
wallYOffset du mur courant a addSeg() – chaque pan conserve ses
donnees propres.
– Rendu des portes : chaque segment recoit son propre materiau
wm[segTexIdx] et ses propres UV. Appel : makeDoorSegGeo(..., texW,.
segFromTile, segYOffset)
– makeDoorSegGeo prend un parametre yOffset supplementaire et l’applique
aux coordonnees UV V : V_offset = yOffset / TEX_V. Cela aligne la
texture de la porte sur la bonne ligne horizontale, comme dans l’original.
– UserData ajoutees sur chaque Node porte : zlBottom, zlTop,
openSpeed, closeSpeed (valeurs Amiga brutes, a convertir au runtime),
en plus de openDuration, raiseCondition, lowerCondition et des 4 sfx.
DoorControl.java :
– setSpatial lit openSpeed, closeSpeed, zlBottom, zlTop depuis les
UserData du Node porte.
– Conversion 25 fps Amiga -> state/s JME :
hEditor = |zl_Top - zl_Bottom| (hauteur de course en unites Amiga)
openSpeed_jme = (zl_OpeningSpeed * 25) / hEditor (state/seconde)
closeSpeed_jme = (zl_ClosingSpeed * 25) / hEditor
– Cas special : si zl_ClosingSpeed == 0 (ex. zone 30 level A), la porte ne
se referme jamais -> on force lowerCondition = LOWER_NEVER.
Verifications
Exemples level A apres le fix :
| Zone | openSpeed | course | duree d’ouverture |
|——|———–|——–|——————-|
| 5 | 16 | 512 | 1.28 s |
| 30 | 2 | 512 | 10 s (lente) |
| 11 | 16 | 512 | 1.28 s |
| 132 | 4 | 704 | 7.04 s |
Apres rebuild des .j3o (./gradlew buildScenes), verifier :
– Les portes de level A s’ouvrent maintenant a des vitesses distinctes
– Les portes multi-pans (zone 30 avec 6 pans) affichent correctement les
textures de chaque pan
– La porte zone 30 et zone 132 restent ouvertes (closeSpeed=0)
Code en reference
zone_liftable.h: structuresZLiftable(36 bytes) etZDoorWall
(10 bytes). Les champszl_OpeningSpeed/zl_ClosingSpeedsont a
l’offset +4 et +6.zone_liftable_pvs.c: parcoursZone_InitDoorListqui confirme la
lecture WORD par WORD jusqu’au marqueur-1pour lesZDoorWall.LevelED.txt(AMOS) : confirmation que le temps d’ouverture est bien
|Top - Bottom| / OpeningSpeedframes a 25 fps.