Outpost 2 File Formats · bei.pm

This text was automated translated by OpenAI GPT-4o Mini.

The file formats described on this page are based on the technical analysis of intellectual property by Dynamix, Inc. and Sierra Entertainment.
The intellectual property is now part of the Activision Publishing, Inc. / Activision Blizzard, Inc. estate and is currently owned by Microsoft Corp..

The information has been gathered through Reverse Engineering and Data Analysis for the purposes of archiving and interoperability with historical data.
No proprietary or confidential specifications were used.

The game is currently available for purchase as a download at gog.com.

Artwork of the game

The following series of articles documents my findings regarding the data formats in the real-time strategy game "Outpost 2: Divided Destiny", which was released by Sierra in 1997 and developed by Dynamix.

I focused primarily on analysing the game's data - and what to do with it - from around 1st November 2015 to 14th November 2015.

According to the information I have been able to gather so far, Dynamix - like many commercial companies - did not develop certain data formats specifically for Outpost 2, but also used them in other projects such as the Mechwarrior series (with modifications).
Regardless, it can also be noted that the innovative capacity of the file formats is quite limited and often builds on long-established concepts from common formats such as JFIF and RIFF.

Further information for interpreting the tables and data formats can be found under What is what?.
The data provided here is generally to be understood as Little Endian.

In conclusion, it can be said that reverse engineering was a lot of fun, even though it is not complete.
Of course, I can also only recommend playing the game yourself, as it offers interesting game mechanics.

Introduction

The data formats used by Outpost 2 have a structure reminiscent of JFIF/PNG - each data block always has an 8-byte header. Therefore, I will refrain from documenting the individual headers at the respective specific points and will only document deviations there.

The format is always as follows; the actual payload is then embedded within it:

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes

Contains information about what to expect in the next data block.

Known values:

  • 0x204C4F56 ('VOL '):
    Volume
  • 0x686C6F76 ('VOLH'):
    Volume Header
  • 0x736C6F76 ('VOLS'):
    Volume Strings
  • 0x696C6F76 ('VOLI'):
    Volume Information
  • 0x4B4C4256 ('BLCK'):
    Volume Block
  • 0x504D4250 ('PBMP'):
    Graphic Data
  • 0x4C415050 ('PPAL'):
    Colour Palette
  • 0x4C415043 ('CPAL'):
    Colour Palette Container
  • 0x64616568 ('head'):
    Header
  • 0x61746164 ('data'):
    User Data
0x0004 uint(24) Block length

Contains information about the size (in bytes) of the following data block.

This refers specifically to the raw payload data - the 8 header bytes are not included.

0x0007 uint(8) Flags?

It is unknown what this block is specifically used for.

In the volumes, this value is often 0x80, while in other files it is frequently 0x00. This suggests that it is a flag set.

Volumes

The volumes are a data container for the game, similar to an archive format like a tarball. At least in Outpost 2, the format recognises only files - no folders. However, these could probably be simulated through appropriate filenames.

A volume consists of the volume header as well as several volume blocks that correspond to the actual files.

"Volumes" are the files with the extension 'vol' in the game directory.

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 56 4f 4c 20 -- -- -- -- -- -- -- -- -- -- -- -- V O L . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Block length
0x0007 uint(8) Flags

Volume Header

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 76 6f 6c 68 -- -- -- -- -- -- -- -- -- -- -- -- v o l h . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Block length
0x0007 uint(8) Flags

The Volume Header does not contain any user data.
It serves merely as a container.

The first entry in the Volume Header should be the Volume Strings, followed by the Volume Information.

Volume Strings

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 76 6f 6c 69 -- -- -- -- -- -- -- -- -- -- -- -- v o l i . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Block length
0x0007 uint(8) Flags
Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 76 6f 6c 73 -- -- -- -- -- -- -- -- -- -- -- -- v o l s . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Block length
0x0007 uint(8) Flags
0x0008 uint(32) Payload length

Indicates how many bytes of the following data are actually usable data.

The remaining data in the volume strings list is evidently to be considered as garbage.

