Smacker / ZRB — Filmati
L'introduzione, i briefing delle missioni e i filmati finali di Total Annihilation sono video Smacker di RAD Game Tools. Sono memorizzati con due estensioni diverse:
Estensione Usata da Note .smkStrumenti Smacker generici Formato RAD standard. .zrbIl payload data/*.zrbdi TACavedog ha rinominato i file Smacker in .zrbper scoraggiare i curiosi dall'estrarli. Il contenuto binario è identico byte per byte.FFmpeg decodifica nativamente lo Smacker, e kbot lo usa come motore di conversione da Smacker a MP4. Nella direzione opposta non converte niente: FFmpeg standard non ha un codificatore né un muxer Smacker, e kbot non ha un writer Smacker. I filmati SMK2 per TA si creano con gli strumenti Smacker di RAD Game Tools.
Tip
Provalo tu stesso.
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
Da Go. Usa 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")
Che cosa trovi in un'installazione di TA
$ ls $(kbot ctx path)/data/*.zrb
1.zrb 2.zrb 3.zrb 4.zrb 5.zrb
Ogni file numerato è un filmato: la sequenza introduttiva originale "Arm
contro Core", i briefing delle missioni, ecc. I frame sono memorizzati a
640 × 240 con il flag interlacciato impostato, quindi il gioco li
mostra a 640 × 480 con una riga nera ogni due, a 30 fps.
kbot zrb to-mp4, lo strumento MCP zrb_to_mp4 e il lettore video dello
studio (con le sue miniature) li mostrano allo stesso modo.
Intestazione (almeno 104 byte)
L'intestazione Smacker contiene una firma, la geometria, il numero di frame, la configurazione audio e le dimensioni delle tabelle dei puntatori. Leggerla è semplice, ma la decodifica del corpo si basa su alberi di Huffman a livello di bit, ed è per questo che kbot rinuncia al corpo e usa 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;
I bit di Flags: 0x01 ring frame (un frame in più dopo l'ultimo, per il
loop), 0x02 interlacciato (mostrato ad altezza doppia con una riga nera
ogni due), 0x04 raddoppiato (mostrato ad altezza doppia con ogni riga
ripetuta). Con sia 0x02 sia 0x04 impostati, il filmato viene mostrato
alla sua altezza memorizzata.
Decodificare la frequenza dei frame
Il segno di FrameRate sceglie tra due codifiche:
| Valore | Significato |
|---|---|
> 0 |
Millisecondi per frame: fps = 1000 / FrameRate. |
< 0 |
Centomillesimi di secondo per frame: fps = 100_000 / abs(FrameRate). |
0 |
Nessuna temporizzazione definita: kbot usa 15 fps. |
Per 30 fps di solito vedrai -3333 (≈ -100000/30).
Varianti della firma
SMK2: il formato Smacker originale. Lo usano quasi tutti i filmati di Cavedog.SMK4: formato esteso con una compressione migliorata, prodotto dagli strumenti RAD più recenti. TA 3.1c riproduce solo SMK2.
kbot legge entrambi (e segnala un file SMK4); FFmpeg li decodifica entrambi.
Tracce audio
Fino a 7 tracce audio. Ogni parola AudioRate[i] contiene la frequenza di
campionamento (bit 0–23) e i flag della traccia (bit 24–31): 0x80
compressa, 0x40 presente, 0x20 a 16 bit (altrimenti a 8 bit), 0x10
stereo (altrimenti mono). Il gioco usa una traccia solo quando il suo bit
di presenza è impostato, qualunque sia la frequenza. Non c'è una tabella
di flag separata: le sette parole dopo l'intestazione sono la tabella delle
dimensioni dei frame.
Note
I file ZRB di Cavedog hanno una sola traccia, nello slot 0: la parola
0xD0005622, cioè presente, 22.050 Hz, stereo, 8 bit, compressa. Gli
altri sei slot sono a zero. kbot zrb info e lo strumento MCP zrb_info
elencano solo le tracce presenti.
Il mito dei "dati cifrati"
Molti modder credono che i file .zrb siano una variante cifrata dello
Smacker. Non lo sono. Rinominando 1.zrb in 1.smk diventano
riproducibili con qualsiasi strumento che conosca lo Smacker (gli strumenti
Bink/Smacker di RAD, FFmpeg, VLC). L'unico offuscamento di Cavedog è stato
l'estensione stessa.
# Equivalent — try both
ffplay data/1.zrb
cp data/1.zrb /tmp/intro.smk && ffplay /tmp/intro.smk
Pipeline di conversione
kbot zrb to-mp4 legge l'intestazione, poi fa decodificare il filmato a
FFmpeg in H.264 (CRF 18) e AAC come lo mostra il gioco: all'altezza di
visualizzazione (un filmato interlacciato 640×240 diventa 640×480 con una
riga nera ogni due), con pixel quadrati, fermandosi al numero di frame
dell'intestazione (un ring frame non viene mostrato).
| Opzione | Effetto |
|---|---|
--line-double |
Riempie le righe aggiuntive di un filmato interlacciato ripetendo ogni riga memorizzata invece che con il nero. |
--stored-height |
Mantiene l'altezza memorizzata del frame (640×240). |
Il lettore video dello studio usa la stessa conversione, e le sue miniature mantengono la forma 4:3 di visualizzazione (128×96, righe raddoppiate).
Important
Non esiste un percorso MP4 → Smacker. FFmpeg standard non ha un
codificatore (smackvid / smackaud) né un muxer Smacker, e kbot non ha
un writer Smacker. kbot zrb from-mp4 e lo strumento MCP zrb_from_mp4
riportano esattamente questo (e provano FFmpeg solo quando elenca sia un
codificatore smackvid sia un muxer smk). Crea i filmati SMK2 per TA con
gli strumenti Smacker di RAD Game Tools.
Dimensioni tipiche
| Elemento | Risoluzione | Frame | Durata | Dimensione del file |
|---|---|---|---|---|
Filmato introduttivo (data/1.zrb) |
640 × 240 (mostrato a 640 × 480) | 599 | ~20 s | ~7 MB |
Altri filmati (data/2.zrb–5.zrb) |
640 × 240 (mostrato a 640 × 480) | — | — | 10–41 MB |
Insidie
Warning
AudioRate è una parola impacchettata, non una frequenza. Letta come
numero semplice, la parola originale 0xD0005622 vale 3.489.682.978 "Hz".
Maschera i 24 bit bassi per la frequenza e verifica il bit 0x40000000
per la presenza. Gli strumenti che leggono altre sette parole di "flag"
dopo l'intestazione stanno in realtà leggendo la tabella delle dimensioni
dei frame.
- Smacker non è Bink. RAD ha pubblicato prima Smacker, poi Bink come
suo successore. TA usa solo Smacker; TA: Kingdoms è passato a Bink. Non
caricare i file
.bikconkbot zrb: usa invecekbot bik. - Gli alberi di Huffman di
SMK4non sono retrocompatibili con i decodificatoriSMK2. FFmpeg gestisce entrambi, ma le librerie di terze parti più vecchie potrebbero non farlo. - I filmati distribuiti memorizzano
-3333(100.000 / 3.333 ≈ 30,003 fps). - L'altezza memorizzata non è l'altezza mostrata. Controlla i flag interlacciato e raddoppiato; riprodurre i filmati originali a 640×240 li schiaccia a metà altezza.
- Rinominare
.zrb↔.smkè innocuo, ma il gioco si aspetta.zrbnella directorydata/. Non dare al motore file con nomi.smk.