Formatos de Arquivo do Outpost 2 · bei.pm

Este texto foi traduzido automaticamente pelo OpenAI GPT-4o Mini.

Os formatos de arquivo descritos nesta página são baseados na análise técnica da propriedade intelectual de Dynamix, Inc. e Sierra Entertainment.
A propriedade intelectual faz parte da massa da Activision Publishing, Inc. / Activision Blizzard, Inc. e atualmente é de propriedade da Microsoft Corp..

As informações foram coletadas através de Engenharia Reversa e Análise de Dados para fins de arquivamento e interoperabilidade com dados históricos.
Nenhuma especificação proprietária ou confidencial foi utilizada.

O jogo pode ser adquirido atualmente como download em gog.com.

Arte do jogo

A seguinte série de artigos documenta minhas descobertas sobre os formatos de dados no jogo de estratégia em tempo real "Outpost 2: Divided Destiny", que foi lançado em 1997 pela Sierra e desenvolvido pela Dynamix.

Eu me dediquei, aproximadamente, de 01 de novembro de 2015 até 14 de novembro de 2015, principalmente à análise dos dados do jogo - e o que pode ser feito com eles.

De acordo com as informações que consegui até agora, a Dynamix - assim como muitas empresas comerciais - não desenvolveu alguns formatos de dados especificamente para Outpost 2, mas os utilizou em outros desenvolvimentos, como por exemplo na série Mechwarrior (modificados).
Independentemente disso, também é possível observar que a capacidade de inovação dos formatos de dados é praticamente limitada e frequentemente se baseia em conceitos mais antigos de formatos comuns como JFIF e RIFF.

Para a interpretação das tabelas e formatos de dados, há mais informações disponíveis em O que é o que?.
Os dados aqui apresentados devem ser compreendidos, em geral, como Little Endian.

Por fim, pode-se dizer que a engenharia reversa foi muito divertida, mesmo que não esteja completa.
Naturalmente, eu também recomendo jogar o próprio jogo, pois ele oferece mecânicas de jogo interessantes.

Introdução

Os formatos de dados usados pelo Outpost 2 têm uma estrutura semelhante à do JFIF / PNG - os blocos de dados individuais sempre possuem um cabeçalho de 8 bytes. Portanto, não vou me dar ao trabalho de documentar os cabeçalhos individuais nos locais específicos correspondentes e apenas documentarei as divergências.

O formato é sempre o seguinte; os dados úteis reais estão então incorporados nele:

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos

Contém informações sobre o que esperar no próximo bloco de dados.

Valores conhecidos:

  • 0x204C4F56 ('VOL '):
    Volume
  • 0x686C6F76 ('VOLH'):
    Cabeçalho do Volume
  • 0x736C6F76 ('VOLS'):
    Strings do Volume
  • 0x696C6F76 ('VOLI'):
    Informações do Volume
  • 0x4B4C4256 ('BLCK'):
    Bloco do Volume
  • 0x504D4250 ('PBMP'):
    Dados Gráficos
  • 0x4C415050 ('PPAL'):
    Paleta de Cores
  • 0x4C415043 ('CPAL'):
    Container de Paletas de Cores
  • 0x64616568 ('head'):
    Cabeçalho
  • 0x61746164 ('data'):
    Dados Úteis
0x0004 uint(24) Comprimento do bloco

Contém a informação sobre o tamanho (em bytes) do seguinte bloco de dados.

Neste caso, refere-se apenas aos dados úteis - os 8 bytes do cabeçalho não estão incluídos.

0x0007 uint(8) Bandeiras?

É desconhecido para que serve exatamente este bloco.

Nos volumes, este valor é frequentemente 0x80, enquanto em outros arquivos é frequentemente 0x00. Isso sugere que se trata de um conjunto de flags.

Volumes

Os volumes são um contêiner de dados para o jogo, semelhante a um formato de arquivo como, por exemplo, Tarball. Pelo menos em Outpost 2, o formato reconhece apenas arquivos - sem pastas. Provavelmente, essas poderiam ser simuladas por meio de nomes de arquivos apropriados.

Um volume consiste no cabeçalho do volume e em vários blocos de volume, que correspondem aos arquivos concretos.

"Volumes" são os arquivos com a extensão 'vol' no diretório do jogo.

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 56 4f 4c 20 -- -- -- -- -- -- -- -- -- -- -- -- V O L . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento do bloco
0x0007 uint(8) Bandeiras

