Все страницы форматов ↓
Графика и медиа

PAL / ALP / LHT / SHD — палитры и таблицы поиска цветов

Источник: coreprime/kbot @ 0ab97bf · Редактировать на GitHub

Весь мир Total Annihilation нарисован в 256 цветах. Эту палитру хранит файл .pal, а файлы .alp, .shd и .lht — построенные на её основе таблицы поиска, с помощью которых движок смешивает, затеняет и освещает пиксели, не выходя из пространства индексированных цветов.

Ни у одного из четырёх нет заголовка, поля версии или сжатия. Файл .pal занимает 1 024 байта (256 × RGBx), .alp — 65 536 байт (256 строк по 256 индексов палитры), а .shd / .lht — по 8 192 байта (32 строки по 256 индексов палитры).

Образцы палитры TA (256 цветов, ячейки 24 пикселя)
palettes/palette.pal — отрисовка командой kbot pal swatch

Tip

Попробуйте сами.

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

См. справку по kbot pal в описании командной строки.

Из Go. Используйте 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)
}

Устройство на диске (.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

Ни сигнатуры, ни версии нет. Игра загружает palettes/<name>.pal так (pal.LoadNamed из kbot-io делает то же самое, и через него студия и обозреватель ресурсов загружают palette.pal для любой отрисовки TA: набора тайлов, миникарт, рельефа в песочнице, объектов, текстур и цветов моделей):

  • 1 024 байта или больше: первые 1 024 байта — палитра, остальное игнорируется.
  • Пустой или отсутствует: палитра берётся из palettes/<name>.pcx — последние 768 байт этого файла, независимо от того, стоит ли перед ними маркер 0x0C. Затем TA 3.1c заново строит таблицы .alp, .shd и .lht для этих цветов.
  • От 1 до 1 023 байт: непригоден; игра читает 1 024 байта, выходя за конец файла. kbot сообщает об ошибке (а студия переходит на встроенную палитру TA).

.pal — каноническая палитра TA

Байты R, G, B, A каждой записи буквально означают красный, зелёный, синий, не используется. Индекс 0 — обычный чёрный. Тайлы рельефа, миникарты и фоны рисуют его непрозрачным (62 из 275 оригинальных карт используют его в своих тайлах). Прозрачность решается для каждого изображения отдельно, а не палитрой: прозрачны байт ключевого цвета кадра GAF (часто 9, иногда 0) и его пропущенные пиксели, а текстуры моделей выбираются без ключевого цвета.

Индекс Соглашение TA Примечания
0 Чёрный Непрозрачен в рельефе, миникартах и фонах; прозрачен только в кадрах спрайтов с ключевым цветом 0.
9 «Волшебный розовый» Инструменты редактирования заливают им прозрачные области в PCX/GAF перед кодированием; во время игры не прозрачен.
16–95 Циклы цветов игроков Движок подменяет их для каждой стороны, чтобы перекрашивать юниты.
223–254 Зарезервированы В основном используются циклами командных цветов и спецэффектами.
255 Чистый белый Часто используется для сердцевины лазерных лучей.

Note

256 троек RGB выбраны не случайно. Cavedog вручную настроила палитру так, чтобы для каждого основного семейства материалов (металл, органика, вода, небо, лава, …) были плавные градиенты. Если заменить записи, чтобы добавить «новый» цвет, обычно ломается каждый юнит, который брал цвета из этого градиента. Группы градиентов показывает вывод pal describe.


.alp / .shd / .lht — таблицы поиска цветов

Эти три файла не содержат данных RGB: каждый байт — индекс палитры. В каждой таблице одна строка из 256 записей на каждого партнёра по смешиванию или уровень, а столбцы — это 256 исходных цветов:

Файл Размер Строк Запись [r][c]
.alp (alpha) 65 536 256 Индекс, ближайший к среднему цветов r и c: смесь пополам, используется для полупрозрачной отрисовки. Таблица симметрична, и [c][c] равно c.
.shd (shade) 8 192 32 Индекс, ближайший к цвету c, умноженному на r × 0.06875: строка 0 — чёрная, строки 14–15 почти не меняют цвета, более высокие строки делают их ярче.
.lht (light) 8 192 32 Индекс, ближайший к цвету c, умноженному на 1 + r/30, — от неизменного (строка 0) до примерно вдвое более яркого.
uint8 alp[256][256];   // blend = alp[a][b]
uint8 shd[32][256];    // shaded = shd[level][c]
uint8 lht[32][256];    // lit    = lht[level][c]

На практике движок никогда не смешивает цвета арифметически — он выполняет поиск по таблице, поэтому итоговый пиксель — всегда настоящий индекс палитры, который можно нарисовать через существующий 8-битный конвейер. Вот почему все тени в TA выглядят как более тёмная версия того же градиента, а не как «50% чёрного поверх»: каждый затенённый результат — это индекс палитры, ближайший к математической смеси.

Игра использует файл таблицы, только если его размер точно совпадает; отсутствующая таблица или таблица любого другого размера строится заново из палитры. Поэтому kbot pal lookup отвергает файлы любого другого размера. TA: Kingdoms поставляет таблицы тех же размеров почти для каждой палитры в своей папке palettes/; большинство этих палитр — файлы PCX, и kbot pal lookup --palette принимает как .pal, так и .pcx.

Important

Таблица поиска — это не палитра. Если отрисовать .alp через kbot pal describe, вы увидите бессмысленные значения RGB, потому что байты — не RGB. Чтобы увидеть, что таблица делает на самом деле, используйте kbot pal lookup — передайте парный .pal, чтобы каждую ячейку можно было окрасить в цвет записи палитры, на которую она указывает.


Разбор примера — palette.pal

Первые 16 записей стандартной палитры TA:

Инд. Hex R G B Роль
0 #000000 0 0 0 Чёрный (непрозрачен в рельефе; ключевой цвет некоторых кадров спрайтов)
1 #800000 128 0 0 Тёмно-красный
2 #008000 0 128 0 Тёмно-зелёный
3 #808000 128 128 0 Оливковый
4 #000080 0 0 128 Тёмно-синий (тень воды)
5 #800080 128 0 128 Тёмно-пурпурный
6 #008080 0 128 128 Тёмно-бирюзовый
7 #808080 128 128 128 Средне-серый
8 #C0DCC0 192 220 192 Бледно-зелёный
9 #5454FC 84 84 252 «Волшебный розовый» (прозрачность в редакторах)
10–15 #000000 × 6 0 0 0 Зарезервированное заполнение

kbot pal describe palettes/palette.pal выводит всю таблицу.


Разбор примера — palette.alp и palette.shd как таблицы поиска

Отрисовка таблиц с палитрой в качестве источника цветов (kbot pal lookup … --cell 2):

palette.alp, показанная через palette.pal
palette.alp: 256 × 256 ячеек. Строка a, столбец b показывают смесь цветов a и b;
диагональ воспроизводит каждый цвет.

palette.shd, показанная через palette.pal
palette.shd: 256 × 32 ячейки. Каждый столбец — исходный цвет;
строки идут от чёрного (строка 0) через сам цвет к более ярким оттенкам.

Как читать таблицу оттенков: столбец 80 (средне-серый) начинается с чёрного в строке 0, поднимается через более тёмные серые своего градиента, примерно в строках 14 и 15 доходит до самого себя, а затем светлеет. Движку никогда не нужно умножать значения RGB — он просто читает shd[level][c].


Преобразование палитр для редакторов

kbot pal convert понимает несколько удобных для редакторов выходных форматов:

Формат Расширение Инструмент
Двоичный .PAL TA .pal Сам формат; пригодится, чтобы записать файл заново после правок.
GIMP Palette .gpl GIMP, Krita, Inkscape.
JASC-PAL (текст) .pal / .txt (--format jasc) Paint Shop Pro, Aseprite.
Образцы в PNG .png (через kbot pal swatch) Наглядная справка; как палитру не загрузить.

Обратное направление — импорт .gpl или .pal (JASC) обратно в двоичный .pal TA — работает, если в исходнике 256 записей.

Note

В палитре TA 13 повторяющихся троек RGB. Если ваш редактор при импорте удаляет повторяющиеся цвета (некоторые так делают), записи пропадут, и палитра незаметно превратится в палитру на 243 записи. kbot pal info сообщает число повторов, чтобы разницу можно было заметить; для проверки прогоните палитру туда и обратно через kbot pal convert -o roundtrip.pal.


Подводные камни

Warning

Четвёртый байт записи — не альфа-канал. Это неиспользуемый байт заполнения, который Cavedog всегда ставила в 0x00. Некоторые открытые инструменты для палитр читают его как альфу и потом отказываются отображать палитру (alpha=0 везде ⇒ всё прозрачно). kbot игнорирует его при чтении и записывает 0x00.

  • Индекс 0 сам по себе не прозрачен. Рельеф, миникарты и фоны рисуют его чёрным; кадр спрайта прозрачен только там, где это говорит его собственный ключевой цвет (или серия пропусков). Отрисовка рельефа и миникарт в kbot использует непрозрачную палитру.
  • Без магических чисел проверка слабая. Единственный способ убедиться в правдоподобности .pal — потребовать не меньше 1024 байт и (по желанию) чтобы байт альфы был нулевым в каждой записи.
  • Таблицу поиска неправильного размера игра игнорирует и строит заново из палитры.
  • .alp / .lht / .shd не взаимозаменяемы. Они настроены на разные эффекты; если поменять их местами, тени или освещение будут заметно неправильными.
  • TA: Kingdoms использует палитры сторон, встроенные в PCX, а не схему с глобальным .pal. Приём с PCX-носителем описан в PCX.

Типичные размеры

Файл Размер Примечания
palette.pal 1 024 байта Из более длинного файла игра читает первые 1 024 байта.
palette.alp 65 536 байт 256 × 256 индексов палитры.
palette.shd / palette.lht 8 192 байта 32 × 256 индексов палитры.
Экспорт GIMP .gpl ~5 КБ Текстовый формат, намного больше двоичного.
Экспорт JASC .pal (текст) ~3 КБ То же.
PNG из kbot pal swatch 1–10 КБ Зависит от размера --cell.
Всего файлов палитр в стандартной TA ~15 файлов Один канонический набор palette.* и несколько дополнительных палитр интерфейса.

См. также

  • PCX — файлы со встроенными палитрами (и соглашение TA:K о носителях палитр).
  • GAF — анимации, которые используют палитру, но не содержат её.
  • TNT, SCT — данные тайлов с палитрой на диске.
  • Глоссарий — paletted image (изображение с палитрой), lookup table (таблица поиска).