In files with a later date, this 'remaining data' is 0x00, which could suggest shortcomings in the toolchain during the development of the game, meaning that a developer only addressed the proper initialisation of the buffers very late on, as it does not affect the game whether the data is initialised or not.

0x000c uint(8)[] List of file names

This is a 0-byte terminated list of file names which, at least in the present data component, only expects ASCII characters.

It is not necessary to analyse this data block in more detail when parsing the data, as the offsets of the file names are directly referenced in the volume information anyway.

The volume strings refer to a list of file names that are contained within the volume.

Volume Information

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 76 6f 6c 69 -- -- -- -- -- -- -- -- -- -- -- -- v o l i . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Block length
0x0007 uint(8) Flags

The volume information contains more detailed information about the files. In a way, it is a sort of FAT directory entry (FAT = File Allocation Table).

The number of files is determined by dividing the block size by the length of the directory entries - 14 bytes.

The individual directory entries each have the following structure:

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Filename offset

Indicates at which offset (!) within the filename list (volume strings) the filename of the file is located.

This refers to the beginning of the data block.

0x0004 uint(32) File offset

Indicates the offset within the entire volume file where the file is located.

0x0008 uint(32) File size

Indicates how large the file is in bytes.

0x000c uint(16) Flags?

Apparently, it provides additional information about the file encoding.

  • 0x03 is set when the file is compressed. It seems that a Huffman tree is used here.
  • 0x80 is apparently always set.

Volume Block

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 56 42 4c 48 -- -- -- -- -- -- -- -- -- -- -- -- V B L H . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Block length
0x0007 uint(8) Flags

A volume block is a container that holds files. It contains the file size redundantly once more - due to the block format - and is directly followed by the actual data.

Tiles

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 50 42 4d 50 -- -- -- -- -- -- -- -- -- -- -- -- P B M P . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Block length
0x0007 uint(8) Flags

The tiles are a Bitmap graphic format specific to Outpost-2. They span 13 tilesets, referred to as "wells" (well0000.bmp to well0012.bmp), which are located within the volume maps.vol.

The tilesets / wells contain the following:

File Name Content
well0000.bmp A 32x32px blue graphic - ideal for testing whether your image loader works
well0001.bmp Contains light rock, mountain ranges on light rock, and countless variants of impact craters in light rock
well0002.bmp Contains light rock 'doodads' - elements that can be placed on light rock for decoration (or intentionally as structures, such as walls), including vegetation
well0003.bmp Contains a crust-like structure on light rock
well0004.bmp Contains dark rock, mountain ranges on dark rock, and countless variants of impact craters in dark rock
well0005.bmp Contains dark rock 'doodads' - elements that can be placed on dark rock for decoration (or intentionally as structures, such as walls)
well0006.bmp Contains a crust-like structure on dark rock, as well as transitions between light and dark rock
well0007.bmp Contains lava including 4-5 frames of animation for it
well0008.bmp Contains sand and countless variants of impact craters in sand
well0009.bmp Contains sand 'doodads' - elements that can be placed on sand for decoration (or intentionally as structures, such as walls)
well0010.bmp Contains 48 transitions from sand to light and dark rock
well0011.bmp Contains the polar caps of the map, with dark rock as the base
well0012.bmp Contains the polar caps of the map, with light rock as the base

It is advisable for an accurate implementation not to render the tiles in advance for caching purposes, as the data for the day/night cycle still needs to be processed - and an enormous amount of data would accumulate.

The tiles are 8bpp graphics with an indexed palette, each with a resolution of 32x32 pixels, which are arranged in a grid. However, a tileset created in this way can accommodate far more.

The main container consists of 2 sections: head and data.

Tiles Header

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 68 65 61 64 -- -- -- -- -- -- -- -- -- -- -- -- h e a d . . . . . . . . . . . .
0x0010 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Block length
0x0007 uint(8) Flags
0x0008 uint(32) Version / Flags?

This could be a version indication of the file format; in all the files I have, the value 0x02 was present here.

0x000c uint(32) Width (Horizontal Resolution)

Indicates how wide the image file is (in pixels).