Cabeçalho de Volume

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 76 6f 6c 68 -- -- -- -- -- -- -- -- -- -- -- -- v o l h . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento do bloco
0x0007 uint(8) Bandeiras

O cabeçalho do volume não contém dados úteis.
Ele serve apenas como um contêiner.

Como primeira informação no cabeçalho do volume, devem estar as strings do volume; em seguida, vêm as informações do volume.

Strings de Volume

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 76 6f 6c 69 -- -- -- -- -- -- -- -- -- -- -- -- v o l i . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento do bloco
0x0007 uint(8) Bandeiras
Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 76 6f 6c 73 -- -- -- -- -- -- -- -- -- -- -- -- v o l s . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento do bloco
0x0007 uint(8) Bandeiras
0x0008 uint(32) Comprimento do payload

Indica quantos bytes dos dados seguintes são realmente dados úteis.

Os dados restantes da lista de Volume-Strings parecem ser classificados como lixo.

Em arquivos com data posterior, esses 'dados restantes' são 0x00, o que pode indicar deficiências na ferramenta durante o desenvolvimento do jogo, ou seja, que um desenvolvedor só se preocupou com a correta inicialização dos buffers muito tarde, uma vez que não afeta o jogo se os dados estão inicializados ou não.

0x000c uint(8)[] Lista de nomes de arquivos

Trata-se de uma lista de nomes de arquivos terminada em 0 bytes, que - pelo menos no componente de dados presente - parece esperar apenas caracteres ASCII.

Não é necessário analisar esse bloco de dados com mais detalhes ao fazer o parsing, uma vez que nas informações do volume os offsets dos nomes dos arquivos são referenciados diretamente.

Os Volume Strings são uma lista de nomes de arquivos que estão contidos dentro do volume.

Informações de Volume

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 76 6f 6c 69 -- -- -- -- -- -- -- -- -- -- -- -- v o l i . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento do bloco
0x0007 uint(8) Bandeiras

As informações de volume contêm detalhes adicionais sobre os arquivos. De certa forma, isso é uma espécie de entrada de diretório FAT (FAT = Tabela de Alocação de Arquivos).

O número de arquivos é determinado pelo tamanho do bloco dividido pelo comprimento das entradas de diretório - 14 bytes.

Cada uma das entradas de diretório tem a seguinte estrutura:

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Deslocamento do nome do arquivo

Indica em qual offset (!) dentro da lista de nomes de arquivos (Strings de Volume) o nome do arquivo é encontrado.

Refere-se ao início do bloco de dados úteis.

0x0004 uint(32) Deslocamento do arquivo

Indica em qual offset dentro do arquivo de volume total a arquivo se encontra.

0x0008 uint(32) Tamanho do arquivo

Indica o tamanho do arquivo em bytes.

0x000c uint(16) Bandeiras?

Parece haver informações adicionais sobre a codificação do arquivo.

  • 0x03 está definido quando o arquivo está comprimido. Aqui, aparentemente, um árvore de Huffman é utilizada.
  • 0x80 parece estar sempre definido.

Bloco de Volume

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 56 42 4c 48 -- -- -- -- -- -- -- -- -- -- -- -- V B L H . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento do bloco
0x0007 uint(8) Bandeiras

Um bloco de volume é um contêiner que armazena arquivos. Ele contém apenas mais uma vez - devido ao formato do bloco - a redundância do tamanho do arquivo e, em seguida, seguem-se diretamente os dados úteis.

Azulejos

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 50 42 4d 50 -- -- -- -- -- -- -- -- -- -- -- -- P B M P . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento do bloco
0x0007 uint(8) Bandeiras

Os Tiles são um formato de gráfico bitmap específico do Outpost-2. Eles se estendem por 13 conjuntos de tiles, chamados de "wells" (well0000.bmp até well0012.bmp), que estão dentro do volume maps.vol.

Os conjuntos de tiles / wells contêm o seguinte:

