PAL / ALP / LHT / SHD — palettes et tables de correspondance de couleurs
Source : coreprime/kbot @ 0ab97bf · Modifier sur GitHub
Total Annihilation a livré tout son monde en 256 couleurs. Le fichier
.palcontient cette palette ; les fichiers.alp,.shdet.lhtsont des tables de correspondance construites à partir d'elle, dont le moteur se sert pour mélanger, ombrer et éclairer les pixels sans quitter l'espace de couleurs indexées.Aucun des quatre n'a d'en-tête, de champ de version ni de compression. Un
.palfait 1 024 octets (256 × RGBx) ; un.alpfait 65 536 octets (256 lignes de 256 index de palette) et les.shd/.lhtfont 8 192 octets chacun (32 lignes de 256 index de palette).
palettes/palette.pal — rendu par kbot pal swatch
Tip
Essayez vous-même.
kbot pal info palettes/palette.pal # one-liner
kbot pal describe palettes/palette.pal # full RGB dump
kbot pal swatch palettes/palette.pal -o pal.png --cell 24
# Render a lookup table, coloured by the palette:
# .alp as 256×256 cells, .shd / .lht as 256×32 cells
kbot pal lookup palettes/palette.alp --palette palettes/palette.pal --target alp.png
kbot pal lookup palettes/palette.shd --target shd.png
# TA: Kingdoms: the palette is usually a PCX next to its tables
kbot pal lookup palettes/aramon.alp --palette palettes/aramon.pcx --target aramon.png
# Round-trip to editor-friendly formats
kbot pal convert palettes/palette.pal -o palette.gpl # GIMP
kbot pal convert palettes/palette.pal -o palette.txt --format jasc # JASC
Consultez la référence de kbot pal de la CLI.
Depuis Go. Utilisez formats/pal :
import "github.com/coreprime/kbot/formats/pal"
p, _ := pal.LoadFromFile("palettes/palette.pal")
fmt.Printf("RGB[0] = %v (black; sprites key it per frame)\n", p.Colors[0])
for i, c := range p.Colors {
fmt.Printf("%3d #%02x%02x%02x\n", i, c.R, c.G, c.B)
}
Disposition sur le disque (.pal)
typedef struct {
uint8 R;
uint8 G;
uint8 B;
uint8 A; // Unused. Cavedog files have this as 0 throughout.
} PALEntry;
PALEntry entries[256]; // 256 × 4 = 1024 bytes
Il n'y a ni signature ni version. Le jeu charge palettes/<name>.pal de la
façon suivante (le pal.LoadNamed de kbot-io fait de même, et le studio et
l'explorateur de ressources chargent palette.pal par son intermédiaire pour
chaque rendu de TA : pool de tuiles, minicartes, terrain du bac à sable,
éléments de décor, textures et couleurs des modèles) :
- 1 024 octets ou plus : les 1 024 premiers octets forment la palette ; le reste est ignoré.
- Vide ou absent : la palette vient alors de
palettes/<name>.pcx— les 768 derniers octets de ce fichier, qu'un marqueur0x0Cles précède ou non. TA 3.1c reconstruit ensuite les tables.alp,.shdet.lhtpour ces couleurs. - De 1 à 1 023 octets : inutilisable ; le jeu lit 1 024 octets au-delà de la fin du fichier. kbot signale une erreur (et le studio se rabat sur la palette de TA intégrée).
.pal — la palette de référence de TA
Les octets R, G, B, A de chaque entrée signifient littéralement
rouge, vert, bleu, inutilisé. L'index 0 est un noir ordinaire.
Les tuiles de terrain, les minicartes et les fonds le dessinent opaque (62
des 275 cartes d'origine l'utilisent dans leurs tuiles). La transparence se
décide image par image, pas par la palette : l'octet clé d'une frame GAF
(souvent 9, parfois 0) et ses pixels sautés sont transparents, et les
textures des modèles sont échantillonnées sans clé.
| Index | Convention de TA | Remarques |
|---|---|---|
0 |
Noir | Opaque dans le terrain, les minicartes et les fonds ; transparent seulement dans les frames de sprites dont la clé est 0. |
9 |
« Rose magique » | Utilisé par les outils d'édition comme couleur de remplissage des zones transparentes dans les PCX/GAF avant l'encodage ; pas transparent à l'exécution. |
16–95 |
Cycles de couleurs des joueurs | Le moteur les remplace selon le camp pour recolorer les unités. |
223–254 |
Réservés | Utilisés surtout par les cycles de couleurs d'équipe et les effets spéciaux. |
255 |
Blanc pur | Souvent utilisé pour le cœur des lasers. |
Note
Les 256 triplets RVB ne sont pas arbitraires. Cavedog a réglé la
palette à la main pour qu'il existe des dégradés réguliers pour chacune des
grandes familles de matériaux (métal, organique, eau, ciel, lave, …).
Remplacer des entrées pour y glisser une « nouvelle » couleur casse en
général toutes les unités qui puisaient dans ce dégradé. Voir la sortie de
pal describe pour les regroupements en dégradés.
.alp / .shd / .lht — tables de correspondance de couleurs
Ces trois fichiers ne sont pas des données RVB : chaque octet est un index de palette. Chaque table a une ligne de 256 entrées par partenaire de mélange ou par niveau, et ses colonnes sont les 256 couleurs sources :
| Fichier | Taille | Lignes | Entrée [r][c] |
|---|---|---|---|
.alp (alpha) |
65 536 | 256 | L'index le plus proche de la moyenne des couleurs r et c : un mélange moitié-moitié, utilisé pour le dessin translucide. Symétrique, et [c][c] vaut c. |
.shd (ombre) |
8 192 | 32 | L'index le plus proche de la couleur c multipliée par r × 0.06875 : la ligne 0 est noire, les lignes 14–15 laissent les couleurs presque inchangées, les lignes supérieures les éclaircissent. |
.lht (lumière) |
8 192 | 32 | L'index le plus proche de la couleur c multipliée par 1 + r/30, d'inchangée (ligne 0) à environ deux fois plus lumineuse. |
uint8 alp[256][256]; // blend = alp[a][b]
uint8 shd[32][256]; // shaded = shd[level][c]
uint8 lht[32][256]; // lit = lht[level][c]
En pratique, le moteur ne mélange jamais les couleurs par le calcul : il consulte une table, si bien que le pixel obtenu est toujours un vrai index de palette, dessinable par la chaîne 8 bpp existante. C'est pourquoi toutes les ombres de TA ressemblent à une version plus sombre du même dégradé de couleurs, et non à « 50 % de noir superposé » : chaque résultat ombré est l'index de palette le plus proche de ce mélange mathématique.
Le jeu n'utilise un fichier de table que si sa taille est exacte ; une table
absente, ou d'une autre taille, est reconstruite à partir de la palette.
kbot pal lookup rejette donc les fichiers de toute autre taille. TA:
Kingdoms livre des tables de mêmes tailles pour presque chaque palette de
son dossier palettes/ ; la plupart de ces palettes sont des fichiers PCX,
et kbot pal lookup --palette accepte un .pcx aussi bien qu'un .pal.
Important
Une table de correspondance n'est pas une palette. Afficher un .alp
avec kbot pal describe vous montrera des valeurs RVB absurdes, car les
octets ne sont pas du RVB. Utilisez kbot pal lookup pour voir ce qu'ils
font réellement — en passant le .pal associé pour que chaque case de la
table soit colorée avec l'entrée de palette vers laquelle elle se résout.
Exemple commenté — palette.pal
Les 16 premières entrées de la palette d'origine de TA :
| Idx | Hex | R V B | Rôle |
|---|---|---|---|
| 0 | #000000 |
0 0 0 | Noir (opaque dans le terrain ; la clé de certaines frames de sprites) |
| 1 | #800000 |
128 0 0 | Rouge foncé |
| 2 | #008000 |
0 128 0 | Vert foncé |
| 3 | #808000 |
128 128 0 | Olive |
| 4 | #000080 |
0 0 128 | Bleu foncé (ombre de l'eau) |
| 5 | #800080 |
128 0 128 | Magenta foncé |
| 6 | #008080 |
0 128 128 | Cyan foncé |
| 7 | #808080 |
128 128 128 | Gris moyen |
| 8 | #C0DCC0 |
192 220 192 | Vert pâle |
| 9 | #5454FC |
84 84 252 | « Rose magique » (transparence de l'éditeur) |
| 10–15 | #000000 × 6 |
0 0 0 | Remplissage réservé |
kbot pal describe palettes/palette.pal affiche la table complète.
Exemple commenté — palette.alp et palette.shd comme tables
Rendu des tables avec la palette comme source de couleurs
(kbot pal lookup … --cell 2) :
palette.alp : 256 × 256 cases. La ligne a, colonne b montre le mélange des couleurs a et b ;
la diagonale reproduit chaque couleur.
palette.shd : 256 × 32 cases. Chaque colonne est une couleur source ;
les lignes vont du noir (ligne 0) à des teintes plus claires, en passant par la couleur elle-même.
Lecture de la table des ombres : la colonne 80 (gris moyen) commence noire à
la ligne 0, remonte les gris plus sombres de son dégradé, atteint sa propre
couleur vers les lignes 14 et 15, puis s'éclaircit. Le moteur n'a jamais
besoin de multiplier des valeurs RVB : il lit simplement shd[level][c].
Convertir les palettes pour les éditeurs
kbot pal convert connaît plusieurs formats de sortie adaptés aux éditeurs :
| Format | Extension | Outil |
|---|---|---|
.PAL binaire de TA |
.pal |
Le format lui-même ; utile pour réécrire après modification. |
| Palette GIMP | .gpl |
GIMP, Krita, Inkscape. |
| JASC-PAL (texte) | .pal / .txt (--format jasc) |
Paint Shop Pro, Aseprite. |
| Nuancier PNG | .png (via kbot pal swatch) |
Référence visuelle ; ne se charge pas comme palette. |
Le sens inverse — importer un .gpl ou un .pal (JASC) dans un .pal
binaire de TA — fonctionne tant que la source a 256 entrées.
Note
La palette de TA contient 13 triplets RVB en double. Si votre éditeur
dédoublonne les couleurs à l'import (certains le font), vous perdrez des
entrées et la palette deviendra silencieusement une palette de 243 entrées.
kbot pal info indique le nombre de doublons pour que vous repériez la
différence ; faites un aller-retour par kbot pal convert -o roundtrip.pal
pour vérifier.
Pièges
Warning
Le 4e octet de chaque entrée n'est pas de l'alpha. C'est un octet de
remplissage inutilisé, que Cavedog a toujours mis à 0x00. Plusieurs
outils de palette open source le lisent comme de l'alpha, puis refusent
d'afficher la palette (alpha=0 partout ⇒ tout transparent). kbot l'ignore
à la lecture et écrit 0x00.
- L'index 0 n'est pas transparent en soi. Le terrain, les minicartes et les fonds le dessinent en noir ; une frame de sprite n'est transparente que là où sa propre clé (ou une plage sautée) l'indique. Les rendus de terrain et de minicarte de kbot utilisent une palette opaque.
- Pas de nombre magique, donc une validation faible. La seule façon de
vérifier un
.palest d'exiger au moins 1 024 octets et (éventuellement) que l'octet alpha soit nul dans chaque entrée. - Une table de correspondance de mauvaise taille est ignorée par le jeu et reconstruite à partir de la palette.
.alp/.lht/.shdne sont pas interchangeables. Ils sont réglés pour des effets différents ; les échanger produit des ombres ou un éclairage visiblement faux.- TA: Kingdoms utilise des palettes par camp intégrées à des PCX, et non
le fonctionnement par
.palglobal. Voir PCX pour l'astuce des PCX porteurs de palette.
Tailles typiques
| Fichier | Taille | Remarques |
|---|---|---|
palette.pal |
1 024 octets | Le jeu lit les 1 024 premiers octets d'un fichier plus long. |
palette.alp |
65 536 octets | 256 × 256 index de palette. |
palette.shd / palette.lht |
8 192 octets | 32 × 256 index de palette. |
Export GIMP .gpl |
~5 Ko | Format texte, bien plus gros que le binaire. |
Export JASC .pal (texte) |
~3 Ko | Idem. |
PNG de kbot pal swatch |
1–10 Ko | Dépend de la taille --cell. |
| Nombre total de fichiers de palette dans TA d'origine | ~15 fichiers | Un jeu palette.* de référence, plus quelques palettes d'interface alternatives. |