Aller au contenu principal

Session 69 — Fix portes : vitesse + textures par pan

Symptomes

  1. 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_ClosingSpeed du ZLiftable etaient ignorees, le
    code utilisait des constantes en dur (DEFAULT_OPEN_SPEED=2.0f,
    DEFAULT_CLOSE_SPEED=1.2f).

  2. 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 : structures ZLiftable (36 bytes) et ZDoorWall
    (10 bytes). Les champs zl_OpeningSpeed/zl_ClosingSpeed sont a
    l’offset +4 et +6.
  • zone_liftable_pvs.c : parcours Zone_InitDoorList qui confirme la
    lecture WORD par WORD jusqu’au marqueur -1 pour les ZDoorWall.
  • LevelED.txt (AMOS) : confirmation que le temps d’ouverture est bien
    |Top - Bottom| / OpeningSpeed frames a 25 fps.

Laisser un commentaire

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