Formate de fișier Outpost 2 · bei.pm
Formatele de fișier descrise pe această pagină se bazează pe analiza tehnică a proprietății intelectuale de la Dynamix, Inc. și Sierra Entertainment.
Proprietatea intelectuală este astăzi parte a masei Activision Publishing, Inc. / Activision Blizzard, Inc. și este deținută în prezent de Microsoft Corp..
Informațiile au fost adunate prin Inginerie Inversă și Analiza Datelor în scopul arhivării și interoperabilității cu datele istorice.
Nu au fost folosite specificații proprietare sau confidențiale.
Jocul poate fi achiziționat în prezent de la gog.com ca descărcare.
Seria de articole de mai jos documentează descoperirile mele referitoare la formatele de date din jocul de strategie în timp real "Outpost 2: Divided Destiny", care a fost lansat în 1997 de Sierra și dezvoltat de Dynamix.
Am lucrat în principal la analiza datelor jocului - și la ce se poate face cu acestea - în perioada 1 noiembrie 2015 până pe 14 noiembrie 2015.
Conform informațiilor pe care le-am obținut până acum, Dynamix - la fel ca multe companii comerciale - nu a dezvoltat unele formate de date special pentru Outpost 2, ci le-a folosit și în alte dezvoltări, cum ar fi seria Mechwarrior (modificate).
Indiferent de aceasta, se poate observa că puterea de inovație a formatelor de fișiere este practic limitată și se bazează adesea pe concepte mai vechi din formate obișnuite, cum ar fi JFIF și RIFF.
Pentru interpretarea tabelelor și a formatelor de date, sunt disponibile informații suplimentare la Ce este ce?.
Datele prezentate aici sunt, în general, de înțeles ca fiind Little Endian.
În concluzie, se poate spune că ingineria inversă a fost foarte distractivă, chiar dacă nu este completă.
Desigur, pot recomanda și să jucați jocul în sine, deoarece oferă mecanici de joc interesante.
Introducere
Formatele de date utilizate de Outpost 2 au o structură care amintește de JFIF / PNG - blocurile de date individuale au întotdeauna un header de 8 Bytes. Prin urmare, nu voi documenta fiecare header în locurile specifice corespunzătoare, ci voi documenta doar abaterile.
Formatul este întotdeauna următorul; datele propriu-zise sunt încorporate în acesta:
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caractere | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Bytes Magice | Conține informații despre ceea ce se poate aștepta în următorul bloc de date. Valori cunoscute:
|
0x0004 | uint(24) | Lungimea blocului | Conține informații despre dimensiunea (în byte) a blocului de date următor. Aici se referă la datele utile propriu-zise - cele 8 byte de antet nu sunt incluse. |
0x0007 | uint(8) | Steaguri? | Nu se știe exact la ce servește acest bloc. În volume, această valoare este adesea 0x80, iar în alte fișiere frecvent 0x00. Aceasta sugerează că este vorba despre un set de steaguri. |
Volume
Volițele sunt un container de date pentru joc, asemănător cu un format de arhivă, cum ar fi Tarball. În cel puțin Outpost 2, formatul cunoaște doar fișiere - fără foldere. Cel mai probabil, acestea ar putea fi simulate prin denumiri corespunzătoare ale fișierelor.
Un volum constă din antetul volumului, precum și din mai multe blocuri de volum, care corespund fișierelor concrete.
"Volumele" sunt fișierele cu extensia 'vol'
din directorul jocului.
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Octeți magici | |
0x0004 | uint(24) | Lungimea blocului | |
0x0007 | uint(8) | Steaguri |
Antet Volum
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Octeți magici | |
0x0004 | uint(24) | Lungimea blocului | |
0x0007 | uint(8) | Steaguri |
Antetul volumului nu conține date utile.
Acesta servește doar ca un container.
Primul element în antetul volumului ar trebui să fie șirurile volumului; urmate apoi de informațiile despre volum.
Șiruri de volum
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Octeți magici | |
0x0004 | uint(24) | Lungimea blocului | |
0x0007 | uint(8) | Steaguri |
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Octeți magici | |
0x0004 | uint(24) | Lungimea blocului | |
0x0007 | uint(8) | Steaguri | |
0x0008 | uint(32) | Lungimea payload-ului | Indică câte byte din următoarele date sunt de fapt date utile. Restul datelor din lista de șiruri de volum sunt evident considerate gunoi. În fișierele cu dată mai recentă, aceste 'date rămase' sunt 0x00, ceea ce ar putea indica neajunsuri cu toolchain-ul în timpul dezvoltării jocului, adică, un dezvoltator s-a ocupat de corecta inițializare a bufferelor abia foarte târziu, deoarece nu are importanță pentru joc dacă datele sunt inițializate sau nu. |
0x000c | uint(8)[] | Lista de nume de fișiere | Aici este vorba despre o listă terminată la 0 byte de nume de fișiere, care - cel puțin în acest component de date furnizat - pare să aștepte doar caractere ASCII. Nu este necesar să evaluăm acest bloc de date mai detaliat în timpul analizei datelor, deoarece în informațiile volumului sunt deja referite direct offset-urile numelui de fișier. |
Volume Strings reprezintă o listă de nume de fișiere care sunt incluse în volum.
Informații despre volum
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Octeți magici | |
0x0004 | uint(24) | Lungimea blocului | |
0x0007 | uint(8) | Steaguri |
Informațiile despre volum conțin detalii mai aprofundate despre fișiere. Acestea reprezintă, într-un fel, un fel de înregistrare în director FAT (FAT = File Allocation Table)
Numărul de fișiere rezultă din dimensiunea blocului împărțită la lungimea înregistrărilor din director - 14 octeți.
Fiecare înregistrare din director are următoarea structură:
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caractere | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Offsetul numelui fișierului | Indică la ce offset (!) din lista de nume de fișiere (Volume-Strings) se găsește numele fișierului. Se referă la începutul blocului de date utile. |
0x0004 | uint(32) | Offset-ul fișierului | Indică la ce offset din întreaga fișier volum se află fișierul. |
0x0008 | uint(32) | Dimensiunea fișierului | Indică cât de mare este fișierul în octeți. |
0x000c | uint(16) | Steaguri? | Se pare că oferă informații suplimentare despre codificarea fișierului.
|
Bloc de volum
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Octeți magici | |
0x0004 | uint(24) | Lungimea blocului | |
0x0007 | uint(8) | Steaguri |
Un volum-block este un container care găzduiește fișiere. Acesta conține doar din nou - datorită formatului block - redundant dimensiunea fișierului, iar apoi urmează direct datele utilizatorului.
Plăci
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Bite magice | |
0x0004 | uint(24) | Lungimea blocului | |
0x0007 | uint(8) | Steaguri |
Tile-urile sunt un format grafic bitmap specific pentru Outpost-2.
Acestea se extind pe 13 seturi de tile-uri, numite "wells"
(well0000.bmp
până la well0012.bmp
),
ce se află în interiorul volumului maps.vol.
În cadrul seturilor de tile-uri / Wells se regăsesc următoarele:
Nume fișier | Conținut |
---|---|
well0000.bmp | O grafică de 32x32px, de culoare albastră - ideală pentru a testa dacă încărcătorul de imagini funcționează |
well0001.bmp | Conține rocă deschisă, lanțuri montane pe roca deschisă și numeroase variante de cratere de impact în rocă deschisă |
well0002.bmp | Conține 'Doodads' din rocă deschisă - adică elemente care pot fi plasate pentru a decora (sau intenționat ca structură, cum ar fi ziduri) pe roca deschisă, inclusiv vegetație |
well0003.bmp | Conține o structură crustată pe roca deschisă |
well0004.bmp | Conține rocă închisă, lanțuri montane pe roca închisă și numeroase variante de cratere de impact în rocă închisă |
well0005.bmp | Conține 'Doodads' din rocă închisă - adică elemente care pot fi plasate pentru a decora (sau intenționat ca structură, cum ar fi ziduri) pe roca închisă |
well0006.bmp | Conține o structură crustată pe roca închisă, precum și tranziții între roca deschisă și cea închisă |
well0007.bmp | Conține lavă, inclusiv 4-5 cadre de animație pentru fiecare |
well0008.bmp | Conține nisip și numeroase variante de cratere de impact în nisip |
well0009.bmp | Conține 'Doodads' din nisip - adică elemente care pot fi plasate pentru a decora (sau intenționat ca structură, cum ar fi ziduri) pe nisip |
well0010.bmp | Conține câte 48 de tranziții de la nisip la rocă deschisă și închisă |
well0011.bmp | Conține capetele polare ale hărții, cu rocă închisă ca substrat |
well0012.bmp | Conține capetele polare ale hărții, cu rocă deschisă ca substrat |
Este recomandat pentru o implementare precisă să nu se redea în avans tile-urile pentru a le salva în cache, deoarece datele pentru ciclul zi/noapte trebuie să fie încă procesate - și ar genera foarte, foarte multe date.
Tile-urile sunt grafice 8bpp cu paletă indexată, fiecare având o rezoluție de 32x32 pixeli, aranjate unele peste altele. Într-un astfel de set de tile-uri pot exista însă mult mai multe
Containerul principal este format din 2 secțiuni: head
și data
.
Antetul Plăcilor
Adr | 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 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Bite magice | |
0x0004 | uint(24) | Lungimea blocului | |
0x0007 | uint(8) | Steaguri | |
0x0008 | uint(32) | Versiune / Steaguri? | Aici ar putea fi vorba despre o indicație de versiune a formatului de fișier; în toate fișierele pe care le am, acest lucru avea valoarea |
0x000c | uint(32) | Lățime (Rezoluție orizontală) | Indică lățimea fișierului de imagine (în pixeli). La toate fântânile din Outpost 2, aici se va aștepta valoarea |
0x0010 | uint(32) | Înălțime (Rezoluție verticală) | Indică cât de mare este fișierul de imagine (în pixeli). La toate fântânile din Outpost 2, aici se va aștepta valoarea |
0x0014 | uint(32) | Adâncimea culorii? | Semnificația acestei valori este necunoscută. Deoarece conține valoarea |
0x0018 | uint(32) | Adâncimea culorii 2? | Semnificația acestei valori este necunoscută. Este posibil să fie vorba despre o adâncime de culoare 'țintă'. |
În urma acestor informații, va urma un fișier de paletă în format RIFF standardizat. Specificația exactă se găsește - deoarece paletele apar și în alte locuri - sub Palete.
Datele Plăcilor
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Bite magice | |
0x0004 | uint(24) | Lungimea blocului | |
0x0007 | uint(8) | Steaguri |
În cele din urmă, urmează datele pixelilor brute, de sus în stânga, pe rând, spre jos dreapta.
Valoarea datelor pentru graficele care sunt de obicei prezentate ca bitmap-uri 8bpp corespunde indexului culorii în paleta de culori.
Engine-ul de joc desenează tile-urile *probabil* la cerere.
Asta pare să se datoreze, printre altele, ciclului zi-noapte, care cunoaște 32 de nuanțe ale tile-urilor individuale. Se pare că de fiecare dată se scade 'puțin' din valoarea de luminozitate. Valorile exacte nu au fost încă stabilite, lucrez pe baza calculelor
v *= (daylight / 48) + 0.25;
cu datele HSV ale pixelilor, unde daylight este o valoare de 0-31 iar v este o valoare între 0-1. În plus, trebuie să se țină cont că pe hartă există câte un margine de 16 tile-uri pe stânga și pe dreapta (acesta servește pentru spawn-ul invizibil al unităților).
În plus, ciclul zi-noapte pare să actualizeze doar o coloană a hărții pentru fiecare ciclu de joc.
Un ciclu zi-noapte accelerat arată astfel:
PRT
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Bytes magice | |
0x0004 | uint(24) | Lungimea paletelor | Indică, spre deosebire de formatul normal de bloc, numărul de palete care se găsesc în acest fișier - nu lungimea blocului în octeți. |
0x0007 | uint(8) | Steaguri | Probabil, ca de obicei, steaguri. Cu toate acestea, nu cunosc niciun steag; deoarece toate valorile pe care le cunosc corespund cu |
Ce înseamnă exact PRT
nu știu; o posibilitate ar fi, de exemplu, 'Palette and Resource Table' - deoarece acest fișier - găsit sub numele op2_art.prt în maps.vol - este unul de acest tip, sau aceasta ar descrie destul de bine funcția sa.
Această fișier conține o listă de palete, o tabelă cu toate bitmap-urile utilizate, toate definițiile animațiilor și o serie de date necunoscute. Urmează în mod liber formatul de container precedent, deoarece nu toate înregistrările respectă acest schema.
Secțiunea CPAL
(probabil pentru container de palete) cuprinde doar datele paletei, specificând câte dintre paletele de 8 biți, fiecare având de obicei 1052 de octeți, sunt prezente.
Mențiunea de 1052 de octeți nu este considerată obligatorie, deoarece formatul paletei ar putea prevedea dimensiuni diferite ale paletelor. Aceasta se aplică doar pentru setul de date cu care este livrat Outpost 2.
După listele de palete urmează imediat, fără un antet introductiv, lista de bitmap-uri; imediat după acestea urmează listele de animații.
Ambele sunt inițiate cu un uint(32) (sau din nou uint24+uint8 steaguri?) care conține numărul de înregistrări.
Palete
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Bytes Magice | |
0x0004 | uint(24) | Lungimea paletelor | Indică, spre deosebire de formatul de bloc normal, numărul de palete care pot fi găsite în acest fișier - nu lungimea blocului în octeți. |
0x0007 | uint(8) | Steaguri | Probabil, ca de obicei, steaguri. Totuși, nu cunosc niciun steag; deoarece toate valorile cunoscute de mine corespund |
Informațiile despre palete sunt foarte ușor de citit.
Acestea constau fiecare dintr-un antet și un segment de date.
Antet Palet
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Bytes Magice | |
0x0004 | uint(24) | Lungimea paletelor | Indică, spre deosebire de formatul de bloc normal, numărul de palete care pot fi găsite în acest fișier - nu lungimea blocului în octeți. |
0x0007 | uint(8) | Steaguri | Probabil, ca de obicei, steaguri. Totuși, nu cunosc niciun steag; deoarece toate valorile cunoscute de mine corespund |
0x0008 | uint(32) | Versiunea formatului paletelor? | Probabil definește ce versiune a formatului paletelor urmează paleta. Toate paletele Outpost2 par să aibă versiunea |
Datele paletelor
Adr | 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 | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Bytes Magice | |
0x0004 | uint(24) | Lungimea blocului | |
0x0007 | uint(8) | Steaguri |
Sețiunea de date conține înregistrările individuale ale paletelor. Numărul de înregistrări ale paletelor rezultă din lungimea blocului / 4.
Înregistrările individuale au următoarea structură simplă;
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caractere | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | 04 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(8) | Componenta roșie | Indică proporția de roșu din culoare |
0x0001 | uint(8) | Componenta verde | Indicã procentul de verde din culoare |
0x0002 | uint(8) | Componentea albastră | Indică proporția de albastru a culorii |
0x0003 | uint(8) | Necunoscut - Steaguri? | Nu este clar ce înseamnă această valoare, deoarece aparent este în mod fundamental |
În legătură cu paletele, mai trebuie spus că pentru paletele utilizate în animații, se aplică următoarele reguli:
- Prima culoare este ÎNTOTDEAUNA transparentă, indiferent de valoarea specificată acolo.
-
Intrările din palete 1-24 sunt considerate ca fiind culorile jucătorilor în paletele 1-8.
De unde provin culorile în afara de jucătorul 1, nu este clar pentru mine.
Presupun că celelalte culori sunt hardcoded.
Bitmap-uri
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caractere | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Lățimea orientată | Indică lățimea liniilor de date pixel în octeți - deoarece acestea sunt aliniate la limitele de 4 octeți. Așadar, este rapid posibil să se acceseze o anumită linie de imagine. De ce această valoare este stocată separat, deși ar putea fi calculată, nu este clar. |
0x0004 | uint(32) | Offset | Indică offsetul primei linii din bitmap |
0x0008 | uint(32) | Înălțime | Indicã înălțimea imaginii în pixeli |
0x000c | uint(32) | Lățime | Indică lățimea imaginii în pixeli |
0x0010 | uint(16) | Tip | Indică tipul imaginii. Se pare că este vorba despre o mască pe biți:
|
0x0012 | uint(16) | Paletă | Defineste care paletă din fișierul PRT ar trebui utilizată |
Structura de date a fișierului PRT indică modul în care sunt construite bitmap-urile folosite pentru sprite-uri. Aceste bitmap-uri servesc ca elemente individuale, din care mai multe sunt asamblate într-un cadru de animație al unui sprite.
Datele specifice ale imaginii se ascund în
op2_art.BMP din directorul jocului.
Motivul pentru care acest fișier bitmap are un antet RIFF (preponderent corect) este neclar. Probabil că Outpost 2 folosește API-uri de sistem pentru a încărca grafica, preluând temporar acest antet și suprascriend câmpurile corespunzătoare, variabile.
Datele pixelilor se găsesc în fișierul BMP la poziția Offset + offset uint32, ceea ce se găsește în fișierul BMP la adresa 0x000A (offset-ul datelor RIFF-Bitmap), și corespund din nou aranjării pe linii de sus în stânga spre dreapta jos.
Graficile monocrome 1bpp pot fi desenate astfel încât culoarea 0 să fie complet transparentă, iar culoarea 1 să fie un negru/gri semi-transparent, deoarece graficele monocrome sunt de obicei utilizate pentru umbrele vehiculelor și clădirilor în animații.
Astfel, se pot asambla deja multe grafice.
Animații
Acum ajungem la clasa regală a disciplinelor din formatele de date Outpost 2:
Animatiile.
Listelor de animație le precede un header global, care servește în principal pentru verificarea datelor. Apoi urmează definițiile concrete ale animațiilor, care se împart în 3 niveluri:
-
Animație
O animație este cea mai înaltă instanță; ea reprezintă o animație a unei unități, a unei clădiri sau a unei 'animații de particule' (impact de cometă, vreme, explozie) într-o anumită situație inițială. -
Cadru
Un cadru este o imagine unică în cadrul unei animații. O animație poate conține unul sau mai multe cadre. -
Subcadru
Un subcadru reprezintă informația că o anumită bitmap trebuie desenată într-o anumită poziție a unui cadru, conform unor criterii specifice. Un cadru poate conține unul sau mai multe subcadre.
Apoi urmează direct definițiile individuale ale animațiilor.
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caractere | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Numărul de animații | Câte seturi de date de animație există |
0x0004 | uint(32) | Numărul de cadre | Câte cadre ar trebui să existe în total |
0x0008 | uint(32) | Numărul de subcadre | Câte subcadre ar trebui să fie în total |
0x000c | uint(32) | Numărul de intrări opționale | Câte "înregistrări opționale" sunt disponibile. |
Animatie
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caractere | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0020 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(32) | Necunoscut 1 | Informații necunoscute |
0x0004 | uint(32) | Cutie de delimitare: Stânga | Indică începutul din stânga (în pixeli) al Bounding Box. |
0x0008 | uint(32) | Bounding Box: Sus | Indică începutul superior (în pixeli) al Bounding Box. |
0x000c | uint(32) | Bounding Box: Lățime | Indică lățimea (în pixeli) a Bounding Box. |
0x0010 | uint(32) | Cutie de delimitare: Înălțime | Indică înălțimea (în pixeli) a Bounding Box. |
0x0014 | uint(32) | Offset: X | Indică punctul mediu orizontal al animației |
0x0018 | uint(32) | Offset: Y | Indică mijlocul vertical al animației |
0x001c | uint(32) | Necunoscut 2 | Informație necunoscută |
0x0020 | uint(32) | Numărul de cadre | Indică câte cadre de animație sunt incluse în această animație |
0x0024 | uint(32) | Numărul de feronerie Windows | Indică câte feronerie trebuie utilizate la desenare |
Datele stratului superior, al animației, sunt în principal date administrative - Boundingbox se referă la coordonatele marcajului din jurul vehiculului/clădirii, atunci când acesta este selectat și indică, de asemenea, care zonă poate fi clicată.
Offset-ul determină în principal „punctul zero”; punctul care trebuie adunat sau scăzut în coordonatele interne ale jocului. Pot să spun și mai matematic: offset-ul se referă aici la originea coordonatelor.
Windows-urile sunt, la fel ca offset-ul, formate din câte 4 valori uint(32) fiecare, ce indică o zonă care este considerată utilizabilă pentru subframe-uri individuale. În afara Windows-urilor, nu se poate desena, cu condiția ca acest lucru să fie prevăzut pentru bitmap.
Cadru
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caractere | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(8) | Numărul de subcadre și comutator pentru Opțional 1, 2 | Acest valor conține:
|
0x0001 | uint(8) | Unknow 1 și Toggle pentru Opțional 3, 4 | Acest valor conține:
|
0x0002 | uint(8) | Opțional 1 | Necunoscut |
0x0003 | uint(8) | Opțional 2 | Necunoscut |
0x0004 | uint(8) | Opțional 3 | Necunoscut |
0x0005 | uint(8) | Opțional 4 | Necunoscut |
Subcadru
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | caractere | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Offset | Tip de date | Denumire | Explicație |
---|---|---|---|
0x0000 | uint(16) | Bitmap-ID | Indică ce bitmap să fie folosit pentru acest subcadru |
0x0002 | uint(8) | Necunoscut 1 | Este necunoscut - totuși, bănuiesc cu tărie că este vorba despre o prioritate de redare (Z-Layer). |
0x0003 | uint(8) | Subframe-Id | Indică în ce subcadru ne aflăm |
0x0004 | sint(16) | Offset - Orizontal | Indică unde în cadrul paginii trebuie să fie plasat subcadru, sau cu câți pixeli trebuie să fie mutată bitmap-ul pe orizontală |
0x0006 | sint(16) | Offset - Vertical | Indică unde în cadrul frame-ului ar trebui plasat subframe-ul, respectiv cu câte pixeli ar trebui să fie mutată bitmap-ul pe verticală. |
Astfel putem acum să combinăm cadre individuale, precum și animații complete, demonstrând aici, exemplificativ, o animație mai complexă, animația cu indexul 500
Animatie 500
Animatia 500 arată cum un transportor Plymouth, încărcat cu minereu obișnuit, este descărcat. Aceasta este una dintre puținele animații care utilizează funcționalitatea de feronerie.
Și astfel se poate asambla întreaga animație.
Din păcate, există încă o problemă cu hubloul superior, deoarece bitul corespunzător din informațiile despre tipul grafic nu este setat.
Iată câteva alte sprite-uri frumos animate din joc:
Interfață utilizator
Acum lipsește doar interfața utilizatorului jocului, care este realizată într-un aspect de metal periat.
Cu toate acestea, este clar că Dynamix nu a fost nevoit să reinventeze roata; aici nu sunt utilizate doar simplu API-urile User32 și GDI32 furnizate de Windows - în special este folosit și managementul resurselor din User32.
Aceasta poate fi extrasă, de exemplu, prin programe precum Resource Hacker, dezvoltat ca software gratuit de Angus Johnson, sau - dacă se evită utilizarea Wine pe Linux / Mac OS - cu ajutorul wrestool inclus în icoutils.
Numele fișierului | Conținut |
---|---|
Outpost2.exe | Conține doar pictograma jocului, care arată stația spațială din New Terra |
op2shres.dll | Conține, pe lângă grafica pentru elementele de control precum margini, butoane, butoane radio și casete de selectare, și fundaluri pentru dialoguri, imagini de acompaniament pentru textele misiunii din poveste și grafică de fundal pentru meniul principal |
out2res.dll | Conține decorația feronerie a ferestrelor din joc, pictograme pentru metal obișnuit și special, ecranul de încărcare, grafica pentru dialoguri, precum și alte grafice de cursor, în plus față de cele animate din directorul jocului |