For all wells in Outpost 2, the value 0x20 or 32 is expected here.

0x0010 uint(32) Height (Vertical Resolution)

Indicates how tall the image file is (in pixels).

In all wells of Outpost 2, the value 0x20 or 32 is to be expected here.

0x0014 uint(32) Colour depth?

The meaning of this value is unknown.

Since it contains the value 8 in all the checked files, it could be a colour depth specification.

0x0018 uint(32) Colour depth 2?

The meaning of this value is unknown.

It may be a 'target' colour depth.

Following this information, there will be a palette file available in the standardised RIFF format. The exact specification can be found - as the palettes appear elsewhere as well - under Palettes.

Tiles Data

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 64 61 74 61 -- -- -- -- -- -- -- -- -- -- -- -- d a t a . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Block length
0x0007 uint(8) Flags

Finally, the raw pixel data follows, line by line from the top left to the bottom right.
The data value for graphics, which are usually in 8bpp bitmap format, corresponds to the index of the colour in the colour palette.

Pixel data begins at the top left and ends at the bottom right.

The game engine likely renders the tiles *on demand*.
This seems to be partly due to the day-night cycle, which has 32 gradations of individual tiles. It appears that a 'little' is subtracted from the brightness value. Exact values have not yet been determined; I am working on the calculation basis

v *= (daylight / 48) + 0.25;

using the HSV data of the pixels, where daylight is a value from 0-31 and v is a value between 0-1. Furthermore, it should be noted that there is an additional margin of 16 tiles on each side of the map (which serves the invisible spawning of units).

Additionally, the day-night cycle only updates one column of the map per game cycle.
A sped-up day-night cycle therefore looks as follows:

Visualisation of the day-night cycle

PRT

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 43 50 41 4c -- -- -- -- -- -- -- -- -- -- -- -- C P A L . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Pallet length

Indicates, contrary to the normal block format, the number of palettes found in this file - not the length of the block in bytes.

0x0007 uint(8) Flags

Probably, as usual, flags.

However, I am not aware of any flags; since all the values I know correspond to 0x00, it is also potentially conceivable that the number of palettes is simply a uint(32).

I am not sure what PRT stands for; one possibility might be 'Palette and Resource Table' - as this file, found as op2_art.prt in maps.vol, pertains to such a concept, or this would describe its function quite well.

This file contains a list of palettes, a table of all used bitmaps, all animation definitions, and a number of unknown data. It loosely follows the previous container format, as not all records adhere to this schema.

The CPAL section (likely stands for Palette Container) encompasses only the palette data, indicating how many of the typically 1052-byte large 8-bit palettes are present.

The 1052-byte specification is not considered binding, as the palette format could potentially allow for different palette sizes. It only applies to the data set supplied with Outpost 2.

Following the palette lists, the bitmap list immediately follows without an introductory header; likewise, the animation lists follow directly after.
Both are each preceded by a uint(32) (or possibly uint24 + uint8 flags?) that contains the number of records.

Palettes

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 50 50 41 4c -- -- -- -- -- -- -- -- -- -- -- -- P P A L . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Pallet length

Indicates, contrary to the normal block format, the number of palettes found in this file - not the length of the block in bytes.

0x0007 uint(8) Flags

Most likely, as usual, flags.

However, I am not aware of any flags; since all the values I know correspond to 0x00, it is also potentially conceivable that the number of palettes is simply a uint(32).

The palette information is very straightforward to read.
It consists of a header and a data segment.

Palette Header

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 68 65 61 64 -- -- -- -- -- -- -- -- -- -- -- -- h e a d . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Pallet length

Indicates, contrary to the normal block format, the number of palettes found in this file - not the length of the block in bytes.

0x0007 uint(8) Flags

Most likely, as usual, flags.

However, I am not aware of any flags; since all the values I know correspond to 0x00, it is also potentially conceivable that the number of palettes is simply a uint(32).

0x0008 uint(32) Pallet format version?

Probably defines which palette format version the palette follows.

All Outpost2 palettes seem to have version 0x01.

