PAL / ALP / LHT / SHD – Paletten und Farb-Nachschlagetabellen
Total Annihilation hat seine gesamte Welt in 256 Farben ausgeliefert. Die
.pal-Datei enthält diese Palette; die Dateien.alp,.shdund.lhtsind daraus abgeleitete Nachschlagetabellen, mit denen die Engine Pixel überblendet, abschattet und aufhellt, ohne den Raum der indizierten Farben zu verlassen.Keine der vier hat einen Header, ein Versionsfeld oder Kompression. Eine
.palist 1.024 Byte groß (256 × RGBx);.alphat 65.536 Byte (256 Zeilen mit je 256 Palettenindizes),.shd/.lhthaben je 8.192 Byte (32 Zeilen mit je 256 Palettenindizes).
palettes/palette.pal – gerendert mit kbot pal swatch
Tip
Probier es selbst.
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
Siehe die kbot pal-Referenz der CLI.
Aus Go heraus. Verwende 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)
}
Aufbau auf der Platte (.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
Es gibt weder Signatur noch Version. Das Spiel lädt
palettes/<name>.pal so (pal.LoadNamed aus kbot-io macht es genauso,
und Studio und Asset-Explorer laden palette.pal darüber für jedes
Rendering von TA: Kachelvorrat, Minikarten, Gelände der Sandbox,
Kartenobjekte, Texturen und Modellfarben):
- 1.024 Byte oder mehr: Die ersten 1.024 Byte sind die Palette; der Rest wird ignoriert.
- Leer oder fehlend: Die Palette kommt stattdessen aus
palettes/<name>.pcx– aus den letzten 768 Byte dieser Datei, ob ihnen nun ein Marker0x0Cvorausgeht oder nicht. TA 3.1c baut dann die Tabellen.alp,.shdund.lhtfür diese Farben neu auf. - 1 bis 1.023 Byte: nicht verwendbar; das Spiel liest 1.024 Byte über das Ende der Datei hinaus. kbot meldet einen Fehler (und das Studio greift auf die eingebaute Palette von TA zurück).
.pal – die kanonische Palette von TA
Die Bytes R, G, B, A pro Eintrag bedeuten wörtlich Rot, Grün,
Blau, unbenutzt. Index 0 ist gewöhnliches Schwarz.
Geländekacheln, Minikarten und Hintergründe zeichnen ihn deckend (62 der
275 Karten der Verkaufsversion verwenden ihn in ihren Kacheln). Über
Transparenz wird pro Bild entschieden, nicht durch die Palette: Das
Schlüsselbyte eines GAF-Frames (oft 9, manchmal 0) und seine
übersprungenen Pixel sind transparent, und Modelltexturen werden ohne
Schlüssel abgetastet.
| Index | Konvention in TA | Anmerkungen |
|---|---|---|
0 |
Schwarz | Deckend in Gelände, Minikarten und Hintergründen; transparent nur in Sprite-Frames, deren Schlüssel 0 ist. |
9 |
„Magic Pink“ | Wird von Editor-Werkzeugen vor dem Kodieren als Füllfarbe für transparente Bereiche in PCX/GAF verwendet; zur Laufzeit nicht transparent. |
16–95 |
Zyklen der Spielerfarben | Die Engine tauscht diese pro Seite aus, um Einheiten umzufärben. |
223–254 |
Reserviert | Meist von Zyklen der Teamfarben und Spezialeffekten verwendet. |
255 |
Reines Weiß | Oft für die Kerne von Laserstrahlen verwendet. |
Note
Die 256 RGB-Tripel sind nicht willkürlich. Cavedog hat die Palette
von Hand so abgestimmt, dass es für jede der wichtigen Materialfamilien
(Metall, Organisches, Wasser, Himmel, Lava, …) gleichmäßige Farbrampen
gibt. Einträge zu ersetzen, um eine „neue“ Farbe hineinzumodden, macht
meist jede Einheit kaputt, die aus dieser Farbrampe gezeichnet hat. Die
Gruppierung der Farbrampen zeigt die Ausgabe von pal describe.
.alp / .shd / .lht – Farb-Nachschlagetabellen
Diese drei Dateien sind keine RGB-Daten: Jedes Byte ist ein Palettenindex. Jede Tabelle hat eine Zeile mit 256 Einträgen pro Mischpartner oder Stufe, und ihre Spalten sind die 256 Ausgangsfarben:
| Datei | Größe | Zeilen | Eintrag [r][c] |
|---|---|---|---|
.alp (Alpha) |
65.536 | 256 | Der Index, der dem Mittelwert der Farben r und c am nächsten liegt: eine Mischung zu gleichen Teilen, verwendet für durchscheinendes Zeichnen. Symmetrisch, und [c][c] ist c. |
.shd (Schatten) |
8.192 | 32 | Der Index, der der Farbe c, skaliert mit r × 0.06875, am nächsten liegt: Zeile 0 ist schwarz, die Zeilen 14–15 lassen die Farben nahezu unverändert, höhere Zeilen hellen sie auf. |
.lht (Licht) |
8.192 | 32 | Der Index, der der Farbe c, skaliert mit 1 + r/30, am nächsten liegt, von unverändert (Zeile 0) bis etwa doppelt so hell. |
uint8 alp[256][256]; // blend = alp[a][b]
uint8 shd[32][256]; // shaded = shd[level][c]
uint8 lht[32][256]; // lit = lht[level][c]
In der Praxis heißt das: Die Engine mischt Farben nie arithmetisch – sie schlägt in einer Tabelle nach, das resultierende Pixel ist also immer ein echter Palettenindex, der durch die vorhandene 8-bpp-Pipeline gezeichnet werden kann. Deshalb sehen alle Schatten in TA wie eine dunklere Version derselben Farbrampe aus und nicht wie „50 % Schwarz darübergelegt“: Jedes abgeschattete Ergebnis ist der Palettenindex, der dieser mathematischen Mischung am nächsten kommt.
Das Spiel verwendet eine Tabellendatei nur, wenn ihre Größe exakt stimmt;
eine fehlende Tabelle oder eine mit irgendeiner anderen Größe wird aus der
Palette neu aufgebaut. kbot pal lookup weist deshalb Dateien jeder
anderen Größe ab. TA: Kingdoms liefert für fast jede Palette in seinem
Ordner palettes/ Tabellen derselben Größen aus; die meisten dieser
Paletten sind PCX-Dateien, und kbot pal lookup --palette nimmt eine
.pcx ebenso wie eine .pal.
Important
Eine Nachschlagetabelle ist keine Palette. Wenn du eine .alp mit
kbot pal describe renderst, siehst du unsinnige RGB-Werte, weil die
Bytes kein RGB sind. Mit kbot pal lookup siehst du, was sie
tatsächlich tun – übergib die zugehörige .pal, damit jede Zelle der
Tabelle mit dem Paletteneintrag eingefärbt werden kann, auf den sie
verweist.
Beispiel im Detail – palette.pal
Die ersten 16 Einträge der Originalpalette von TA:
| Idx | Hex | R G B | Rolle |
|---|---|---|---|
| 0 | #000000 |
0 0 0 | Schwarz (deckend im Gelände; der Schlüssel mancher Sprite-Frames) |
| 1 | #800000 |
128 0 0 | Dunkelrot |
| 2 | #008000 |
0 128 0 | Dunkelgrün |
| 3 | #808000 |
128 128 0 | Oliv |
| 4 | #000080 |
0 0 128 | Dunkelblau (Wasserschatten) |
| 5 | #800080 |
128 0 128 | Dunkelmagenta |
| 6 | #008080 |
0 128 128 | Dunkelcyan |
| 7 | #808080 |
128 128 128 | Mittelgrau |
| 8 | #C0DCC0 |
192 220 192 | Blassgrün |
| 9 | #5454FC |
84 84 252 | „Magic Pink“ (Transparenz im Editor) |
| 10–15 | #000000 × 6 |
0 0 0 | Reservierte Auffüllung |
kbot pal describe palettes/palette.pal gibt die vollständige Tabelle
aus.
Beispiel im Detail – palette.alp und palette.shd als Nachschlagetabellen
Die Tabellen, gerendert mit der Palette als Farbquelle
(kbot pal lookup … --cell 2):
palette.alp: 256 × 256 Zellen. Zeile a, Spalte b zeigt die Mischung der Farben a und b;
die Diagonale gibt jede Farbe selbst wieder.
palette.shd: 256 × 32 Zellen. Jede Spalte ist eine Ausgangsfarbe;
die Zeilen reichen von Schwarz (Zeile 0) über die Farbe selbst bis zu helleren Tönen.
So liest man die Schattentabelle: Spalte 80 (Mittelgrau) beginnt in
Zeile 0 schwarz, steigt durch dunklere Grautöne ihrer Farbrampe an,
erreicht sich selbst etwa in den Zeilen 14 und 15 und wird dann heller.
Die Engine muss nie RGB-Werte multiplizieren – sie liest einfach
shd[level][c].
Paletten für Editoren konvertieren
kbot pal convert beherrscht mehrere editorfreundliche Ausgabeformate:
| Format | Endung | Werkzeug |
|---|---|---|
Binäre .PAL von TA |
.pal |
Das Format selbst; nützlich, um nach Bearbeitungen neu auszugeben. |
| GIMP-Palette | .gpl |
GIMP, Krita, Inkscape. |
| JASC-PAL (Text) | .pal / .txt (--format jasc) |
Paint Shop Pro, Aseprite. |
| PNG-Farbtafel | .png (über kbot pal swatch) |
Visuelle Referenz; nicht als Palette ladbar. |
Die Gegenrichtung – eine .gpl oder .pal (JASC) wieder in eine binäre
.pal von TA importieren – funktioniert, solange die Quelle 256 Einträge
hat.
Note
Die Palette von TA enthält 13 doppelte RGB-Tripel. Wenn dein Editor
beim Import doppelte Farben entfernt (manche tun das), verlierst du
Einträge, und die Palette wird stillschweigend zu einer mit 243
Einträgen. kbot pal info meldet die Anzahl der Duplikate, damit du den
Unterschied bemerkst; mach zur Prüfung einen Round-Trip über
kbot pal convert -o roundtrip.pal.
Stolperfallen
Warning
Das 4. Byte pro Eintrag ist kein Alpha. Es ist ein unbenutztes
Füllbyte, das Cavedog immer auf 0x00 gesetzt hat. Mehrere
Open-Source-Werkzeuge für Paletten lesen es als Alpha und rendern die
Palette dann nicht (überall alpha=0 ⇒ alles transparent). kbot ignoriert
es beim Lesen und gibt beim Schreiben 0x00 aus.
- Index 0 ist nicht von sich aus transparent. Gelände, Minikarten und Hintergründe zeichnen ihn schwarz; ein Sprite-Frame ist nur dort transparent, wo sein eigener Schlüssel (oder Überspring-Lauf) es sagt. Die Gelände- und Minikarten-Renderings von kbot verwenden eine deckende Palette.
- Ohne Magic Numbers ist die Prüfung schwach. Die einzige
Plausibilitätsprüfung für eine
.palbesteht darin, mindestens 1.024 Byte zu verlangen und (optional), dass das Alpha-Byte in jedem Eintrag null ist. - Eine Nachschlagetabelle der falschen Größe ignoriert das Spiel und baut sie aus der Palette neu auf.
.alp/.lht/.shdsind nicht austauschbar. Sie sind auf unterschiedliche Effekte abgestimmt; vertauscht man sie, entstehen sichtbar falsche Schatten oder Aufhellungen.- TA: Kingdoms verwendet in PCX eingebettete Paletten pro Seite, nicht
den Weg über die globale
.pal. Den Trick mit dem Träger-PCX beschreibt PCX.
Typische Größen
| Datei | Größe | Anmerkungen |
|---|---|---|
palette.pal |
1.024 Byte | Von einer längeren Datei liest das Spiel die ersten 1.024 Byte. |
palette.alp |
65.536 Byte | 256 × 256 Palettenindizes. |
palette.shd / palette.lht |
8.192 Byte | 32 × 256 Palettenindizes. |
GIMP-Export .gpl |
~5 KB | Textformat, viel größer als binär. |
JASC-Export .pal (Text) |
~3 KB | Ebenso. |
PNG von kbot pal swatch |
1–10 KB | Hängt von der Größe --cell ab. |
| Palettendateien im Original-TA insgesamt | ~15 Dateien | Ein kanonischer Satz palette.* plus ein paar alternative Oberflächenpaletten. |