Toutes les pages de formats ↓
Graphismes et médias

Smacker / ZRB — vidéo des cinématiques

Source : coreprime/kbot @ 0ab97bf · Modifier sur GitHub

Les cinématiques d'introduction, de briefing de mission et de fin de Total Annihilation sont des vidéos Smacker de RAD Game Tools. Elles sont stockées sous deux extensions différentes :

Extension Utilisée par Remarques
.smk Les outils Smacker génériques Format RAD standard.
.zrb La charge utile data/*.zrb de TA Cavedog a renommé les fichiers Smacker en .zrb pour décourager l'extraction occasionnelle. Le contenu binaire est identique à l'octet près.

FFmpeg décode le Smacker nativement, et kbot s'en sert comme moteur de conversion Smacker → MP4. Rien ne convertit dans l'autre sens : FFmpeg standard n'a ni encodeur ni multiplexeur Smacker, et kbot n'a pas de module d'écriture Smacker. Les films SMK2 pour TA se fabriquent avec les outils Smacker de RAD Game Tools.

Tip

Essayez vous-même.

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

Depuis Go. Utilisez 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")

Ce que l'on trouve dans une installation de TA

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

Chaque fichier numéroté est une cinématique — la séquence d'introduction originale « Arm vs Core », les briefings de mission, etc. Les images sont stockées en 640 × 240 avec le flag entrelacé positionné : le jeu les affiche donc en 640 × 480, une ligne sur deux étant noire, à 30 i/s. kbot zrb to-mp4, l'outil MCP zrb_to_mp4 et le lecteur vidéo du studio (ainsi que ses vignettes) les affichent de la même façon.


En-tête (104 octets au minimum)

L'en-tête Smacker porte une signature, la géométrie, le nombre d'images, la configuration audio et la taille des tables de pointeurs. Le lire est simple, mais le décodage du corps repose sur des arbres de Huffman au niveau du bit, et c'est pourquoi kbot renonce à décoder le corps et utilise 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;

Bits de Flags : 0x01 image anneau (ring frame : une image supplémentaire après la dernière, pour boucler), 0x02 entrelacé (affiché à deux fois la hauteur, une ligne sur deux étant noire), 0x04 doublé (affiché à deux fois la hauteur, chaque ligne étant répétée). Avec 0x02 et 0x04 positionnés tous les deux, le film est affiché à sa hauteur stockée.

Décoder la cadence

Le signe de FrameRate choisit entre deux encodages :

Valeur Signification
> 0 Millisecondes par image : fps = 1000 / FrameRate.
< 0 Cent-millièmes de seconde par image : fps = 100_000 / abs(FrameRate).
0 Pas de cadence définie — kbot utilise 15 i/s.

Pour 30 i/s, on trouve en général -3333 (≈ -100000/30).

Variantes de signature

  • SMK2 — le format Smacker d'origine. Presque toutes les cinématiques de Cavedog l'utilisent.
  • SMK4 — un format étendu, à la compression améliorée, issu d'outils RAD plus récents. TA 3.1c ne lit que le SMK2.

kbot lit les deux (et signale un fichier SMK4) ; FFmpeg décode les deux.

Pistes audio

Jusqu'à 7 pistes audio. Chaque mot AudioRate[i] contient la fréquence d'échantillonnage (bits 0–23) et les flags de la piste (bits 24–31) : 0x80 compressée, 0x40 présente, 0x20 16 bits (sinon 8 bits), 0x10 stéréo (sinon mono). Le jeu n'utilise une piste que si son bit « présente » est positionné, quelle que soit sa fréquence. Il n'y a pas de table de flags séparée : les sept mots qui suivent l'en-tête forment la table des tailles d'images.

Note

Les fichiers ZRB de Cavedog ont une seule piste, dans l'emplacement 0 : le mot 0xD0005622 — présente, 22 050 Hz, stéréo, 8 bits, compressée. Les six autres emplacements sont à zéro. kbot zrb info et l'outil MCP zrb_info ne listent que les pistes présentes.


Le mythe des « données chiffrées »

Beaucoup de moddeurs croient que les fichiers .zrb sont une variante chiffrée du Smacker. Ce n'est pas le cas. Renommer 1.zrb en 1.smk suffit à les rendre lisibles par n'importe quel outil qui connaît le Smacker (outils Bink/Smacker de RAD, FFmpeg, VLC). La seule dissimulation de Cavedog était l'extension elle-même.

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

Chaînes de conversion

kbot zrb to-mp4 lit l'en-tête, puis fait décoder le film par FFmpeg en H.264 (CRF 18) et AAC tel que le jeu l'affiche : à la hauteur d'affichage (un film entrelacé de 640×240 devient du 640×480, une ligne sur deux étant noire), avec des pixels carrés, en s'arrêtant au nombre d'images indiqué dans l'en-tête (une image anneau n'est pas affichée).

Option Effet
--line-double Remplit les lignes supplémentaires d'un film entrelacé en répétant chaque ligne stockée, au lieu de les laisser noires.
--stored-height Conserve la hauteur d'image stockée (640×240).

Le lecteur vidéo du studio utilise la même conversion, et ses vignettes conservent les proportions d'affichage 4:3 (128×96, lignes doublées).

Important

Il n'existe pas de chemin MP4 → Smacker. FFmpeg standard n'a ni encodeur Smacker (smackvid / smackaud) ni multiplexeur, et kbot n'a pas de module d'écriture Smacker. kbot zrb from-mp4 et l'outil MCP zrb_from_mp4 le signalent exactement (et n'essaient FFmpeg que s'il liste à la fois un encodeur smackvid et un multiplexeur smk). Fabriquez les films SMK2 pour TA avec les outils Smacker de RAD Game Tools.


Tailles typiques

Ressource Résolution Images Durée Taille du fichier
Cinématique d'introduction (data/1.zrb) 640 × 240 (affichée en 640 × 480) 599 ~20 s ~7 Mo
Autres cinématiques (data/2.zrb–5.zrb) 640 × 240 (affichées en 640 × 480) — — 10–41 Mo

Pièges

Warning

AudioRate est un mot compacté, pas une fréquence. Lu comme un simple nombre, le mot d'origine 0xD0005622 vaut 3 489 682 978 « Hz ». Masquez les 24 bits de poids faible pour obtenir la fréquence, et testez le bit 0x40000000 pour la présence. Les outils qui lisent sept mots de « flags » supplémentaires après l'en-tête lisent en fait la table des tailles d'images.

  • Le Smacker n'est pas le Bink. RAD a d'abord sorti Smacker, puis Bink pour lui succéder. TA n'utilise que Smacker ; TA: Kingdoms est passé à Bink. Ne chargez pas de fichiers .bik avec kbot zrb : utilisez plutôt kbot bik.
  • Les arbres de Huffman du SMK4 ne sont pas rétrocompatibles avec les décodeurs SMK2. FFmpeg gère les deux, mais d'anciennes bibliothèques tierces peuvent ne pas le faire.
  • Les cinématiques livrées stockent -3333 (100 000 / 3 333 ≈ 30,003 i/s).
  • La hauteur stockée n'est pas la hauteur affichée. Vérifiez les flags entrelacé et doublé ; lire les films d'origine en 640×240 les écrase à la moitié de leur hauteur.
  • Renommer .zrb ↔ .smk est sans danger, mais le jeu attend des .zrb dans le répertoire data/. Ne fournissez pas au moteur de fichiers nommés en .smk.

Voir aussi

  • Bink — le codec successeur que TA: Kingdoms utilise à la place de Smacker.
  • HPI — l'archive enveloppe qui livre les fichiers ZRB.
  • Glossaire — cadence, signature.