Nome do arquivo Conteúdo
well0000.bmp Uma imagem azul de 32x32px - ideal para testar se o carregador de imagens está funcionando
well0001.bmp Contém rochas claras, cadeias de montanhas sobre rochas claras e inúmeras variantes de crateras de impacto em rochas claras
well0002.bmp Contém 'Doodads' de rochas claras - ou seja, elementos que podem ser colocados para decorar (ou intencionalmente como estrutura, como muros) em rochas claras, incluindo vegetação
well0003.bmp Contém uma estrutura semelhante a crosta em rochas claras
well0004.bmp Contém rochas escuras, cadeias de montanhas sobre rochas escuras e inúmeras variantes de crateras de impacto em rochas escuras
well0005.bmp Contém 'Doodads' de rochas escuras - ou seja, elementos que podem ser colocados para decorar (ou intencionalmente como estrutura, como muros) em rochas escuras
well0006.bmp Contém uma estrutura semelhante a crosta em rochas escuras, assim como transições entre rochas claras e escuras
well0007.bmp Contém lava, incluindo 4-5 quadros de animação da mesma
well0008.bmp Contém areia e inúmeras variantes de crateras de impacto em areia
well0009.bmp Contém 'Doodads' de areia - ou seja, elementos que podem ser colocados para decorar (ou intencionalmente como estrutura, como muros) em areia
well0010.bmp Contém 48 transições de areia para rochas claras e escuras
well0011.bmp Contém as calotas polares do mapa, com rochas escuras como fundo
well0012.bmp Contém as calotas polares do mapa, com rochas claras como fundo

É altamente recomendável, para uma implementação precisa, não renderizar os tiles antecipadamente para que possam ser armazenados em cache, pois os dados para o ciclo dia/noite ainda precisam ser processados - e haveria uma quantidade muito grande de dados.

Os tiles são gráficos 8bpp com paleta indexada, cada um com resolução de 32x32 pixels, dispostos entre si. Em um tileset assim formado, no entanto, pode haver muito mais.

O contêiner principal é composto por 2 seções: head e data.

Cabeçalho dos Azulejos

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 68 65 61 64 -- -- -- -- -- -- -- -- -- -- -- -- h e a d . . . . . . . . . . . .
0x0010 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento do bloco
0x0007 uint(8) Bandeiras
0x0008 uint(32) Versão / Bandeiras?

Isso pode ser uma indicação de versão do formato de arquivo; em todos os arquivos que possuo, o valor aqui era 0x02

0x000c uint(32) Largura (Resolução Horizontal)

Indica a largura do arquivo de imagem (em pixels).

Para todos os poços do Outpost 2, o valor esperado aqui será 0x20 ou 32.

0x0010 uint(32) Altura (Resolução Vertical)

Indica quão alta é a imagem (em pixels).

Em todos os poços do Outpost 2, o valor esperado aqui será 0x20 ou 32.

0x0014 uint(32) Profundidade de cor?

A importância deste valor é desconhecida.

Uma vez que ele contém o valor 8 em todos os arquivos verificados, pode ser uma indicação de profundidade de cor.

0x0018 uint(32) Profundidade de cor 2?

O significado deste valor é desconhecido.

Possivelmente se trata de uma profundidade de cor 'destino'.

Após essas informações, haverá ainda um arquivo de paleta disponível no formato RIFF padronizado. A especificação exata pode ser encontrada - uma vez que as paletas também aparecem em outros lugares - em Paletas.

Dados dos Azulejos

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 64 61 74 61 -- -- -- -- -- -- -- -- -- -- -- -- d a t a . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento do bloco
0x0007 uint(8) Bandeiras

Finalmente, seguem os dados de pixel brutos, da esquerda para cima, linha por linha, até a parte inferior direita.
O valor dos dados nas gráficos, que geralmente estão na forma de bitmaps 8bpp, corresponde ao índice da cor na paleta de cores.

Dados de pixel começam no canto superior esquerdo e terminam no canto inferior direito.

A engine de jogo provavelmente desenha os tiles *sob demanda*.
Isso parece ser devido ao ciclo dia-noite, que conhece 32 graduações de tiles individuais. Aparentemente, o valor de luminosidade é diminuído 'um pouco' a cada vez. Valores exatos ainda não foram determinados, estou trabalhando com a base de cálculo

v *= (daylight / 48) + 0.25;

usando os dados HSV dos pixels, onde daylight é um valor de 0-31 e v é um valor entre 0-1. Além disso, é importante considerar que no mapa ainda existem bordas de 16 tiles à esquerda e à direita (que servem para o aparecimento invisível de unidades).

Além disso, o ciclo dia-noite parece atualizar apenas uma coluna do mapa a cada ciclo de jogo.
Um ciclo dia-noite acelerado se parece com o seguinte:

