Todas as páginas de formatos ↓
Gráficos e multimédia

Smacker / ZRB — vídeo das cinemáticas

Fonte: coreprime/kbot @ 0ab97bf · Editar no GitHub

A introdução, os briefings das missões e as cinemáticas finais do Total Annihilation são vídeos Smacker da RAD Game Tools. Estão guardados com duas extensões diferentes:

Extensão Usada por Notas
.smk Ferramentas Smacker genéricas Formato RAD normal.
.zrb O payload data/*.zrb do TA A Cavedog mudou a extensão dos ficheiros Smacker para .zrb para desencorajar a extração casual. O conteúdo binário é idêntico byte a byte.

O FFmpeg descodifica Smacker nativamente, e o kbot usa-o como motor de conversão de Smacker → MP4. Nada converte no sentido inverso: o FFmpeg normal não tem codificador nem multiplexador (muxer) de Smacker, e o kbot não tem escritor de Smacker. Os filmes SMK2 para o TA fazem-se com as ferramentas Smacker da RAD Game Tools.

Tip

Experimente por si.

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

A partir de Go. Use 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")

O que encontra numa instalação do TA

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

Cada ficheiro numerado é uma cinemática: a sequência de introdução original "Arm vs Core", os briefings das missões, etc. Os fotogramas estão guardados a 640 × 240 com a flag de entrelaçado definida, por isso o jogo mostra-os a 640 × 480, com uma linha preta a cada duas, a 30 fps. O kbot zrb to-mp4, a ferramenta MCP zrb_to_mp4 e o leitor de vídeo do estúdio (e as suas miniaturas) mostram-nos da mesma forma.


Cabeçalho (104 bytes no mínimo)

O cabeçalho Smacker contém uma assinatura, a geometria, as contagens de fotogramas, a configuração do áudio e os tamanhos das tabelas de ponteiros. Lê-lo é simples, mas a descodificação do corpo assenta em árvores de Huffman ao nível do bit, e é por isso que o kbot não trata do corpo e recorre ao 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 fotograma de anel (um fotograma extra depois do último, para a repetição em ciclo), 0x02 entrelaçado (mostrado com o dobro da altura, com uma linha preta a cada duas), 0x04 duplicado (mostrado com o dobro da altura, com cada linha repetida). Com 0x02 e 0x04 definidos ao mesmo tempo, o filme é mostrado com a altura guardada.

Descodificar a taxa de fotogramas

O sinal de FrameRate escolhe entre duas codificações:

Valor Significado
> 0 Milissegundos por fotograma: fps = 1000 / FrameRate.
< 0 Cem-milésimos de segundo por fotograma: fps = 100_000 / abs(FrameRate).
0 Sem temporização definida: o kbot usa 15 fps.

Para 30 fps, vê-se normalmente -3333 (≈ -100000/30).

Variantes da assinatura

  • SMK2 — o formato Smacker original. Quase todas as cinemáticas da Cavedog o usam.
  • SMK4 — formato alargado com melhor compressão, das ferramentas mais recentes da RAD. O TA 3.1c só reproduz SMK2.

O kbot lê os dois (e assinala um ficheiro SMK4); o FFmpeg descodifica os dois.

Faixas de áudio

Até 7 faixas de áudio. Cada palavra AudioRate[i] junta a frequência de amostragem (bits 0–23) e as flags da faixa (bits 24–31): 0x80 comprimida, 0x40 presente, 0x20 16 bits (senão 8 bits), 0x10 estéreo (senão mono). O jogo só usa uma faixa quando o seu bit de presença está definido, seja qual for a frequência. Não há uma tabela de flags separada: as sete palavras a seguir ao cabeçalho são a tabela de tamanhos dos fotogramas.

Note

Os ficheiros ZRB da Cavedog têm uma única faixa, na posição 0: a palavra 0xD0005622, ou seja, presente, 22 050 Hz, estéreo, 8 bits, comprimida. As outras seis posições estão a zero. O kbot zrb info e a ferramenta MCP zrb_info só listam as faixas presentes.


O mito dos "dados cifrados"

Muitos modders acreditam que os ficheiros .zrb são uma variante cifrada do Smacker. Não são. Mudar o nome de 1.zrb para 1.smk torna-os reproduzíveis em qualquer ferramenta que conheça o Smacker (as ferramentas Bink/Smacker da RAD, o FFmpeg, o VLC). A única ofuscação da Cavedog foi a própria extensão.

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

Processos de conversão

O kbot zrb to-mp4 lê o cabeçalho e depois põe o FFmpeg a descodificar o filme para H.264 (CRF 18) e AAC tal como o jogo o mostra: com a altura de apresentação (um filme entrelaçado de 640×240 passa a 640×480, com uma linha preta a cada duas), com píxeis quadrados e parando na contagem de fotogramas do cabeçalho (o fotograma de anel não é mostrado).

Opção Efeito
--line-double Preenche as linhas extra de um filme entrelaçado repetindo cada linha guardada, em vez de as deixar pretas.
--stored-height Mantém a altura guardada dos fotogramas (640×240).

O leitor de vídeo do estúdio usa a mesma conversão, e as suas miniaturas mantêm a forma de apresentação 4:3 (128×96, linhas duplicadas).

Important

Não há caminho de MP4 → Smacker. O FFmpeg normal não tem codificador de Smacker (smackvid / smackaud) nem muxer, e o kbot não tem escritor de Smacker. O kbot zrb from-mp4 e a ferramenta MCP zrb_from_mp4 dizem exatamente isso (e só tentam o FFmpeg quando este lista tanto um codificador smackvid como um muxer smk). Faça os filmes SMK2 para o TA com as ferramentas Smacker da RAD Game Tools.


Tamanhos típicos

Recurso Resolução Fotogramas Duração Tamanho do ficheiro
Cinemática de introdução (data/1.zrb) 640 × 240 (mostrada a 640 × 480) 599 ~20 s ~7 MB
Outras cinemáticas (data/2.zrb–5.zrb) 640 × 240 (mostradas a 640 × 480) — — 10–41 MB

Armadilhas

Warning

AudioRate é uma palavra compactada, não uma frequência. Lida como um número simples, a palavra dos ficheiros comerciais, 0xD0005622, dá 3 489 682 978 "Hz". Aplique uma máscara aos 24 bits inferiores para obter a frequência e teste o bit 0x40000000 para saber se a faixa está presente. As ferramentas que leem mais sete palavras de "flags" depois do cabeçalho estão a ler a tabela de tamanhos dos fotogramas.

  • Smacker não é Bink. A RAD lançou primeiro o Smacker e depois o Bink, como seu sucessor. O TA só usa Smacker; o TA: Kingdoms passou para o Bink. Não carregue ficheiros .bik com kbot zrb: use antes o kbot bik.
  • As árvores de Huffman do SMK4 não são retrocompatíveis com os descodificadores de SMK2. O FFmpeg trata os dois, mas as bibliotecas de terceiros mais antigas podem não tratar.
  • As cinemáticas distribuídas guardam -3333 (100 000 / 3333 ≈ 30.003 fps).
  • A altura guardada não é a altura mostrada. Verifique as flags de entrelaçado e de duplicado; reproduzir os filmes comerciais a 640×240 achata-os para metade da altura.
  • Mudar a extensão .zrb ↔ .smk é inofensivo, mas o jogo espera .zrb na pasta data/. Não entregue ao motor ficheiros com nomes .smk.

Ver também

  • Bink — o codec sucessor que o TA: Kingdoms usa em vez do Smacker.
  • HPI — o arquivo invólucro que traz os ficheiros ZRB.
  • Glossário — taxa de fotogramas, assinatura.