Tutte le pagine dei formati ↓
Grafica e media

Smacker / ZRB — Filmati

Fonte: coreprime/kbot @ 0ab97bf · Modifica su GitHub

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
.smk Strumenti Smacker generici Formato RAD standard.
.zrb Il payload data/*.zrb di TA Cavedog ha rinominato i file Smacker in .zrb per 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 .bik con kbot zrb: usa invece kbot bik.
  • Gli alberi di Huffman di SMK4 non sono retrocompatibili con i decodificatori SMK2. 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 .zrb nella directory data/. Non dare al motore file con nomi .smk.

Vedi anche

  • Bink: il codec successore che TA: Kingdoms usa al posto di Smacker.
  • HPI: l'archivio contenitore con cui vengono distribuiti i file ZRB.
  • Glossario: frequenza dei frame (frame rate), firma (signature).