Objectif
Remplacer les vertex-colors aplaties (flat shading derive du texOffset) par de
vraies textures. Les armes, monstres et decors affichent desormais les pixels
d’origine issus de newtexturemaps.
Decouverte du format texture (analyse ASM drawpol l.2546-2559)
drawpol:
move.l d6, d0
asr.l #8, d0 ; d0 = (d6 >> 8) = 14 bits U_int
swap d5
move.b d5, d0 ; low byte de d0 = V_int (byte @ +3)
move.b (a0, d0.w*4), d3 ; sample texel byte
Le d0 final = (U_int << 8) | V_int, puis d0 * 4 donne le byte offset final.
Ce *4 revele un layout interleaved 4-chunky :
– adjacent en V = +4 bytes
– adjacent en U (dans le meme bloc de 4 colonnes) = +1 byte
– bloc de 4 colonnes interleaved = 256 bytes (64 pixels * 4 bytes)
Layout newtexturemaps (128 KB = 2 banques * 64 KB)
byte layout d'une banque (65536 bytes) :
block 0 (bytes 0..255) : 4 colonnes interleaved
byte[0] byte[1] byte[2] byte[3] <- row 0, col 0,1,2,3
byte[4] byte[5] byte[6] byte[7] <- row 1, col 0,1,2,3
... (64 rows, 256 bytes)
block 1 (bytes 256..511) : 4 colonnes suivantes (4..7)
...
block 255 (bytes 65280..65535) : colonnes 1020..1023
Une banque = 256 blocs * 256 bytes = 65536 = 1024 colonnes de 64 pixels.
Les textures sont des strips verticaux de 64 pixels comme les murs du jeu.
Modifications TextureMapConverter
- Layout interleaved 4-chunky implemente dans la generation des PNG
- Nouvelle sortie
texturemaps_atlas.png(1024×128) = bank0 + bank1 empiles - Nouvelles methodes publiques
texOffsetToColumn()ettexOffsetToBank() sampleColor()mis a jour pour le nouveau layout
Modifications VectObjConverter
- Record
Triangleetendu : positions + UV par vertex + couleur shade readPolygons()genere les UV atlas pour chaque vertex :
java
int baseCol = TextureMapConverter.texOffsetToColumn(rawTexOffset);
int baseRow = TextureMapConverter.texOffsetToBank(rawTexOffset) * 64;
float uCol = (baseCol + vtxU[v]) / 1024f;
float vRow = (baseRow + vtxV[v]) / 128f;buildGeometry()emet maintenantType.TexCoorden plus de Position/Normal/ColorbuildMaterial()chargeTextures/vectobj/texturemaps_atlas.pngen ColorMap
avec NearestNoMipMaps + MagFilter.Nearest pour le look retro pixel-art
Configuration materiau
Unshaded.j3md :
ColorMap = texturemaps_atlas.png (nearest filtering)
VertexColor = true (module par brightness par-poly)
FaceCullMode.Off (front+back visible)
WrapMode.Repeat (permet U > 1 pour tiling)
Le pixel final = texture * vertex_color, donc le brightness par poly module
correctement la texture (eclairage directionnel preserve).
Fallback propre
Si texturemaps_atlas.png n’existe pas encore (premier run avant
./gradlew convertTextureMaps), buildMaterial() tombe sur vertex-color seul
avec un WARN dans les logs – le comportement session 58-61 reste fonctionnel.
Pipeline
./gradlew convertTextureMaps # genere les PNG atlas
./gradlew convertVectObj # puis regenere les .j3o avec UVs + texture
Known limitation
La correspondance exacte byte U,V du vertex → pixel dans l’atlas est une
premiere approximation : on traite U et V comme des pixels directs dans une
region 64×64 ancree a la colonne du texOffset. L’ASM fait une indexation plus
complexe (fixed-point 16.16 avec mask 0x3FFFFF) dont l’equivalence exacte en
UV normalisees demandera peut-etre un ajustement dans une future session si
certaines textures apparaissent decalees ou mal echelonnees.