Formati di file di Outpost 2 · bei.pm
I formati di file descritti in questa pagina si basano sull'analisi tecnica della proprietà intellettuale di Dynamix, Inc. e Sierra Entertainment.
La proprietà intellettuale è attualmente parte del patrimonio di Activision Publishing, Inc. / Activision Blizzard, Inc. ed è attualmente di proprietà di Microsoft Corp..
Le informazioni sono state raccolte tramite Reverse Engineering e analisi dei dati a scopo di archiviazione e interoperabilità con dati storici.
Non sono state utilizzate specifiche proprietarie o riservate.
Il gioco è attualmente disponibile per l'acquisto come download su gog.com.
La seguente serie di articoli documenta le mie scoperte sui formati di dati nel gioco di strategia in tempo reale "Outpost 2: Divided Destiny", pubblicato nel 1997 da Sierra e sviluppato da Dynamix.
Ho dedicato principalmente dal 1° novembre 2015 al 14 novembre 2015 all'analisi dei dati del gioco - e a cosa farne.
Secondo le informazioni che ho potuto raccogliere finora, Dynamix - come molte aziende commerciali - non ha sviluppato alcuni formati di dati specificamente per Outpost 2, ma li ha utilizzati anche in altre produzioni come, ad esempio, la serie Mechwarrior (in forma modificata).
Inoltre, è possibile constatare che la capacità innovativa dei formati di dati è praticamente limitata e spesso si basa su concetti già esistenti di formati comuni come JFIF e RIFF.
Per l'interpretazione delle tabelle e dei formati di dati sono disponibili ulteriori informazioni su Cos'è cos'è?.
I dati qui indicati devono essere generalmente intesi come Little Endian.
In conclusione, posso dire che il reverse engineering è stato molto divertente, anche se non è completo.
Certo, posso anche consigliare di giocare il gioco stesso, poiché offre meccaniche di gioco interessanti.
Introduzione
I formati di dati utilizzati da Outpost 2 hanno una struttura simile a JFIF / PNG - i singoli blocchi di dati presentano sempre un'intestazione di 8 byte. Perciò eviterò di documentare le singole intestazioni nei luoghi specifici corrispondenti e documenterò solo le deviazioni.
Il formato è sempre il seguente; i dati utili sono quindi incorporati al suo interno:
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | Contiene informazioni su cosa aspettarsi nel prossimo blocco di dati. Valori noti:
|
0x0004 | uint(24) | Lunghezza del blocco | Contiene l'informazione su quanto è grande (in byte) il seguente blocco di dati. Si intende qui solo il payload - gli 8 byte dell'intestazione non sono inclusi. |
0x0007 | uint(8) | Bandiere? | Non è chiaro a cosa serva esattamente questo blocco. Nei volumi, questo valore è frequentemente 0x80, mentre in altri file è spesso 0x00. Ciò suggerisce che si tratti di un insieme di flag. |
Volumi
I volumi sono dei contenitori di dati per il gioco, simili a un formato di archivio come ad esempio il Tarball. Almeno in Outpost 2, il formato riconosce solo file - nessuna cartella. Probabilmente, tuttavia, queste ultime potrebbero essere simulate attraverso nomi di file appropriati.
Un volume è composto dall'intestazione del volume e da diversi blocchi di volume, che corrispondono ai file concreti.
"I 'volumi'" sono i file con l'estensione 'vol'
nella directory di gioco.
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 56 | 4f | 4c | 20 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | V | O | L | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | |
0x0004 | uint(24) | Lunghezza del blocco | |
0x0007 | uint(8) | Bandiere |
Intestazione Volume
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 68 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | h | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | |
0x0004 | uint(24) | Lunghezza del blocco | |
0x0007 | uint(8) | Bandiere |
L'intestazione del volume non contiene alcun dato utile.
Essa funge unicamente da contenitore.
Le stringhe del volume dovrebbero trovarsi come prima informazione nell'intestazione del volume; a seguire ci sono le informazioni sul volume.
Stringhe di Volume
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 69 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | i | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | |
0x0004 | uint(24) | Lunghezza del blocco | |
0x0007 | uint(8) | Bandiere |
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 73 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | s | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | |
0x0004 | uint(24) | Lunghezza del blocco | |
0x0007 | uint(8) | Bandiere | |
0x0008 | uint(32) | Lunghezza del payload | Indica quanti byte dei seguenti dati sono effettivamente dati utili. I restanti dati della lista dei volume-strings devono essere considerati come garbage. Nei file con data più recente, questi 'dati rimanenti' sono 0x00, il che potrebbe suggerire insufficienze nella toolchain durante lo sviluppo del gioco, in altre parole, che solo molto tardi un sviluppatore si è occupato della corretta inizializzazione dei buffer, poiché non ha alcun impatto sul gioco se i dati siano inizializzati o meno. |
0x000c | uint(8)[] | Elenco dei nomi dei file | Si tratta di un elenco di nomi di file terminato con 0 byte, che - almeno nel presente componente dei dati - sembra aspettarsi solo caratteri ASCII. Non è necessario analizzare ulteriormente questo blocco di dati durante il parsing, poiché nelle informazioni sul volume vengono comunque referenziati direttamente gli offset dei nomi dei file. |
I Volume Strings sono un elenco di nomi di file che sono contenuti all'interno del volume.
Informazioni sul volume
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 69 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | i | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | |
0x0004 | uint(24) | Lunghezza del blocco | |
0x0007 | uint(8) | Bandiere |
Le informazioni sul volume contengono dettagli più specifici sui file. Si tratta in un certo senso di una sorta di voce di directory FAT (FAT = File Allocation Table).
Il numero di file si ottiene dividendo la dimensione del blocco per la lunghezza delle voci di directory - 14 byte.
I singoli elementi di directory hanno la seguente struttura:
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Offset del nome del file | Indica a quale offset (!) all'interno dell'elenco dei nomi dei file (Volume-Strings) si trova il nome del file. Si riferisce all'inizio del blocco di dati utili. |
0x0004 | uint(32) | Offset del file | Indica a quale offset all'interno dell'intero file volume si trova il file. |
0x0008 | uint(32) | Dimensione del file | Indica quanto è grande il file in byte. |
0x000c | uint(16) | Bandiere? | Fornisce chiaramente informazioni aggiuntive sulla codifica del file.
|
Blocco Volume
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 56 | 42 | 4c | 48 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | V | B | L | H | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | |
0x0004 | uint(24) | Lunghezza del blocco | |
0x0007 | uint(8) | Bandiere |
Un volume-block è un contenitore che ospita file. Contiene soltanto - a causa del formato a blocchi - in modo ridondante la dimensione del file e successivamente seguono direttamente i dati utili.
Piastrelle
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 50 | 42 | 4d | 50 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | P | B | M | P | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | |
0x0004 | uint(24) | Lunghezza del blocco | |
0x0007 | uint(8) | Bandiere |
I tiles sono un formato grafico bitmap specifico per Outpost-2. Si estendono su 13 tileset,
chiamati "wells" (well0000.bmp
fino a well0012.bmp
),
che si trovano all'interno del volume maps.vol.
I tileset / Wells contengono quanto segue:
Nome file | Contenuto |
---|---|
well0000.bmp | Un'immagine blu di 32x32px - ideale per testare se il proprio caricatore di immagini funziona |
well0001.bmp | Contiene rocce chiare, catene montuose su rocce chiare e innumerevoli varianti di crateri da impatto su rocce chiare |
well0002.bmp | Contiene 'Doodads' di rocce chiare - elementi che possono essere posizionati per decorare (o intenzionalmente come struttura, come ad esempio muri) su rocce chiare, compresa la vegetazione |
well0003.bmp | Contiene una struttura a crosta su rocce chiare |
well0004.bmp | Contiene rocce scure, catene montuose su rocce scure e innumerevoli varianti di crateri da impatto su rocce scure |
well0005.bmp | Contiene 'Doodads' di rocce scure - elementi che possono essere posizionati per decorare (o intenzionalmente come struttura, come ad esempio muri) su rocce scure |
well0006.bmp | Contiene una struttura a crosta su rocce scure, così come transizioni tra rocce chiare e scure |
well0007.bmp | Contiene lava, inclusi 4-5 frame di animazione della stessa |
well0008.bmp | Contiene sabbia e innumerevoli varianti di crateri da impatto nella sabbia |
well0009.bmp | Contiene 'Doodads' di sabbia - elementi che possono essere posizionati per decorare (o intenzionalmente come struttura, come ad esempio muri) sulla sabbia |
well0010.bmp | Contiene 48 transizioni da sabbia a rocce chiare e scure |
well0011.bmp | Contiene le calotte polari della mappa, con rocce scure come sottostrato |
well0012.bmp | Contiene le calotte polari della mappa, con rocce chiare come sottostrato |
È consigliabile per una realizzazione accurata non rendere in anticipo i tiles per metterli in cache, poiché i dati per il ciclo giorno/notte devono ancora essere elaborati - e ci sarebbero moltissimi dati.
I tiles sono grafica 8bpp con palette indicizzata, ciascuno con risoluzione 32x32 pixel, disposti tra di loro. In un tileset così creato, però, possono esserci molti più
Il contenitore principale è composto da 2 sezioni: head
e data
.
Intestazione delle Piastrelle
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 68 | 65 | 61 | 64 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | h | e | a | d | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | |
0x0004 | uint(24) | Lunghezza del blocco | |
0x0007 | uint(8) | Bandiere | |
0x0008 | uint(32) | Versione / Bandiera? | Qui potrebbe trattarsi di un'indicazione della versione del formato file; in tutti i file a mia disposizione era presente il valore |
0x000c | uint(32) | Larghezza (Risoluzione Orizzontale) | Indica quanto è larga la file immagine (in pixel). Per tutti i pozzi di Outpost 2, ci si aspetta qui il valore |
0x0010 | uint(32) | Altezza (risoluzione verticale) | Indica quanto è alta la file immagine (in pixel). Per tutti i pozzi di Outpost 2, ci si aspetta qui il valore |
0x0014 | uint(32) | Profondità del colore? | Il significato di questo valore è sconosciuto. Poiché è presente in tutti i file esaminati il valore |
0x0018 | uint(32) | Profondità di colore 2? | Il significato di questo valore è sconosciuto. Potrebbe trattarsi di una 'profondità' colore 'obiettivo'. |
Secondo queste indicazioni, seguirà un file di palette in formato RIFF standardizzato. La specifica esatta si trova - poiché le palette compaiono anche altrove - sotto Palette.
Dati delle piastrelle
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 64 | 61 | 74 | 61 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | d | a | t | a | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | |
0x0004 | uint(24) | Lunghezza del blocco | |
0x0007 | uint(8) | Bandiere |
Infine, seguono i dati dei pixel puri, riga per riga da sinistra in alto a destra in basso.
Il valore dei dati per le grafiche generalmente presenti come bitmap a 8bpp corrisponde all'indice del colore nella tavolozza.
Il motore di gioco disegna i tiles *probabilmente* su richiesta.
Questo sembra essere dovuto, tra l'altro, al ciclo giorno-notte che prevede 32 gradazioni di singoli tiles. Apparentemente, viene sottratto 'un po'' dal valore di luminosità. Valori precisi non sono ancora stati determinati, sto lavorando sulla base di calcolo
v *= (daylight / 48) + 0.25;
con i dati HSV dei pixel, dove daylight è un valore da 0-31 e v è un valore compreso tra 0-1. Inoltre, è da considerare che sulla mappa esiste un margine di 16 tiles a sinistra e a destra (che serve per la generazione invisibile delle unità).
In aggiunta, sembra che il ciclo giorno-notte aggiorni solo una colonna della mappa per ogni ciclo di gioco.
Un ciclo giorno-notte accelerato appare quindi come segue:
PRT
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 43 | 50 | 41 | 4c | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | C | P | A | L | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte Magici | |
0x0004 | uint(24) | Lunghezza della pallet | Indica, contrariamente al formato di blocco normale, il numero di palette presenti in questo file - non la lunghezza del blocco in byte. |
0x0007 | uint(8) | Bandiere | Probabilmente, come al solito, flags. Tuttavia, non sono a conoscenza di alcun flag; dato che tutti i valori che conosco corrispondono a |
Cosa rappresenti esattamente PRT
non è a me noto; potrebbe essere, ad esempio, 'Palette and Resource Table' - poiché questo file, che si trova come op2_art.prt in maps.vol, è proprio di questo tipo, o almeno questa descrizione ne riassumerebbe bene la funzione.
Il file contiene un elenco di palette, una tabella su tutte le bitmap utilizzate, tutte le definizioni delle animazioni e una serie di dati sconosciuti. Segue in modo vago il formato del contenitore precedente, poiché non tutti i record seguono questo schema.
La sezione CPAL
(che probabilmente sta per contenitore di palette) racchiude solo i dati delle palette, specificando quanti dei soliti 1052 byte di palette a 8 bit sono presenti.
Il valore di 1052 byte non è da considerarsi vincolante, poiché il formato delle palette potrebbe prevedere dimensioni diverse. Si applica solo ai dati con cui viene distribuito Outpost 2.
Dopo l'elenco delle palette, segue immediatamente e senza un header introduttivo, l'elenco delle bitmap; subito dopo seguono le liste delle animazioni.
Entrambi sono introdotti da un uint(32) (o forse da uint24 + uint8 flags?), che contiene il numero di record.
Palette
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 50 | 50 | 41 | 4c | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | P | P | A | L | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte magici | |
0x0004 | uint(24) | Lunghezza del pallet | Indica, a differenza del formato blocco normale, il numero di palette che si possono trovare in questo file - non la lunghezza del blocco in byte. |
0x0007 | uint(8) | Bandiere | Probabilmente, come al solito, flags. Tuttavia, non sono a conoscenza di alcun flag; poiché tutti i valori a me noti corrispondono a |
Le informazioni sulle palette sono molto semplici da comprendere.
Esse consistono ciascuna in un'intestazione e in un segmento di dati.
Intestazione Palette
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 68 | 65 | 61 | 64 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | h | e | a | d | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte magici | |
0x0004 | uint(24) | Lunghezza del pallet | Indica, a differenza del formato blocco normale, il numero di palette che si possono trovare in questo file - non la lunghezza del blocco in byte. |
0x0007 | uint(8) | Bandiere | Probabilmente, come al solito, flags. Tuttavia, non sono a conoscenza di alcun flag; poiché tutti i valori a me noti corrispondono a |
0x0008 | uint(32) | Versione del formato pallet? | Probabilmente definisce a quale versione del formato delle palette la palette si conforma. Tutte le palette di Outpost2 sembrano appartenere alla versione |
Dati sulle palette
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 64 | 61 | 74 | 61 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | d | a | t | a | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Byte magici | |
0x0004 | uint(24) | Lunghezza del blocco | |
0x0007 | uint(8) | Bandiere |
La sezione dati raccoglie le singole voci delle palette. Il numero delle voci delle palette è dato dalla lunghezza del blocco / 4.
Gli singoli elementi hanno una struttura semplice come segue;
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | 04 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(8) | Componente rosso | Indica la percentuale di rosso del colore |
0x0001 | uint(8) | Componente verde | Indica la percentuale di verde del colore |
0x0002 | uint(8) | Componente blu | Indica la componente blu del colore |
0x0003 | uint(8) | Sconosciuto - Bandiera? | Non è chiaro cosa significhi questo valore, poiché sembra essere fondamentalmente |
Per quanto riguarda le palette, c'è solo da dire che per le palette utilizzate nelle animazioni valgono le seguenti regole:
- Il primo colore è SEMPRE trasparente, indipendentemente dal valore specificato.
-
Le voci delle palette da 1 a 24 devono essere considerate come colori dei giocatori nelle palette da 1 a 8.
Non è chiaro da dove provengano esattamente i colori oltre al giocatore 1.
Sospetto che i restanti colori siano hardcoded.
Bitmaps
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Larghezza allineata | Indica la larghezza delle righe di dati pixel in byte - poiché queste sono allineate ai confini di 4 byte. In questo modo è possibile saltare rapidamente a una determinata riga dell'immagine. Non è chiaro perché questo valore venga memorizzato separatamente, sebbene potrebbe essere calcolato. |
0x0004 | uint(32) | Offset | Indica l'offset della prima riga nella bitmap |
0x0008 | uint(32) | Altezza | Specifica l'altezza dell'immagine in pixel |
0x000c | uint(32) | Larghezza | Indica la larghezza dell'immagine in pixel |
0x0010 | uint(16) | Tipo | Indica il tipo di immagine. Sembra trattarsi di una maschera bit:
|
0x0012 | uint(16) | Palette | Definisce quale palette utilizzare dal file PRT |
Questa struttura dati del file PRT indica come sono costruite le bitmap utilizzate per gli sprite. Queste bitmap fungono da singolo componente, da cui più elementi vengono assemblati per un frame di animazione di uno sprite.
I dati delle immagini concreti si trovano invece in
op2_art.BMP nella directory di gioco.
Perché questo file bitmap abbia un'intestazione RIFF bitmap (per lo più corretta) non è chiaro. Probabilmente Outpost 2 utilizza API di sistema per caricare le grafiche, adottando temporaneamente questa intestazione e sovrascrivendo i campi corrispondenti e variabili.
I dati dei pixel si trovano nel file BMP nella posizione Offset + l'offset uint32, che si trova nel file BMP all'indirizzo 0x000A (offset dati RIFF bitmap), e corrispondono di nuovo all'ordinamento riga per riga dall'alto verso il basso e da sinistra a destra.
Grafiche monocromatiche 1bpp possono essere disegnate in modo tale che il colore 0 sia completamente trasparente, mentre il colore 1 è un nero/grigio semi-trasparente, poiché le grafiche monocrome vengono generalmente utilizzate per le ombre di veicoli e edifici nelle animazioni.
In questo modo si possono già assemblare molte grafiche.
Animazioni
Adesso arriviamo alla classe regina delle discipline all'interno dei formati dati di Outpost 2:
Le animazioni.
Le liste delle animazioni sono introdotte da un'intestazione globale, che serve principalmente alla verifica dei dati. Seguono quindi le specifiche delle animazioni concrete, che si suddividono in 3 livelli:
-
Animazione
Un'animazione è l'istanza principale; rappresenta un'animazione di un'unità, di un edificio o di un 'animazione di particelle' (impatto di un cometa, meteo, esplosione) in una determinata situazione iniziale. -
Frame
Un frame è un'immagine singola all'interno di un'animazione. Un'animazione può contenere uno o più frame. -
Subframe
Un subframe è l'informazione riguardante il fatto che un determinato bitmap deve essere disegnato in una certa posizione di un frame secondo specifici criteri. Un frame può contenere uno o più subframe.
Segue quindi direttamente la definizione delle singole animazioni.
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Numero di animazioni | Quanti set di dati di animazione sono presenti |
0x0004 | uint(32) | Numero di frame | Quanti frame dovrebbero esserci in totale |
0x0008 | uint(32) | Numero di sottocadri | Quanti subframe dovrebbero esserci in totale |
0x000c | uint(32) | Numero di voci opzionali | Quanti "elementi opzionali" sono presenti. |
Animazione
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0020 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(32) | Sconosciuto 1 | Informazioni sconosciute |
0x0004 | uint(32) | Bounding Box: Sinistra | Indica l'inizio sinistro (in pixel) della Bounding Box. |
0x0008 | uint(32) | Bounding Box: Sopra | Specifica l'inizio superiore (in pixel) della Bounding Box. |
0x000c | uint(32) | Bounding Box: Larghezza | Indica la larghezza (in pixel) della Bounding Box. |
0x0010 | uint(32) | Riquadro: Altezza | Indica l'altezza (in pixel) della Bounding Box. |
0x0014 | uint(32) | Offset: X | Indica il punto centrale orizzontale dell'animazione |
0x0018 | uint(32) | Offset: Y | Indica il punto centrale verticale dell'animazione |
0x001c | uint(32) | Sconosciuto 2 | Informazione sconosciuta |
0x0020 | uint(32) | Numero di frame | Indica quanti fotogrammi di animazione sono contenuti in questa animazione |
0x0024 | uint(32) | Numero di finestre | Indica quanti finestre devono essere utilizzate durante il disegno |
I dati del livello superiore, dell'animazione, sono principalmente dati di gestione - la Boundingbox indica le coordinate del contrassegno attorno al veicolo/edificio, quando esso è selezionato e indica anche quale area deve essere cliccabile.
L'offset determina principalmente il "punto zero"; il punto da sommare o sottrarre alle coordinate interne del gioco. Potremmo anche dire in termini matematici: l'offset indica qui l'origine delle coordinate.
Le finestre consistono, proprio come l'offset, in 4 valori uint(32) ciascuna (per finestra), che specificano un'area utilizzabile per singoli subframe. Fuori dalle finestre non è permesso realizzare disegni, a meno che non sia specificamente previsto per la bitmap.
Cornice
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(8) | Numero del subframe e attivazione per Opzionale 1, 2 | Questo valore contiene:
|
0x0001 | uint(8) | Sconosciuto 1 e Toggle per Opzionale 3, 4 | Questo valore contiene:
|
0x0002 | uint(8) | Opzionale 1 | Sconosciuto |
0x0003 | uint(8) | Opzionale 2 | Sconosciuto |
0x0004 | uint(8) | Opzionale 3 | Sconosciuto |
0x0005 | uint(8) | Opzionale 4 | Sconosciuto |
Sottostruttura
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caratteri | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tipo di dato | Nome | Spiegazione |
---|---|---|---|
0x0000 | uint(16) | Bitmap-ID | Indica quale bitmap deve essere utilizzata per questo sottostrato |
0x0002 | uint(8) | Sconosciuto 1 | È sconosciuto - tuttavia sospetto fortemente che si tratti di una priorità di rendering (Z-Layer). |
0x0003 | uint(8) | Id del sottogruppo | Indica in quale sottocornice ci troviamo |
0x0004 | sint(16) | Offset - Orizzontale | Specifica dove all'interno del frame deve essere posizionato il subframe, oppure di quanti pixel deve essere spostata orizzontalmente la bitmap |
0x0006 | sint(16) | Offset - Verticale | Indica dove all'interno del frame deve essere posizionato il subframe, oppure di quanti pixel deve essere spostata verticalmente la bitmap |
Con questo possiamo ora assemblare singoli frame, così come animazioni complete; qui viene dimostrato, a titolo esemplificativo, con un'animazione più complessa, quella con l'indice 500.
Animazione 500
L'animazione 500 mostra come un furgone Plymouth, caricato con materiale comune, venga scaricato. Si tratta di una delle poche animazioni che utilizza la funzionalità di Windowing.
In questo modo si può unire l'intera animazione.
Purtroppo c'è ancora un problema con il portellone superiore, poiché qui il bit corrispondente nelle informazioni sul tipo di grafica non è impostato.
Ecco alcuni altri bellissimi sprite animati dal gioco:
Interfaccia Utente
Manca ancora l'interfaccia utente del gioco, realizzata in uno stile metallo spazzolato.
Tuttavia, è evidente che Dynamix non ha dovuto reinventare la ruota; qui non vengono semplicemente utilizzate le API User32 e GDI32 fornite da Windows - in particolare, viene anche utilizzata la gestione delle risorse di User32.
Queste possono essere estratte, ad esempio, tramite programmi come il Resource Hacker sviluppato come freeware da Angus Johnson, oppure - se si teme di usare Wine su Linux / Mac OS - utilizzando wrestool incluso in icoutils.
Nome file | Contenuto |
---|---|
Outpost2.exe | Contiene solo l'icona del gioco, che mostra la stazione spaziale di New Terra |
op2shres.dll | Contiene oltre alle grafiche per i controlli come bordi, pulsanti, pulsanti di opzione e caselle di controllo, anche sfondi per dialoghi, immagini di accompagnamento per i testi delle missioni e la grafica di sfondo del menu principale |
out2res.dll | Contiene la decorazione delle finestre in gioco, icone per metalli comuni e speciali, la schermata di caricamento, grafiche per dialoghi e ulteriori grafiche per il cursore, oltre a quelle animate nella cartella di gioco |