OFP Forum, OFP Home, OFP File Formats, OFP Tools, OFP Missions, OFP 3D Modeling, OFP Terrain
Operation Flashpoint (OFP) aka ArmA: Cold War Assault (CWA)
OFP WRP files use two different file formats to contain the data. This document contains information on OPRW format as used by WrpEdit, and as supplied in the standard bis Islands of Malden, Nogova and etc. This document does not provide information on the better known 4WVR format.
See General wrp format for more info
Two versions of OPRW format exist.
1. Version2 (pre)
2. Version 3 (Post) Resistance.
The only difference between these two formats is a 16 byte added terrain dimension size inserted towards beginning of header. Since all BI islands, including Resistance's Nogova, are 256 x 256 cells square, the information is redundant in terms of the 'official' terrains. However this feature has been exploited heavily by terrain editors to make some huge territories. Cat Aghansitan, and PMC Vietnam to name but two.
Conventions
byte = 1 char = 8 bits ulong = unsigned long, 4 bytes ushort= unsigned short 2 bytes asciiz= variable length zero terminated string. float= 4byte (single precision)
OPRW file structure is as follows;
struct { char Signature[4]; //"OPRW" ulong Version; // 2 or 3 3 == Resistance ulong MapSize[2][2]; // resistance only= 256,256,256,256 ulong CellFlags[256][256]; //packed Bitflags 31->0 /*?????????????????iiiddgg??RF?Gaa ** iii incline 0->7 ** dd damage 0->3 ** gg geometry levels 0->3 (plus G bit) ** F forest bit ** R roadway bit ** G extended geom flag ** aa enum surfacetype {Ground,Coast,Beach,Sea}; */ byte CellEnvSounds[256][256]; //packed predefined values // correspond to Config.cpp CfgEnvSounds class. // 0 none // 1 sea // 2 tree // 3 meadow // 4 hill // 5 rain // 0ther . ulong nPeakEntries; // number of peaks in list, can be 0 float Peaks[3]......; /*If present, XZY values for each peak (X and Z must be aligned to cells (50.0) Ignored. OFP recalculates them at loading-time. */ ushort CellTextureIndexes[256][256];//packed /*Each value is index in the Textures List (see below). Index based from zero. Value = 0 has a corresponding entry in the Textures List, but is not used. */ ulong CellsExtFlag[256][256]; //packed /*XXXXabcc ** Contains 3 subsections: * cc 0-FF Random values (0..255) * b signed 7 -> -8 Random values, depends on texture color * a signed Random values, depends on texture color flag . Ignored. OFP recalculates them at loading-time. . Section can be filled with zero. This allows it to be packed more. */ float Elevation[256][256]; //packed /*Values of vertices of 257x257 mesh (cells - 256x256). Last right column, and last top row of ** this mesh (257x257) contains 0.0 and is not included in this section. */ /* No restriction for min/max values but recommended values: from -50.0 to 1000.0 Textures { ulong nEntries; // Number of texture entries. At least 1 entry0 { asciiz Filename; byte Color; } /*Typically "data\more_anim.01.pac". It is not used by the engine, ** this is the transparent value index. Most of the 'solid' textures have color values. */ .... EntryLast{...}; //can also contain unused entries and empty names (for unused entries). }; Models { ulong nEntries; //can be zero Entry0 { asciiz Filename; //"data3d\thing.p3d" } ... EntryLast{...}; }; Objects{...}; //56 byte records, or none, see below };
Objects, if any, are indexes into the models named above (if any).
Objects, and the models they refer to, are the way to place buildings, trees, etc on the terrain.
Objects consist of contiguous 56-byte records of floats and ulongs. The last 'object' is different, it is simply a 4 byte (ulong) value containing 0xFFFFFFFF signifying the end of the object list (if any) and, the end of the file.
Thus, for a wrp file containing no objects, the file still has the 0xFFFFFFFF signature.
To be more specific, a wrp file containing no objects and no models to refer to contain
0x000000000 // no models 0xFFFFFFFF // no objects
The format of each object is as follows
ulong ObjectID;// 0 to wherever. /* A unique identifier for every object in this list, as each object, ** even if using an identical model, ** is in a different position on the terrain. Ie three buildings in a row. */ . //ObjectID 0xFFFFFFFFF is unique and means end of list and end of file. No data follows . ulong ModelIndex; //The index number to use from the model list above to obtain the filename. float Transform[4[3]]; //This is the traditional 9 cell vertex to orient and rotate a model.
Transform[4][3];
This is the transform matrix used directly by Microsoft DirectX engines.
In fact, the 'correct' matrix is actually 4 x 4, but the last column always represents 0,0,0,1 thus
M11,M12 M13 (0.0) M21,M22,M23 (0.0) M31,M32,M33 (0.0) M41,M42,M43 (1.0)
and so is never stored.
This identical matrix is used for WRP files (both formats) and RTM files.
The last row (M41…) happens to be the position of the object X Z Y co-ordinates, and is often referred to separately.
For further information visit Microsoft page.
In order to conserve space, where, the majority of cells will contain identical information (if not zero, then an awful lot of 'sea' texture). run length packing is used. The algorithm is identical to that used in pbo compression. Principally, a flag byte followed by mixtures of 8 raw bytes and 2byte pointers.
Each of the array[ ][ ] entries above are packed. They are treated as separate compressed blocks each with their own checksum. Since the desired size is known (256×256), unpacking consists of decoding the file up to that limit then checking the checksum.
The next 'block' ie, the next array is then treated in a similar manner.
For further information on this packing method see pbo file format