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 .smkLes outils Smacker génériques Format RAD standard. .zrbLa charge utile data/*.zrbde TACavedog a renommé les fichiers Smacker en .zrbpour 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
.bikaveckbot zrb: utilisez plutôtkbot bik. - Les arbres de Huffman du
SMK4ne sont pas rétrocompatibles avec les décodeursSMK2. 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↔.smkest sans danger, mais le jeu attend des.zrbdans le répertoiredata/. Ne fournissez pas au moteur de fichiers nommés en.smk.