Visualização do ciclo dia-noite

PRT

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 43 50 41 4c -- -- -- -- -- -- -- -- -- -- -- -- C P A L . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento da palete

Diferente do formato de bloco normal, indica o número de paletes que podem ser encontrados neste arquivo - não o comprimento do bloco em bytes.

0x0007 uint(8) Bandeiras

Provavelmente, como de costume, flags.

No entanto, não conheço nenhuma flag; como todos os valores que conheço correspondem a 0x00, também seria potencialmente possível que o número de paletas fosse simplesmente um uint(32).

Não sei exatamente o que significa PRT; uma possibilidade poderia ser 'Tabela de Paletas e Recursos' - já que este arquivo - encontrado como op2_art.prt no maps.vol - é realmente uma tabela desse tipo, ou isso descreveria bem a sua função.

Este arquivo contém uma lista de paletas, uma tabela de todos os bitmaps utilizados, todas as definições de animação e uma série de dados desconhecidos. Ele segue de forma solta o formato de contêiner anterior, pois nem todos os registros seguem esse esquema.

A seção CPAL (provavelmente significa Contêiner de Paletas) envolve apenas os dados das paletas, indicando quantas das paletas de 8 bits, que geralmente têm 1052 bytes, estão presentes.

A especificação de 1052 bytes não é considerada obrigatória, pois o formato da paleta pode potencialmente prever tamanhos de paletas diferentes. Ela se aplica apenas ao conjunto de dados com o qual o Outpost 2 é fornecido.

Após as listas de paletas, segue imediatamente e sem um cabeçalho introdutório, a lista de bitmaps; e logo após, as listas de animação.
Ambas são iniciadas com um uint(32) (ou novamente uint24+uint8 flags?) que contém a quantidade de registros.

Paletas

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 50 50 41 4c -- -- -- -- -- -- -- -- -- -- -- -- P P A L . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento da palete

Indica, ao contrário do formato de bloco normal, a quantidade de paletes encontradas neste arquivo - não o tamanho do bloco em bytes.

0x0007 uint(8) Bandeiras

Provavelmente, como de costume, bandeiras.

No entanto, não conheço bandeiras; como todos os valores que conheço correspondem a 0x00, também seria potencialmente concebível que a quantidade de paletas fosse simplesmente um uint(32).

As informações das paletes são muito fáceis de ler.
Elas consistem em um cabeçalho e um segmento de dados.

Cabeçalho de Paletes

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 68 65 61 64 -- -- -- -- -- -- -- -- -- -- -- -- h e a d . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento da palete

Indica, ao contrário do formato de bloco normal, a quantidade de paletes encontradas neste arquivo - não o tamanho do bloco em bytes.

0x0007 uint(8) Bandeiras

Provavelmente, como de costume, bandeiras.

No entanto, não conheço bandeiras; como todos os valores que conheço correspondem a 0x00, também seria potencialmente concebível que a quantidade de paletas fosse simplesmente um uint(32).

0x0008 uint(32) Versão do formato de palete?

Define provavelmente qual versão do formato de palete a palete segue.

Todos os paletes do Outpost2 parecem ter a versão 0x01.

Dados das Paletes

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 64 61 74 61 -- -- -- -- -- -- -- -- -- -- -- -- d a t a . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Bytes Mágicos
0x0004 uint(24) Comprimento do bloco
0x0007 uint(8) Bandeiras

A seção de dados contém as entradas individuais das paletes. A quantidade de entradas de paletes é determinada pelo comprimento do bloco / 4.

As entradas individuais têm a seguinte estrutura simples;

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 -- -- -- 04 -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(8) Componente Vermelho

Indica a porcentagem de vermelho da cor

0x0001 uint(8) Componente Verde

Indica a proporção de verde na cor

0x0002 uint(8) Componente azul

Indica a proporção de azul na cor

0x0003 uint(8) Desconhecido - Bandeiras?

Não está claro o que esse valor significa, uma vez que ele parece ser basicamente 0x04.

Quanto às paletas, só resta dizer que para as paletas a serem usadas em animações, as seguintes regras se aplicam:

  • A primeira cor é SEMPRE transparente, não importa qual valor esteja indicado.
  • As entradas da paleta 1-24 são consideradas como cores do jogador nas paletas 1-8.
    Não está claro de onde vêm as cores além do jogador 1.
    Suspeito que as outras cores sejam hardcoded.