Palette Data

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 64 61 74 61 -- -- -- -- -- -- -- -- -- -- -- -- d a t a . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Magic Bytes
0x0004 uint(24) Block length
0x0007 uint(8) Flags

The data section includes the individual pallet entries. The number of pallet entries is determined by the block length / 4.

The individual entries have the following simple structure;

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 -- -- -- 04 -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(8) Red component

Indicates the red component of the colour

0x0001 uint(8) Green component

Indicates the green component of the colour

0x0002 uint(8) Blue component

Indicates the blue component of the colour

0x0003 uint(8) Unknown - Flags?

It is unclear what this value means, as it apparently is fundamentally 0x04.

Regarding the palettes, it can additionally be said that the following rules apply to palettes used for animations:

  • The first colour is ALWAYS transparent, regardless of what value is specified there.
  • Palette entries 1-24 are to be considered as player colours in palettes 1-8.
    Where the colours, apart from player 1, originate from is unclear to me.
    I suspect that the remaining colours are hardcoded.

Palette Reference

Bitmaps

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
0x0010 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Aligned width

Indicates the width of the pixel data rows in bytes - as they are aligned to 4-byte boundaries.

This makes it quick to access a specific image row.

It is unclear why this value is stored separately, even though it could be calculated.
It may be an optimisation for the rendering code.

0x0004 uint(32) Offset

Indicates the offset of the first line in the bitmap

0x0008 uint(32) Height

Specifies the height of the image in pixels

0x000c uint(32) Width

Specifies the width of the image in pixels

0x0010 uint(16) Type

Indicates the type of the image. It appears to be a bitmask:

  • 0x04 is set if it is a 1bpp graphic.
  • 0x40 is set if it is a graphic that needs to implement windowing.
0x0012 uint(16) Palette

Defines which palette from the PRT file should be used

This data structure of the PRT file specifies how the bitmaps used for the sprites are constructed. These bitmaps serve as individual components, from which several are assembled into an animation frame of a sprite.

The actual image data, on the other hand, is hidden in the op2_art.BMP in the game directory.
It is unclear why this bitmap file has a (mostly correct) RIFF bitmap header. It is likely that Outpost 2 uses system APIs to load the graphics by temporarily adopting this header and overwriting the relevant, varying fields.

The pixel data can be found in the BMP file at the position Offset + the uint32-offset, which can be found at address 0x000A in the BMP file (RIFF bitmap data offset), and again corresponds to the row-wise arrangement from the top left to the bottom right.

Monochrome 1bpp graphics can be drawn in such a way that colour 0 represents complete transparency, while colour 1 is a semi-transparent black/grey, as monochrome graphics are typically used for vehicle and building shadows in the animations.

This allows for a considerable amount of graphics to be assembled.

Protected Living Module (Plymouth)

Animations

Now we come to the pinnacle of the disciplines within the Outpost 2 data formats:
The animations.

The animation lists begin with a global header, primarily serving data verification. Following this are the specific animation definitions, which are divided into three levels:

  1. Animation
    An animation is the highest instance; it represents the animation of a unit, a building, or a 'particle animation' (meteor impact, weather, explosion) in a specific starting condition.
  2. Frame
    A frame is a single image within an animation. An animation can contain one or more frames.
  3. Subframe
    A subframe is the information indicating that a specific bitmap should be drawn at a particular position of a frame under certain criteria. A frame can contain one or more subframes.

Next, we will directly follow with the individual animation definitions.

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Number of animations

How many animation data records are available?

0x0004 uint(32) Number of frames

How many frames should there be in total?

0x0008 uint(32) Number of subframes

How many subframes should be present in total?

0x000c uint(32) Number of optional entries

How many "optional entries" are available.

Animation

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
0x0010 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
0x0020 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(32) Unknown 1

Unknown information

0x0004 uint(32) Bounding Box: Left

Specifies the left start (in pixels) of the Bounding Box.

0x0008 uint(32) Bounding Box: Top

Indicates the upper start (in pixels) of the Bounding Box.

0x000c uint(32) Bounding Box: Width

Indicates the width (in pixels) of the Bounding Box.

0x0010 uint(32) Bounding Box: Height

