Todas las páginas de formatos ↓
Gráficos y multimedia

PAL / ALP / LHT / SHD: paletas y tablas de consulta de color

Fuente: coreprime/kbot @ 0ab97bf · Editar en GitHub

Total Annihilation distribuyó todo su mundo en 256 colores. El archivo .pal contiene esa paleta; los archivos .alp, .shd y .lht son tablas de consulta construidas a partir de ella que el motor usa para mezclar, sombrear e iluminar píxeles sin salir del espacio de color indexado.

Ninguno de los cuatro tiene cabecera, campo de versión ni compresión. Un .pal ocupa 1024 bytes (256 × RGBx); un .alp, 65 536 bytes (256 filas de 256 índices de la paleta), y .shd / .lht, 8192 bytes cada uno (32 filas de 256 índices de la paleta).

Muestrario de la paleta de TA (256 colores, celdas de 24 px)
palettes/palette.pal, renderizada con kbot pal swatch

Tip

Pruébalo tú mismo.

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

Consulta la referencia de kbot pal de la CLI.

Desde Go. Usa 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)
}

Estructura en disco (.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

No hay firma ni versión. El juego carga palettes/<name>.pal así (el pal.LoadNamed de kbot-io hace lo mismo, y el studio y el explorador de recursos cargan palette.pal a través de él en todos los renderizados de TA: pool de casillas, minimapas, terreno del sandbox, elementos, texturas y colores de los modelos):

  • 1024 bytes o más: los primeros 1024 bytes son la paleta; el resto se ignora.
  • Vacío o ausente: la paleta se toma de palettes/<name>.pcx: los últimos 768 bytes de ese archivo, vaya o no precedidos de una marca 0x0C. Después, TA 3.1c reconstruye las tablas .alp, .shd y .lht para esos colores.
  • De 1 a 1023 bytes: no sirve; el juego lee 1024 bytes y se sale del final del archivo. kbot da un error (y el studio recurre a la paleta de TA integrada).

.pal: la paleta canónica de TA

Los bytes R, G, B, A de cada entrada significan literalmente rojo, verde, azul, sin uso. El índice 0 es un negro normal. Las casillas del terreno, los minimapas y los fondos lo dibujan opaco (62 de los 275 mapas de la versión comercial lo usan en sus casillas). La transparencia se decide en cada imagen, no en la paleta: el byte clave de un fotograma GAF (a menudo 9, a veces 0) y sus píxeles saltados son transparentes, y las texturas de los modelos se muestrean sin color clave.

Índice Convención de TA Notas
0 Negro Opaco en el terreno, los minimapas y los fondos; transparente solo en los fotogramas de sprite cuyo color clave es 0.
9 «Rosa mágico» Las herramientas de edición lo usan como color de relleno de las zonas transparentes en PCX/GAF antes de codificar; no es transparente durante la partida.
16–95 Ciclos de color de jugador El motor los cambia según el bando para recolorear las unidades.
223–254 Reservado Los usan sobre todo los ciclos de color de equipo y los efectos especiales.
255 Blanco puro Se usa a menudo para el núcleo de los láseres.

Note

Los 256 tripletes RGB no son arbitrarios. Cavedog ajustó la paleta a mano para que hubiera rampas suaves en cada una de las grandes familias de materiales (metal, orgánico, agua, cielo, lava, …). Sustituir entradas para meter un color «nuevo» en un mod suele estropear todas las unidades que tomaban colores de esa rampa. Consulta la salida de pal describe para ver cómo se agrupan las rampas.


.alp / .shd / .lht: tablas de consulta de color

Estos tres archivos no son datos RGB: cada byte es un índice de la paleta. Cada tabla tiene una fila de 256 entradas por cada color con el que se mezcla o por cada nivel, y sus columnas son los 256 colores de origen:

Archivo Tamaño Filas Entrada [r][c]
.alp (alfa) 65 536 256 El índice más cercano a la media de los colores r y c: una mezcla a partes iguales, que se usa para dibujar con translucidez. Es simétrica, y [c][c] es c.
.shd (sombra) 8192 32 El índice más cercano al color c escalado por r × 0.06875: la fila 0 es negra, las filas 14–15 dejan los colores casi sin cambios y las filas superiores los aclaran.
.lht (luz) 8192 32 El índice más cercano al color c escalado por 1 + r/30, desde sin cambios (fila 0) hasta aproximadamente el doble de brillante.
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 la práctica: el motor nunca mezcla colores aritméticamente, sino que consulta una tabla, así que el píxel resultante es siempre un índice real de la paleta que se puede dibujar con el proceso de 8 bpp existente. Por eso todas las sombras de TA parecen una versión más oscura de la misma rampa de color, y no «negro al 50 % superpuesto»: cada resultado sombreado es el índice de la paleta más cercano a esa mezcla matemática.

El juego solo usa un archivo de tabla cuando su tamaño es exacto; una tabla que falta o que tiene cualquier otro tamaño se reconstruye a partir de la paleta. Por eso kbot pal lookup rechaza los archivos de cualquier otro tamaño. TA: Kingdoms distribuye tablas de los mismos tamaños para casi todas las paletas de su carpeta palettes/; la mayoría de esas paletas son archivos PCX, y kbot pal lookup --palette acepta tanto un .pcx como un .pal.

Important

Una tabla de consulta no es una paleta. Si renderizas un .alp con kbot pal describe verás valores RGB sin sentido, porque los bytes no son RGB. Usa kbot pal lookup para ver lo que hacen de verdad: pásale el .pal que la acompaña para que cada celda de consulta se pueda colorear con la entrada de la paleta a la que se resuelve.


Ejemplo desarrollado: palette.pal

Las 16 primeras entradas de la paleta original de TA:

Índ. Hex R G B Papel
0 #000000 0 0 0 Negro (opaco en el terreno; el color clave de algunos fotogramas de sprite)
1 #800000 128 0 0 Rojo oscuro
2 #008000 0 128 0 Verde oscuro
3 #808000 128 128 0 Oliva
4 #000080 0 0 128 Azul oscuro (sombra del agua)
5 #800080 128 0 128 Magenta oscuro
6 #008080 0 128 128 Cian oscuro
7 #808080 128 128 128 Gris medio
8 #C0DCC0 192 220 192 Verde pálido
9 #5454FC 84 84 252 «Rosa mágico» (transparencia del editor)
10–15 #000000 × 6 0 0 0 Relleno reservado

kbot pal describe palettes/palette.pal imprime la tabla completa.


Ejemplo desarrollado: palette.alp y palette.shd como tablas de consulta

Las tablas renderizadas con la paleta como fuente de color (kbot pal lookup … --cell 2):

palette.alp visualizada a través de palette.pal
palette.alp: 256 × 256 celdas. La fila a, columna b muestra la mezcla de los colores a y b;
la diagonal reproduce cada color.

palette.shd visualizada a través de palette.pal
palette.shd: 256 × 32 celdas. Cada columna es un color de origen;
las filas van del negro (fila 0), pasando por el propio color, hasta tonos más claros.

Cómo leer la tabla de sombras: la columna 80 (gris medio) empieza en negro en la fila 0, sube por los grises más oscuros de su rampa, llega a sí misma hacia las filas 14 y 15 y después se aclara. El motor nunca necesita multiplicar valores RGB: solo lee shd[level][c].


Convertir paletas para los editores

kbot pal convert entiende varios formatos de salida cómodos para los editores:

Formato Extensión Herramienta
.PAL binario de TA .pal El propio formato; útil para volver a generarlo tras editarlo.
GIMP Palette .gpl GIMP, Krita, Inkscape.
JASC-PAL (texto) .pal / .txt (--format jasc) Paint Shop Pro, Aseprite.
Muestrario PNG .png (con kbot pal swatch) Referencia visual; no se puede cargar como paleta.

La dirección contraria (importar un .gpl o un .pal JASC de vuelta a un .pal binario de TA) funciona siempre que el origen tenga 256 entradas.

Note

La paleta de TA tiene 13 tripletes RGB duplicados. Si tu editor elimina los colores duplicados al importar (algunos lo hacen), perderás entradas y la paleta pasará sin avisar a tener 243 entradas. kbot pal info indica cuántos duplicados hay para que puedas detectar la diferencia; haz el viaje de ida y vuelta con kbot pal convert -o roundtrip.pal para comprobarlo.


Escollos

Warning

El 4.º byte de cada entrada no es alfa. Es un byte de relleno sin uso que Cavedog siempre ponía a 0x00. Varias herramientas de paletas de código abierto lo leen como alfa y luego no consiguen renderizar la paleta (alfa=0 en todas partes ⇒ todo transparente). kbot lo ignora al leer y escribe 0x00 al generar.

  • El índice 0 no es transparente por sí mismo. El terreno, los minimapas y los fondos lo dibujan negro; un fotograma de sprite solo es transparente donde lo indica su propio color clave (o un tramo de salto). Los renderizados de terreno y minimapa de kbot usan una paleta opaca.
  • Sin números mágicos, la validación es débil. La única forma de comprobar que un .pal es razonable es exigir al menos 1024 bytes y (opcionalmente) que el byte alfa sea cero en todas las entradas.
  • El juego ignora una tabla de consulta de tamaño incorrecto y la reconstruye a partir de la paleta.
  • .alp / .lht / .shd no son intercambiables. Están ajustadas para efectos distintos; si las intercambias, obtendrás sombras o iluminación visiblemente incorrectas.
  • TA: Kingdoms usa paletas por bando incrustadas en PCX, no el sistema del .pal global. Consulta PCX para ver el truco del PCX portador.

Tamaños habituales

Archivo Tamaño Notas
palette.pal 1024 bytes De un archivo más largo, el juego lee los primeros 1024 bytes.
palette.alp 65 536 bytes 256 × 256 índices de la paleta.
palette.shd / palette.lht 8192 bytes 32 × 256 índices de la paleta.
Exportación .gpl de GIMP ~5 KB Formato de texto, mucho más grande que el binario.
Exportación .pal JASC (texto) ~3 KB Lo mismo.
PNG de kbot pal swatch 1–10 KB Depende del tamaño de --cell.
Total de archivos de paleta en TA original ~15 archivos Un conjunto canónico palette.* más unas cuantas paletas alternativas de la interfaz.

Véase también

  • PCX: archivos con paletas incrustadas (y la convención de PCX portadores de paleta de TA:K).
  • GAF: animaciones que usan una paleta pero no la incluyen.
  • TNT, SCT: datos de casillas con paleta en disco.
  • Glosario: paletted image, lookup table.