Aller au contenu principal

Session 132decimus — Fix bug edges + extension extracteur (clips/map/flymap)

Bug fix : 0 edges sur tous les niveaux

Après premier run de extractLevelsFull sur les 16 niveaux, on observe 0 edges
sur tous les niveaux, ce qui est impossible (les niveaux ont 50-220 zones).

Diagnostic : le calcul était

int numEdges = (offsetToObjects - offsetToFloorLines) / EDGE_SIZE;

basé sur le commentaire ; todo de hires.s:362-369. Mais sur LEVEL_A :
offsetToFloorLines = 25494
offsetToObjects = 3014

=> (3014 - 25494) < 0, donc numEdges = 0. Les edges sont en réalité à la fin
du fichier, pas entre les autres sections. Le commentaire ASM était un TODO non
résolu chez Team17 eux-mêmes.

Fix dans LevelFullExtractor.java :

int edgeStart = header.offsetToFloorLines;
int edgeEnd   = header.offsetToObjects > edgeStart
              ? header.offsetToObjects   // cas "theorique"
              : bin.length;              // cas reel observe
int numEdges  = Math.max(0, (edgeEnd - edgeStart) / EDGE_SIZE);
// Sanity check : somme des ZoneT_Points_w (chaque zone est polygone N-edges)
int zoneEdgesSum = zones.stream().mapToInt(ZoneRecord::pointsCount).sum();
if (zoneEdgesSum > 0 && zoneEdgesSum < numEdges) numEdges = zoneEdgesSum;

Extension : intégration de twolev.clips/.map/.flymap

Deuxième phase de l’extracteur : lire les 3 fichiers de niveau qu’on n’utilisait
pas. Refactor minimal pour rester rétrocompatible.

Nouveaux records dans LevelFullExtractor :
PvsClipData(totalBytes, totalWords, groups, tailHex) :
contenu de twolev.clips découpé en groupes de WORDs séparés par 0xFFFE,
avec la queue (probable Lvl_ConnectTable) en hex.
LevelGrid(width, height, totalBytes, dataHex) :
grille 100×100 bytes pour twolev.map et twolev.flymap.

Nouveaux champs dans ExtractedLevel :
PvsClipData clips (null si twolev.clips absent)
LevelGrid map (null si twolev.map absent)
LevelGrid flyMap (null si twolev.flymap absent)

API :
extract(id, bin, graph) reste la signature historique (overload qui délègue
avec null/null/null) — SmokeTest continue à marcher sans modif.
extract(id, bin, graph, clips, map, flyMap) est la nouvelle signature complète.

Main charge les 3 fichiers via Files.exists() (silencieux si absent).
L’output console affiche maintenant [CMF] indiquant la présence de chaque
fichier optionnel : [CMF] = tous trois présents, [--F] = juste flymap, etc.

JSON : les 3 nouveaux champs sont sérialisés en queue. Pour les fichiers
absents : "clips": null, "map": null, "flyMap": null. Pour les présents,
structure complète avec groups: [[...], [...], ...] pour les clips et dataHex
pour les grilles.

Format de twolev.clips reverse-engineeré

Depuis hires.s:418-475 :
– Tableau de WORDs signés 16-bit big-endian
– Séparateur 0xFFFE (-2) entre les groupes de clips
– Chaque groupe = liste d’indices vers les points (vertices) qui clippent un
edge dans le PVS d’une zone
– Après tous les groupes : Lvl_ConnectTable (table de connexions inter-zones,
format à reverser plus tard)

Notre parseur découpe naïvement sur tous les 0xFFFE et place le reste après le
dernier 0xFFFE dans tailHex. Plus tard, le cross-référencement avec les
PVST.clipId permettra d’identifier exactement où s’arrête la série de groupes
PVS et où commence la ConnectTable.

Format de twolev.map / twolev.flymap

Grilles 100×100 bytes (10000 = 100²). Chaque cellule = ID de tile :
twolev.map : map top-down (sol/plafond visible au menu pause)
twolev.flymap : pathfinding AI grid pour les flying aliens

Stocké en hex pour rester compact dans le JSON. Le décodage 2D se fait côté
consommateur (par exemple un futur LevelMapInspector).

Laisser un commentaire

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