Outpost 2 Filformater · bei.pm
Filformatene beskrevet på denne siden er basert på teknisk analyse av åndsverk fra Dynamix, Inc. og Sierra Entertainment.
Åndsverket er i dag en del av Activision Publishing, Inc. / Activision Blizzard, Inc. og eies for øyeblikket av Microsoft Corp..
Informasjonen er samlet inn gjennom Reverse Engineering og dataanalyse for arkiverings- og interoperabilitetsformål med historiske data.
Ingen proprietære eller konfidensielle spesifikasjoner har blitt brukt.
Spillet kan nå kjøpes som nedlasting på gog.com.
Denne artikkelserien dokumenterer mine funn om dataformater i sanntidsstrategispillet "Outpost 2: Divided Destiny", som ble utgitt av Sierra i 1997 og utviklet av Dynamix.
Jeg har hovedsakelig arbeidet med analysen av spillets data - og hva man kan gjøre med dem - fra 1. november 2015 til 14. november 2015.
I henhold til informasjonen jeg har kunnet samle så har Dynamix - som så mange kommersielle selskaper - ikke utviklet noen dataformater spesifikt for Outpost 2, men også brukt dem i andre utviklinger som for eksempel Mechwarrior-serien (modifisert).
Uavhengig av dette kan det også påpekes at innovasjonskraften i dataformatene stort sett er begrenset, og ofte bygger på langt eksisterende konsepter fra vanlige formater som JFIF og RIFF.
For tolkning av tabeller og dataformater er det mer informasjon tilgjengelig under Hva er hva?.
De oppgitte dataene skal generelt forstås som Little Endian.
Avslutningsvis kan det sies at reverse engineering var veldig gøy, selv om det ikke er fullstendig.
Selvfølgelig kan jeg også anbefale å spille spillet selv, da det tilbyr interessante spillmekanikker.
Introduksjon
Dataformatene som brukes av Outpost 2 har en struktur som minner om JFIF / PNG - de enkelte datablokkene har alltid en 8 Byte header. Dermed velger jeg å unngå å dokumentere de enkelte headerne på de spesifikke stedene, og dokumenterer bare avvikene der.
Formatet er alltid det følgende; de faktiske nyttedataene er deretter innebygd i det:
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske bytes | Inneholder informasjon om hva som kan forventes i den neste datablokken. Kjente verdier:
|
0x0004 | uint(24) | Blokklengde | Inneholder informasjon om hvor stor (i byte) den følgende datablokken er. Her menes de rene nyttedataene - de 8 header-byte er ikke inkludert. |
0x0007 | uint(8) | Flagger? | Det er ukjent hva denne blokken nøyaktig brukes til. I volumene er denne verdien ofte 0x80, mens den i andre filer ofte er 0x00. Dette tyder på at det er et flaggsett. |
Volumer
Volumer er en databeholder for spillet, lignende et arkivformat som for eksempel Tarball. I hvert fall i Outpost 2 kjenner formatet kun filer - ingen mapper. Det er sannsynlig at disse imidlertid kan simuleres gjennom passende filnavn.
Ett volum består av volumheaderen samt flere volumblokker som tilsvarer de konkrete filene.
"Volumer" er filene med filendelsen 'vol'
i spillkatalogen.
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 56 | 4f | 4c | 20 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | V | O | L | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske byte | |
0x0004 | uint(24) | Blokklengde | |
0x0007 | uint(8) | Flagg |
Volumoverskrift
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 68 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | h | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske byte | |
0x0004 | uint(24) | Blokklengde | |
0x0007 | uint(8) | Flagg |
Volumenkoppen inneholder ingen nyttedata.
Den fungerer kun som en beholder.
Som den første datoen i volumkappen skal volumstrenger være; deretter følger voluminformasjonen.
Volumstrenger
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 69 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | i | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske byte | |
0x0004 | uint(24) | Blokklengde | |
0x0007 | uint(8) | Flagg |
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 73 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | s | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske byte | |
0x0004 | uint(24) | Blokklengde | |
0x0007 | uint(8) | Flagg | |
0x0008 | uint(32) | Payload-lengde | Angir hvor mange bytes av de følgende dataene som faktisk er nyttige data. De resterende dataene i volum-strenglisten anses å være garbage. I filer med senere datoer er disse 'resterende dataene' 0x00, noe som kan tyde på mangler med verktøykjeden under utviklingen av spillet, med andre ord at en utvikler først tok seg av korrekt initialisering av buffrene veldig sent, siden det ikke påvirker spillet om dataene er initialisert eller ikke. |
0x000c | uint(8)[] | Filnavn-liste | Dette er en 0-byte terminert liste over filnavn, som - i det nåværende datainnholdet - bare forventer ASCII-tegn. Det er ikke nødvendig å evaluere denne datablokken nærmere når man parser dataene, siden offsetene til filnavnene allerede refereres direkte i voluminformasjonen. |
Volumetekstene er en liste over filnavn som finnes innenfor volumet.
Voluminformasjon
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 69 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | i | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske byte | |
0x0004 | uint(24) | Blokklengde | |
0x0007 | uint(8) | Flagg |
Voluminformasjonen inneholder mer detaljerte opplysninger om filene. Dette er på en måte en slags FAT-katalogoppføring (FAT = File Allocation Table).
Antall filer beregnes ved å dele blokkstørrelsen på lengden av katalogoppføringene - 14 byte.
Hver enkelt katalogoppføring har følgende oppbygning:
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Filnavn-forskyvning | Angir hvilken offset (!) innenfor filnavnlisten (volumstrenger) filnavnet til filen finnes. Dette refererer til starten av nyttelastblokken. |
0x0004 | uint(32) | Fil-offset | Angir hvor i volumefilen filen befinner seg. |
0x0008 | uint(32) | Filstørrelse | Angir hvor stor filen er i byte. |
0x000c | uint(16) | Flagger? | Ser ut til å gi ekstra informasjon om filkoding.
|
Volumblokk
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 56 | 42 | 4c | 48 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | V | B | L | H | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske byte | |
0x0004 | uint(24) | Blokklengde | |
0x0007 | uint(8) | Flagg |
En volumeblok er en beholder som tar opp filer. Den inneholder bare en gang til - på grunn av blokkformatet - redundant filstørrelsen, og deretter følger bruksdataene direkte.
Fliser
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 50 | 42 | 4d | 50 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | P | B | M | P | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske byte | |
0x0004 | uint(24) | Blokklengde | |
0x0007 | uint(8) | Flagg |
Tiles er et spesifikt bitmapgrafikkformat for Outpost-2. De strekker seg over 13 tilesett, kalt "wells" (well0000.bmp
til well0012.bmp
), som finnes innenfor volumet maps.vol.
Tilesett / Wells inneholder følgende:
Filnavn | Innhold |
---|---|
well0000.bmp | En 32x32px stor, blå grafikk - ideell for å teste om din egen bilde-loader fungerer |
well0001.bmp | Inneholder lyst berg, fjellkjeder på lyst berg og utallige varianter av nedslagskrater i lyst berg |
well0002.bmp | Inneholder 'Doodads' i lyst berg - elementer som kan plasseres for å bryte opp (eller bevisst som struktur, som f.eks. murer) på lyst berg, inkludert vegetasjon |
well0003.bmp | Inneholder en skorpeaktig struktur på lyst berg |
well0004.bmp | Inneholder mørkt berg, fjellkjeder på mørkt berg og utallige varianter av nedslagskrater i mørkt berg |
well0005.bmp | Inneholder 'Doodads' i mørkt berg - elementer som kan plasseres for å bryte opp (eller bevisst som struktur, som f.eks. murer) på mørkt berg |
well0006.bmp | Inneholder en skorpeaktig struktur på mørkt berg, samt overganger mellom lyst og mørkt berg |
well0007.bmp | Inneholder lava inkludert 4-5 rammer av animasjonen av den |
well0008.bmp | Inneholder sand og utallige varianter av nedslagskrater i sand |
well0009.bmp | Inneholder 'Doodads' i sand - elementer som kan plasseres for å bryte opp (eller bevisst som struktur, som f.eks. murer) på sand |
well0010.bmp | Inneholder 48 overganger fra sand til lyst og mørkt berg |
well0011.bmp | Inneholder polarområdene på kartet, med mørkt berg som bakgrunn |
well0012.bmp | Inneholder polarområdene på kartet, med lyst berg som bakgrunn |
Det anbefales å ikke rendre flisene på forhånd for å cache dem, da dataene for dag/natt-syklusen fortsatt må bearbeides - og det ville genereres veldig mange data.
Flisene er 8bpp-grafikk med indeksert palett, hver med en oppløsning på 32x32 piksler, og de er ordnet i rader. I et slik flisesett kan det imidlertid være betydelig flere
Hovedbeholderen består av 2 seksjoner: head
og data
.
Fliser Hode
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 68 | 65 | 61 | 64 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | h | e | a | d | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske byte | |
0x0004 | uint(24) | Blokklengde | |
0x0007 | uint(8) | Flagg | |
0x0008 | uint(32) | Versjon / Flagg? | Dette kan være en versjonsangivelse av filformatet; i alle filer jeg har, stod det her verdien |
0x000c | uint(32) | Bredde (Horisonal oppløsning) | Angir hvor bred bildefilen er (i piksler). For alle brønnene i Outpost 2 vil verdien her være |
0x0010 | uint(32) | Høyde (Vertikal oppløsning) | Angir hvor høy bildefilen er (i piksler). For alle brønnene i Outpost 2 vil verdien her være |
0x0014 | uint(32) | Fargedybde? | Betyden av denne verdien er ukjent. Siden den inneholder verdien |
0x0018 | uint(32) | Fargedybde 2? | Betyden av denne verdien er ukjent. Det kan være en 'mål'-fargedybde. |
I henhold til disse opplysningene vil det også bli presentert en palettfil i standardisert RIFF-format. Den nøyaktige spesifikasjonen finnes - siden palettene også dukker opp andre steder - under Paletter.
Fliser Data
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 64 | 61 | 74 | 61 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | d | a | t | a | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske byte | |
0x0004 | uint(24) | Blokklengde | |
0x0007 | uint(8) | Flagg |
Til slutt følger de rå pikseldataene, fra øverst til venstre radvis mot nederst til høyre.
Datastrengen for grafikkene, som vanligvis foreligger som 8bpp-bitmaper, tilsvarer indeksen til fargen i fargepaletten.
Spillmotoren tegner sannsynligvis *tiles* etter behov.
Dette ser ut til å skyldes dag- og natt-syklusen, som har 32 nyanser av individuelle tiles. Det ser ut til at det trekkes 'litt' fra lysverdi. Nøyaktige verdier har ennå ikke blitt fastslått, jeg jobber med beregningsgrunnlaget
v *= (daylight / 48) + 0.25;
med HSV-dataene til pikslene, der daylight er en verdi fra 0-31 og v er en verdi mellom 0-1. I tillegg må det tas hensyn til at det på kartet er en rand på 16 tiles til venstre og høyre (som tjener til usynlig spawne av enheter).
I tillegg ser det ut til at dag- og natt-syklusen oppdaterer kun én kolonne av kartet per spillsyklus.
En akselerert dag- og natt-syklus ser derfor slik ut:
PRT
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 43 | 50 | 41 | 4c | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | C | P | A | L | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske bytes | |
0x0004 | uint(24) | Palettlengde | Angi, i motsetning til normalt blokkformat, antallet paletter som finnes i denne filen - ikke lengden på blokken i byte. |
0x0007 | uint(8) | Flagg | Sannsynligvis, som vanlig, flagg. Jeg kjenner imidlertid ikke til noen flagg; siden alle kjente verdier tilsvarer |
Hva PRT
står for er meg ukjent; det kan for eksempel være 'Palette and Resource Table' - siden denne filen - som finnes som op2_art.prt i maps.vol - faktisk er en slik fil, eller dette ville beskrive funksjonen ganske bra.
Denne filen inneholder en liste over paletter, en tabell over alle brukte bitmap-er, alle animasjonsdefinisjoner og en rekke ukjente data. Den følger den tidligere containerformatet løst, da ikke alle datasett følger dette skjemaet.
CPAL
-seksjonen (som sannsynligvis står for palettcontainer) omfatter bare palettdataene, ved å angi hvor mange av de vanligvis 1052 byte store 8-bit paletter som er til stede.
1052-byte-angivelsen anses ikke som bindende, da palettformatet potensielt kan ha forskjellige palettstørrelser. Den gjelder bare for datamaterialet som Outpost 2 leveres med.
Etter palettlistene følger umiddelbart, uten innledende overskrift, listen over bitmap-er; deretter følger animasjonslistene umiddelbart.
Begge innledes med en uint(32) (eller igjen uint24+uint8 flagg?) som inneholder antall datasett.
Paletter
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 50 | 50 | 41 | 4c | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | P | P | A | L | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske Byte | |
0x0004 | uint(24) | Pallelengde | Angi, i motsetning til normalt blokkformat, antall paletter som finnes i denne filen - ikke lengden på blokken i byte. |
0x0007 | uint(8) | Flagg | Sannsynligvis, som vanlig, flagg. Jeg kjenner imidlertid ikke til noen flagg; siden alle kjente verdier tilsvarer |
Paletteinformasjonen er veldig enkel å lese.
Den består alltid av en header og et datasegment.
Palett-overskrift
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 68 | 65 | 61 | 64 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | h | e | a | d | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske Byte | |
0x0004 | uint(24) | Pallelengde | Angi, i motsetning til normalt blokkformat, antall paletter som finnes i denne filen - ikke lengden på blokken i byte. |
0x0007 | uint(8) | Flagg | Sannsynligvis, som vanlig, flagg. Jeg kjenner imidlertid ikke til noen flagg; siden alle kjente verdier tilsvarer |
0x0008 | uint(32) | Palettformat-versjon? | Definerer sannsynligvis hvilken versjon av palettformatet paletten følger. Alle Outpost2-paletter ser ut til å ha versjon |
Palettedata
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 64 | 61 | 74 | 61 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | d | a | t | a | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Magiske Byte | |
0x0004 | uint(24) | Blokklengde | |
0x0007 | uint(8) | Flagg |
Datasetet inneholder de enkelte palloppføringene. Antallet palloppføringer er basert på blokkens lengde / 4.
De enkelte oppføringene har en enkel struktur som følger;
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | 04 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(8) | Rød komponent | Angir den røde andelen av fargen |
0x0001 | uint(8) | Grønn komponent | Angir den grønne andelen av fargen |
0x0002 | uint(8) | Blå komponent | Angir den blå andelen av fargen |
0x0003 | uint(8) | Ukjent - Flagg? | Det er uklart hva denne verdien betyr, da den tilsynelatende er grunnleggende |
Når det gjelder palettene, er det ellers bare å si at følgende regler gjelder for paletter som skal brukes til animasjoner:
- Den første fargen er ALLTID transparent, uansett hvilken verdi som angis der.
-
Palettoppføringene 1-24 regnes som spillerfarge i palett 1-8.
Hvor fargene utenom spiller 1 egentlig kommer fra, er uklart for meg.
Jeg antar at de resterende fargene er hardkodet.
Bitmaper
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Justert bredde | Angir bredden på pikseldata-linjene i byte - siden disse er justert til 4-byte-grenser. Dermed er det raskt mulig å hoppe til en bestemt bildelinje. Hvorfor denne verdien lagres separat, selv om den kunne blitt beregnet, er uklart. |
0x0004 | uint(32) | Offset | Angir offsetet for den første linjen i bitmapen |
0x0008 | uint(32) | Høyde | Angir høyden på bildet i piksler |
0x000c | uint(32) | Bredde | Angir bredden på bildet i piksler |
0x0010 | uint(16) | Typ | Angir type bildet. Her ser det ut til å være en bitmaske:
|
0x0012 | uint(16) | Palett | Definerer hvilken palett som skal brukes fra PRT-filen |
Denne datastrukturen i PRT-filen angir hvordan bitmapene som brukes for sprites er bygget opp. Disse bitmapene fungerer som enkeltkomponenter, hvor flere settes sammen til et animasjonsramme for en sprite.
De konkrete bildedataene finnes derimot i
op2_art.BMP i spillmappen.
Hvorfor denne bitmapfilen har en (for det meste korrekt) RIFF-bitmapheader, er uklart. Sannsynligvis bruker Outpost 2 system-API-er for å laste grafikken, ved midlertidig å overta denne headeren og overskrive de relevante, varierende feltene.
Pixeldatas er plassert i BMP-filen på Offset + uint32-offset, som kan finnes i BMP-filen på adresse 0x000A (RIFF-bitmap-dataoffset), og dette tilsvarer igjen radvis oppstilling fra øverste venstre til nederste høyre.
Monokrome 1bpp-grafikker kan tegnes slik at farge 0 er fullstendig gjennomsiktig, mens farge 1 er et halvtransparent svart/grått, da monokromgrafikk vanligvis brukes for skygger av kjøretøy og bygninger i animasjonene.
Dette gjør at man allerede kan sette sammen mange grafikker.
Animasjonene
Nå kommer vi til toppen av disiplinene innen Outpost 2 dataformater:
Animasjonene.
Animasjonslistene innledes med en global header, som primært tjener til dataverifisering. Deretter følger de konkrete animasjonsdefinisjonene, som deles inn i 3 nivåer:
-
Animasjon
En animasjon er den øverste instansen; den representerer en animasjon av en enhet, en bygning eller en 'partikkel-animasjon' (kometnedslag, vær, eksplosjon) i en bestemt startposisjon. -
Bilde
Et bilde er et enkelt bilde innen en animasjon. En animasjon kan inneholde ett eller flere bilder. -
Underbilde
Et underbilde er informasjonen om at et bestemt bitmap skal tegnes på en bestemt plassering av et bilde under visse kriterier. Et bilde kan inneholde ett eller flere underbilder.
Deretter følger de individuelle animasjonsdefinisjonene.
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Antall animasjoner | Hvor mange animasjonsdatasett finnes |
0x0004 | uint(32) | Antall rammer | Hvor mange rammer bør det totalt være |
0x0008 | uint(32) | Antall delrammer | Hvor mange subrammer burde det totalt være |
0x000c | uint(32) | Antall valgfrie oppføringer | Hvor mange "valgfri oppføringer" finnes. |
Animasjon
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0020 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(32) | Ukjent 1 | Ukjente opplysninger |
0x0004 | uint(32) | Innpakningsboks: Venstre | Angir den venstre starten (i piksler) av Bounding Box. |
0x0008 | uint(32) | Avgrensningsboks: Øverst | Angir den øverste starten (i piksler) av Bounding Box. |
0x000c | uint(32) | Avgrensningsboks: Bredde | Angir bredden (i piksler) av Bounding Box. |
0x0010 | uint(32) | Avgrensningsboks: Høyde | Angir høyden (i piksler) på Bounding Box. |
0x0014 | uint(32) | Offset: X | Angir den horisontale midtpunktet for animasjonen |
0x0018 | uint(32) | Offset: Y | Angir den vertikale midtpunktet for animasjonen |
0x001c | uint(32) | Ukjent 2 | Ukjent informasjon |
0x0020 | uint(32) | Antall rammer | Angir hvor mange animasjonsrammer som er inkludert i denne animasjonen |
0x0024 | uint(32) | Antall vinduer | Angir hvor mange vinduer som skal brukes ved tegning |
Dataene til det øverste laget, animasjonen, er primært administrasjonsdata - Boundingbox refererer til koordinatene til markeringen rundt kjøretøyet/bygningen, når det er valgt, og indikerer samtidig hvilket område som skal være klikkbart.
Offsetet bestemmer primært "nullpunktet"; punktet som skal legges til eller trekkes fra i henhold til interne spillkoordinater. Man kan også si mer matematisk: offsetet betegner her koordinatsystemets opprinnelse.
Når det gjelder vinduene, er de, akkurat som offsetet, hver av dem (per vindu) 4 uint(32)-verdier, som angir et område som anses som brukbart for individuelle subrammer. Utenfor vinduene skal man ikke tegne, med mindre det er spesifisert for bitmapen.
Ramme
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(8) | Subframe-antall og Toggle for Valgfri 1, 2 | Denne verdien inneholder:
|
0x0001 | uint(8) | Unbekannt 1 og Toggle for Valgfritt 3, 4 | Denne verdien inneholder:
|
0x0002 | uint(8) | Valgfritt 1 | Ukjent |
0x0003 | uint(8) | Valgfritt 2 | Ukjent |
0x0004 | uint(8) | Valgfritt 3 | Ukjent |
0x0005 | uint(8) | Valgfri 4 | Ukjent |
Underramme
Adr | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | tegn | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Forskyvning | Datatype | Betegnelse | Forklaring |
---|---|---|---|
0x0000 | uint(16) | Bitmap-ID | Angir hvilken bitmap som skal brukes for denne subrammen |
0x0002 | uint(8) | Ukjent 1 | Er ukjent - jeg mistenker imidlertid sterkt at dette handler om en renderprioritet (Z-lag). |
0x0003 | uint(8) | Subramme-ID | Angir i hvilken underramme vi befinner oss |
0x0004 | sint(16) | Offset - Horisontal | Angir hvor innenfor rammen underrammen skal plasseres, eller hvor mange piksler bitmapen skal flyttes horisontalt |
0x0006 | sint(16) | Offset - Vertikal | Angir hvor innenfor rammen underrammen skal plasseres, eller hvor mange piksler bitmapet skal flyttes vertikalt |
Med dette kan vi nå sette sammen enkeltstående rammer, så vel som komplette animasjoner. Her demonstreres det med et eksempel på en mer kompleks animasjon, animasjonen med indeksen 500.
Animasjon 500
Animasjon 500 viser hvordan en Plymouth-fraktbil, som er lastet med vanlig malm, blir losset. Dette er en av de få animasjonene som bruker vindusfunksjonaliteten.
Og slik kan den komplette animasjonen settes sammen.
Dessverre er det fortsatt et problem med den øverste lasteluken, da det aktuelle bitet i grafikktypens informasjon ikke er satt.
Her er noen flere, vakkert animerte sprites fra spillet:
Brukergrensesnitt
Nå mangler vi bare brukergrensesnittet til spillet, som har et børstet metall-utseende.
Men også her er det tydelig at Dynamix ikke måtte finne opp hjulet på nytt; her brukes ikke bare de enkle funksjonene fra User32- og GDI32-APIene som tilbys av Windows - spesielt benyttes også ressursstyringen fra User32.
Disse kan for eksempel ekstraheres ved hjelp av programmer som Resource Hacker, utviklet som freeware av Angus Johnson, eller - hvis man unngår å bruke Wine på Linux / Mac OS - ved hjelp av wrestool som er inkludert i icoutils.
Filnavn | Innhold |
---|---|
Outpost2.exe | Inneholder kun ikonet til spillet, som viser romstasjonen foran New Terra |
op2shres.dll | Inneholder i tillegg til grafikk for kontroller som rammer, knapper, radioknapper og avkrysningsbokser også dialogbakgrunner, tilleggsbilder for story-misjonstekster og bakgrunnsgrafikken for hovedmenyen |
out2res.dll | Inneholder in-game vindusdekorasjoner, ikoner for vanlig og spesialmetall, lasteskjermen, grafikk for dialoger samt andre musepekergrafikker, i tillegg til de animerte i spillkatalogen |