Усі сторінки форматів ↓
Графіка й медіа

Smacker / ZRB — відео заставок

Джерело: coreprime/kbot @ 0ab97bf · Редагувати на GitHub

Вступ, брифінги місій і фінальні ролики Total Annihilation — це відео RAD Game Tools Smacker. Вони зберігаються під двома різними розширеннями:

Розширення Де використовується Примітки
.smk Звичайні інструменти Smacker Стандартний формат RAD.
.zrb Дані data/*.zrb у TA Cavedog перейменувала файли Smacker на .zrb, щоб відбити охоту до випадкового видобування. Двійковий вміст ідентичний до байта.

FFmpeg декодує Smacker напряму, і kbot використовує його як рушій конвертації Smacker → MP4. У зворотний бік ніщо не конвертує: стандартний FFmpeg не має ні кодувальника, ні мультиплексора Smacker, а в kbot немає засобу запису Smacker. Ролики SMK2 для TA створюють інструментами Smacker від RAD Game Tools.

Tip

Спробуйте самі.

kbot zrb info     data/1.zrb               # header summary
kbot zrb to-mp4   data/1.zrb intro.mp4     # decode to a 640x480 MP4 (requires ffmpeg)
kbot zrb from-mp4 intro.mp4 out.zrb        # reports that no Smacker encoder exists

З Go. Скористайтеся пакетом formats/smacker:

import "github.com/coreprime/kbot/formats/smacker"

r, _ := smacker.OpenReader("data/1.zrb")
defer r.Close()
fmt.Println(r.Width(), r.Height(), r.FrameCount(), r.FrameRate())
_ = smacker.ConvertToMP4("data/1.zrb", "intro.mp4")

Що ви знайдете в інсталяції TA

$ ls $(kbot ctx path)/data/*.zrb
1.zrb  2.zrb  3.zrb  4.zrb  5.zrb

Кожен пронумерований файл — це ролик: оригінальна вступна послідовність «Arm vs Core», брифінги місій тощо. Кадри зберігаються в розмірі 640 × 240 зі встановленим прапорцем черезрядковості (interlaced), тож гра показує їх у 640 × 480, де кожен другий рядок чорний, із частотою 30 кадрів/с. kbot zrb to-mp4, MCP-інструмент zrb_to_mp4 і відеопрогравач студії (та його мініатюри) показують їх так само.


Заголовок (щонайменше 104 байти)

Заголовок Smacker містить сигнатуру, геометрію, кількість кадрів, налаштування звуку й розміри таблиць вказівників. Прочитати його нескладно, але тіло декодується на рівні бітів через дерева Гаффмана, тож kbot не береться за тіло й використовує FFmpeg.

typedef struct {
    uint32 Signature;        // 'SMK2' = 0x324B4D53 or 'SMK4' = 0x344B4D53
    uint32 Width;
    uint32 Height;
    uint32 Frames;
    int32  FrameRate;        // See below — sign-encoded
    uint32 Flags;
    uint32 AudioSize[7];
    uint32 TreesSize;        // Huffman tree section length
    uint32 MMapSize;
    uint32 MClrSize;
    uint32 FullSize;
    uint32 TypeSize;
    uint32 AudioRate[7];     // packed: rate in bits 0-23, flags in bits 24-31
    uint32 dummy;            // 4-byte reserved; the header ends here (104 bytes)
    // …followed by one entry per frame, plus one for the ring frame
    // when Flags bit 0 is set:
    uint32 FrameSizes[Frames (+1)];
    uint8  FrameTypes[Frames (+1)];
    uint8  HuffmanTrees[TreesSize];
} SmackerHeader;

Біти Flags: 0x01 — кільцевий кадр (ring frame; один додатковий кадр після останнього, для зациклення), 0x02 — черезрядковість (показується з подвоєною висотою, де кожен другий рядок чорний), 0x04 — подвоєння (показується з подвоєною висотою, де кожен рядок повторено). Якщо встановлено і 0x02, і 0x04, ролик показується зі збереженою висотою.

Декодування частоти кадрів

Знак FrameRate обирає одне з двох кодувань:

Значення Що означає
> 0 Мілісекунди на кадр: fps = 1000 / FrameRate.
< 0 Стотисячні частки секунди на кадр: fps = 100_000 / abs(FrameRate).
0 Час не визначено — kbot використовує 15 кадрів/с.

Для 30 кадрів/с зазвичай трапляється -3333 (≈ -100000/30).

Варіанти сигнатури

  • SMK2 — оригінальний формат Smacker. Його використовують майже всі ролики Cavedog.
  • SMK4 — розширений формат із покращеним стисненням, від новіших інструментів RAD. TA 3.1c відтворює лише SMK2.

kbot читає обидва (і позначає файл SMK4); FFmpeg декодує обидва.

Звукові доріжки

До 7 звукових доріжок. Кожне слово AudioRate[i] пакує частоту дискретизації (біти 0–23) і прапорці доріжки (біти 24–31): 0x80 — стиснена, 0x40 — присутня, 0x20 — 16-бітна (інакше 8-бітна), 0x10 — стерео (інакше моно). Гра використовує доріжку лише тоді, коли встановлено її біт присутності, хоч би якою була частота. Окремої таблиці прапорців немає: сім слів після заголовка — це таблиця розмірів кадрів.

Note

Файли ZRB від Cavedog мають одну доріжку в слоті 0: слово 0xD0005622 — присутня, 22 050 Гц, стерео, 8 бітів, стиснена. Решта шість слотів заповнено нулями. kbot zrb info і MCP-інструмент zrb_info перелічують лише присутні доріжки.


Міф про «зашифровані дані»

Серед моддерів поширене переконання, що файли .zrb — це зашифрований різновид Smacker. Це не так. Якщо перейменувати 1.zrb на 1.smk, його можна відтворити в будь-якому інструменті, що розуміє Smacker (інструменти RAD Bink/Smacker, FFmpeg, VLC). Єдиною обфускацією Cavedog було саме розширення.

# Equivalent — try both
ffplay data/1.zrb
cp data/1.zrb /tmp/intro.smk && ffplay /tmp/intro.smk

Конвеєри конвертації

kbot zrb to-mp4 читає заголовок, а потім доручає FFmpeg декодувати ролик у H.264 (CRF 18) і AAC так, як його показує гра: з висотою показу (черезрядковий ролик 640×240 стає 640×480, де кожен другий рядок чорний), із квадратними пікселями й зупинкою на кількості кадрів із заголовка (кільцевий кадр не показується).

Прапорець Дія
--line-double Заповнювати додаткові рядки черезрядкового ролика повторенням кожного збереженого рядка замість чорного.
--stored-height Зберегти збережену висоту кадру (640×240).

Відеопрогравач студії використовує ту саму конвертацію, а його мініатюри зберігають форму показу 4:3 (128×96, рядки подвоєно).

Important

Шляху MP4 → Smacker немає. Стандартний FFmpeg не має ні кодувальника Smacker (smackvid / smackaud), ні мультиплексора, а в kbot немає засобу запису Smacker. kbot zrb from-mp4 і MCP-інструмент zrb_from_mp4 повідомляють саме про це (і пробують FFmpeg лише тоді, коли той показує в списку і кодувальник smackvid, і мультиплексор smk). Ролики SMK2 для TA створюйте інструментами Smacker від RAD Game Tools.


Типові розміри

Ресурс Роздільність Кадри Тривалість Розмір файлу
Вступний ролик (data/1.zrb) 640 × 240 (показується 640 × 480) 599 ~20 с ~7 МБ
Інші ролики (data/2.zrb–5.zrb) 640 × 240 (показується 640 × 480) — — 10–41 МБ

Підводні камені

Warning

AudioRate — упаковане слово, а не частота. Якщо прочитати його як звичайне число, релізне слово 0xD0005622 дасть 3 489 682 978 «Гц». Для частоти виділіть маскою молодші 24 біти, а для присутності перевірте біт 0x40000000. Інструменти, що читають після заголовка ще сім слів «прапорців», насправді читають таблицю розмірів кадрів.

  • Smacker — це не Bink. RAD спершу випустила Smacker, а потім Bink як його наступника. TA використовує лише Smacker; TA: Kingdoms перейшла на Bink. Не завантажуйте файли .bik через kbot zrb — натомість використовуйте kbot bik.
  • Дерева Гаффмана SMK4 не сумісні з декодерами SMK2. FFmpeg обробляє обидва, але старіші сторонні бібліотеки можуть не впоратися.
  • Постачувані ролики зберігають -3333 (100 000 / 3 333 ≈ 30,003 кадру/с).
  • Збережена висота — не висота показу. Перевіряйте прапорці черезрядковості й подвоєння; якщо відтворювати релізні ролики в 640×240, вони сплющуються до половини висоти.
  • Перейменування .zrb ↔ .smk нешкідливе, але гра очікує .zrb у каталозі data/. Не постачайте рушію файли з іменами .smk.

Див. також

  • Bink — кодек-наступник, який TA: Kingdoms використовує замість Smacker.
  • HPI — архів-обгортка, у якому постачаються файли ZRB.
  • Глосарій — frame rate, signature.