Referência de Paletas

Mapas de bits

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
0x0010 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Largura alinhada

Indica a largura das linhas de dados em pixels em bytes - uma vez que estão alinhadas aos limites de 4 bytes.

Dessa forma, é possível acessar rapidamente uma linha de imagem específica.

Por que esse valor é armazenado separadamente, embora possa ser calculado, não está claro.
Talvez seja uma otimização para o código de renderização.

0x0004 uint(32) Deslocamento

Indica o deslocamento da primeira linha no bitmap

0x0008 uint(32) Altura

Indica a altura da imagem em pixels

0x000c uint(32) Largura

Indica a largura da imagem em pixels

0x0010 uint(16) Tipo

Indica o tipo da imagem. Aqui parece tratar-se de uma máscara de bits:

  • 0x04 está definido se se tratar de uma gráfica de 1bpp.
  • 0x40 está definido se se tratar de uma gráfica que deve implementar janelas.
0x0012 uint(16) Paleta

Define qual palete da arquivo PRT deve ser utilizada

Estrutura de dados do arquivo PRT indica como os bitmaps usados para os sprites são organizados. Esses bitmaps servem como um único componente, dos quais vários são montados em um quadro de animação de um sprite.

Os dados de imagem concretos estão, por outro lado, no op2_art.BMP no diretório do jogo.
Por que esse arquivo bitmap possui um cabeçalho RIFF (predominantemente correto) não está claro. Provavelmente, o Outpost 2 usa APIs do sistema para carregar os gráficos, adotando temporariamente esse cabeçalho e sobrescrevendo os campos correspondentes e variáveis.

Os dados de pixel estão localizados no arquivo BMP na posição Offset + o uint32-Offset, encontrado no arquivo BMP no endereço 0x000A (offset de dados RIFF-Bitmap), e correspondem novamente à disposição linha a linha de cima para baixo, da esquerda para a direita.

Gráficos monocromáticos 1bpp podem ser desenhados de forma que a cor 0 represente transparência total, enquanto a cor 1 seja um preto/cinza semitransparente, já que os gráficos monocromáticos são geralmente usados para sombras de veículos e edifícios nas animações.

Dessa forma, já é possível montar muitas graficias.

Módulo residencial protegido (Plymouth)

Animações

Agora chegamos à classe principal das disciplinas dentro dos formatos de dados do Outpost 2:
As animações.

As listas de animação começam com um cabeçalho global, que serve principalmente para a verificação de dados. Em seguida, seguem as definições concretas de animação, que se dividem em 3 níveis:

  1. Animação
    Uma animação é a instância superior; ela representa uma animação de uma unidade, de um edifício ou de uma 'animação de partículas' (impacto de cometas, clima, explosão) em uma determinada situação inicial.
  2. Quadro
    Um quadro é uma única imagem dentro de uma animação. Uma animação pode conter um ou mais quadros.
  3. Subquadro
    Um subquadro é a informação de que uma determinada bitmap deve ser desenhada em uma determinada posição de um quadro sob certos critérios. Um quadro pode conter um ou mais subquadros.

Em seguida, já seguem as definições individuais de animação.

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Número de animações

Quantos registros de animação existem

0x0004 uint(32) Número de quadros

Quantos frames deveriam estar presentes no total

0x0008 uint(32) Número de Subquadros

Quantos subquadros devem estar presentes no total

0x000c uint(32) Número de entradas opcionais

Quantas "entradas opcionais" estão disponíveis.

Animação

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
0x0010 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
0x0020 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(32) Desconhecido 1

Informações desconhecidas

0x0004 uint(32) Caixa de Limite: Esquerda

Define a posição inicial à esquerda (em pixels) da Bounding Box.

0x0008 uint(32) Bounding Box: Cima

Indica o início superior (em pixels) da Bounding Box.

0x000c uint(32) Caixa de Limite: Largura

Indica a largura (em pixels) da Bounding Box.

0x0010 uint(32) Caixa delimitadora: altura

Indica a altura (em pixels) da Bounding Box.

0x0014 uint(32) Deslocamento: X

Indica o ponto central horizontal da animação

0x0018 uint(32) Deslocamento: Y

Indica o ponto médio vertical da animação

0x001c uint(32) Desconhecido 2

Informação desconhecida

0x0020 uint(32) Número de quadros

Indica quantos frames de animação estão contidos nesta animação

