Smacker / ZRB — відео заставок
Джерело: coreprime/kbot @ 0ab97bf · Редагувати на GitHub
Вступ, брифінги місій і фінальні ролики Total Annihilation — це відео RAD Game Tools Smacker. Вони зберігаються під двома різними розширеннями:
Розширення Де використовується Примітки .smkЗвичайні інструменти Smacker Стандартний формат RAD. .zrbДані data/*.zrbу TACavedog перейменувала файли 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.