Indicates the height (in pixels) of the Bounding Box.

0x0014 uint(32) Offset: X

Indicates the horizontal midpoint of the animation

0x0018 uint(32) Offset: Y

Specifies the vertical midpoint of the animation

0x001c uint(32) Unknown 2

Unknown Information

0x0020 uint(32) Number of frames

Indicates how many animation frames are contained in this animation

0x0024 uint(32) Number of windows

Indicates how many windows to apply when drawing

The data from the top layer, the animation, primarily consists of administrative data - the Bounding box refers to the coordinates of the marker around the vehicle/building when it is selected and also indicates which area should be clickable.

The offset primarily determines the "zero point"; the point that needs to be added to or subtracted from the in-game coordinates. One could also say mathematically: the offset here refers to the origin of the coordinates.

The windows consist, just like the offset, of 4 uint(32) values per window, which specify an area that is considered usable for individual subframes. Drawing is not permitted outside the windows, unless it is specifically designated for the bitmap.

Frame

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(8) Number of subframes and toggle for optional 1, 2

This value contains:

  • 0x7F (Bitmask): The number of subframes used in this frame
  • 0x80: Information on whether Optional 1 and 2 are present
0x0001 uint(8) Unknown 1 and toggle for Optional 3, 4

This value contains:

  • 0x7F (bitmask): Unknown - I strongly suspect that this refers to the number of game ticks that elapse before the next frame is displayed
  • 0x80: Information on whether Optional 3 and 4 are present
0x0002 uint(8) Optional 1

Unknown

0x0003 uint(8) Optional 2

Unknown

0x0004 uint(8) Optional 3

Unknown

0x0005 uint(8) Optional 4

Unknown

Subframe

Addr x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF char
0x0000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- . . . . . . . . . . . . . . . .
Offset Data type Designation Explanation
0x0000 uint(16) Bitmap ID

Indicates which bitmap should be used for this subframe

0x0002 uint(8) Unknown 1

It is unknown - however, I strongly suspect that this relates to a render priority (Z-layer).

0x0003 uint(8) Subframe ID

Indicates which subframe we are in

0x0004 sint(16) Offset - Horizontal

Indicates where within the frame the subframe should be placed, or by how many pixels the bitmap should be shifted horizontally.

0x0006 sint(16) Offset - Vertical

Indicates where within the frame the subframe should be placed, or by how many pixels the bitmap should be moved vertically.

With this, we can now compose individual frames as well as complete animations accordingly, demonstrated here with a more complex animation, the animation with index 500.

Animation 500

Animation 500 shows how a Plymouth transporter, loaded with ordinary ore, is unloaded. This is one of the few animations that utilise the windowing functionality.

And so the complete animation can be assembled.
Unfortunately, there is still an issue with the upper loading hatch, as the corresponding bit in the graphic type information is not set.

Here are a few more beautifully animated sprites from the game:

Rendering of Animation 500 illustrated

Animation 500 fully assembled

Plymouth Building Factory

Eden Spaceport

Eden Medical Centre

SCAT

Plymouth Spaceport

Easter egg:
Santa Claus

Easter egg:
Dan's Dog

User Interface

Now, what remains is the user interface of the game, which features a brushed metal look.

However, it is also evident that Dynamix did not need to reinvent the wheel; they are simply utilising the User32 and GDI32 APIs provided by Windows—particularly, they are employing the resource management capabilities of User32.

These can be extracted, for example, using programs such as Resource Hacker, developed as freeware by Angus Johnson, or - if one is hesitant to use Wine on Linux / Mac OS - with the wrestool included in icoutils.

Filename Contents
Outpost2.exe Contains only the game's icon, which depicts the space station in front of New Terra
op2shres.dll Includes graphics for UI elements such as borders, buttons, radio buttons, and checkboxes, as well as dialogue backgrounds, accompanying images for the story mission texts, and the main menu background graphic
out2res.dll Contains the in-game window decorations, icons for regular and special metal, the loading screen, graphics for dialogues, as well as additional cursor graphics, in addition to the animated ones in the game directory