0x0024 uint(32) Número de janelas

Indica quantas janelas devem ser usadas ao desenhar

Os dados da camada superior, da animação, são prioritariamente dados administrativos - a Boundingbox refere-se às coordenadas da marcação em torno do veículo/edifício, quando este está selecionado e também indica qual área deve ser clicável.

O offset determina prioritariamente o "ponto zero"; o ponto que deve ser adicionado ou subtraído às coordenadas internas do jogo. Poderíamos dizer de forma mais matemática: o offset aqui indica a origem das coordenadas.

As janelas (Windows) são, assim como o offset, compostas por 4 valores uint(32) cada, que indicam uma área que é considerada utilizável para subquadros individuais. Fora das janelas, desde que seja apropriado para o bitmap, não se deve desenhar.

Estrutura

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(8) Número de subquadros e alternância para Opcional 1, 2

Este valor contém:

  • 0x7F (Máscara de bits): O número de subquadros utilizados neste quadro
  • 0x80: A informação sobre a presença de Opcional 1 e 2
0x0001 uint(8) Desconhecido 1 e Alternar para Opcional 3, 4

Este valor contém:

  • 0x7F (máscara de bits): Desconhecido - Suspeito fortemente que se refere ao número de gameticks que passam até que o próximo frame seja exibido
  • 0x80: A informação sobre a presença das opções 3 e 4
0x0002 uint(8) Opcional 1

Desconhecido

0x0003 uint(8) Opcional 2

Desconhecido

0x0004 uint(8) Opcional 3

Desconhecido

0x0005 uint(8) Opcional 4

Desconhecido

Subquadro

Endereço x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF caractere
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Deslocamento Tipo de dado Designação Explicação
0x0000 uint(16) Bitmap-ID

Indica qual bitmap deve ser usada para este subquadro

0x0002 uint(8) Desconhecido 1

É desconhecido - no entanto, suspeito fortemente que se trate de uma prioridade de renderização (Z-Layer).

0x0003 uint(8) Id do Subquadro

Indica em qual subquadro estamos

0x0004 sint(16) Deslocamento - Horizontal

Indica onde dentro do quadro o subquadro deve ser colocado, ou quantos pixels a bitmap deve ser deslocada horizontalmente

0x0006 sint(16) Offset - Vertical

Indica onde dentro do frame o subframe deve ser colocado, ou quantos pixels a bitmap deve ser deslocada verticalmente

Com isso, agora podemos montar frames individuais, bem como animações completas, demonstrado aqui como exemplo em uma animação mais complexa, a animação com o índice 500.

Animação 500

A animação 500 mostra como um transporte Plymouth, carregado com minério comum, é descarregado. Esta é uma das poucas animações que utiliza a funcionalidade de janelas.

E assim, a animação completa pode ser montada.
Infelizmente, ainda há um problema com a escotilha superior, pois o bit correspondente nas informações do tipo de gráfico não está definido.

Aqui estão mais alguns sprites lindamente animados do jogo:

Renderização da animação 500 ilustrada

Animação 500 totalmente montada

Fábrica de Edifícios Plymouth

Porto Espacial Eden

Centro Médico Eden

SCAT

Porto Espacial Plymouth

Easteregg:
Papai Noel

Easteregg:
Dog de Dans

Interface do Usuário

Agora falta apenas a interface do usuário do jogo, que é feita em um estilo de metal escovado.

Mas também aqui é evidente que Dynamix não precisou reinventar a roda; aqui não são apenas utilizadas as APIs User32 e GDI32 fornecidas pelo Windows - em particular, também é gerenciado o uso de recursos do User32.

Esses recursos podem ser extraídos, por exemplo, por programas como o Resource Hacker, desenvolvido como freeware por Angus Johnson, ou - caso você evite usar Wine no Linux / Mac OS - com a ajuda do wrestool incluído no icoutils.

Nome do arquivo Conteúdo
Outpost2.exe Contém apenas o ícone do jogo, que mostra a estação espacial em New Terra
op2shres.dll Contém, além de gráficos para elementos de controle como bordas, botões, botões de rádio e caixas de seleção, também fundos de diálogo, imagens de apoio para os textos das missões da história e o gráfico de fundo do menu principal
out2res.dll Contém a decoração de janelas do jogo, ícones para metal comum e especial, a tela de carregamento, gráficos para diálogos, além de outros gráficos de cursor, além dos animados no diretório do jogo