Wrp File Format - OPRW2 & 3: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
mNo edit summary
m (Text replacement - " +\] +" to "] ")
 
(16 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{unsupported-doc}}
{{Feature|UnsupportedDoc}}
==General==
== General ==
''Flashpoint 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 BI Islands of Malden, Nogova and etc. This document does '''not''' provide information on the better known [[Wrp File Format - 4WVR|4WVR]] format.
''Flashpoint 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 BI Islands of Malden, Nogova and etc. OPRW files are, essentially, binarised.
 
This document does '''not''' provide information on the better known [[Wrp File Format - 4WVR|4WVR]] format.


See [[BIS_File_Formats#Island_File_Formats|Island File Formats]] for more info''
See [[BIS_File_Formats#Island_File_Formats|Island File Formats]] for more info''


Two versions of OPRW format exist.  
Several versions of OPRW format exist.  


1. Version2 (pre)  
*Version2: Cold War Crisis. The original.
*Version3: Resistance.
2. Version 3 (Post) Resistance.
*Version17: Elite
*Version18: General Arma editing.
*Version20: Arma's sara.pbo (at least)
 
This document describes ONLY Versions 2 & 3.
 
The '''only''' difference between these two formats is a 16 byte added map 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' maps. However this feature has been exploited heavily by map modellers to make some huge territories. Cat Afghansitan, and PMC Vietnam to name but two.


The '''only''' difference between these two formats is a 16 byte added map 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' maps. However this feature has been exploited heavily by map modellers to make some huge territories. Cat Aghansitan, and PMC Vietnam to name but two.
== Conventions ==
=== Legend ===
see [[Generic FileFormat Data Types]]


===Conventions===
== Structure ==
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)


==Structure==
  OPRWv2_3
OPRW file structure is as follows;
  struct
  {
  {
  WrpHeader  Header;
  ulong      PackedCellBitFlags[LayerDimensions];
  byte      PackedCellEnvSoundsp[LayerDimensions];
  ulong      nPeaks;
  XYZTriplet Peaks[nPeaks];////see http://en.wikipedia.org/wiki/Maxima_and_minima
  ushort    PackedCellTextureIndexes[LayerDimensions];
  ulong      PackedCellExtFlags[LayerDimensions];
  float      PackedCellElevations[MapDimensions];
  ulong      nTextures;
  Texture    Textures[nTextures];        // At least 1
  ulong      nModels;
  Model      Models[nModels];            //can be zero
  Object    Objects{...};              //56 byte records
  long      EndOfObjects;                //'''always''' -1
};
=== WrpHeader ===
  WrpHeader
  {
   char  Signature[4]; //"OPRW"
   char  Signature[4]; //"OPRW"
   ulong Version;     // 2 or 3 3 == Resistance
   ulong Version;     // 2(cwr) or 3 (Resistance)
   ulong MapSize[2][2]; // '''resistance only= 256,256,256,256'''
   '''if (Resistance)'''
   ulong CellFlags[256][256]; //packed Bitflags 31->0
   {
   /*?????????????????iiiddgg??RF?Gaa
  XYPair  LayerDimensions; // (texture) 256 x 256 eg
  ** iii incline 0->7
  XYPair  MapDimensions;   // (terrain) ditto
  ** dd  damage 0->3
   }
  ** gg  geometry levels 0->3 (plus G bit)
}
  ** F  forest bit
 
  ** R  roadway bit
This is a fairly common header througout all wrp formats (including WVR types). There are wrinkles to each one, so check the documentation for each.
  ** G  extended geom flag
 
  ** aa  enum surfacetype {Ground,Coast,Beach,Sea};
Official bis {{ofp}} islands are ALL 256 x 256 map and layer dimensions on a 50meter cube 'cell' (the cell also has a height)
  */
 
  byte  CellEnvSounds[256][256];  //packed predefined values
=== CellBitFlags ===
                                  // correspond to Config.cpp CfgEnvSounds class.
 
// 0 none
00000000 00000000 0iiiddgg00RF0Gaa
// 1 sea
* iii incline 0..7
// 2 tree
* dd  damage 0..3
// 3 meadow
* Ggg geometry levels 0..7
// 4 hill
* F  forest bit
// 5 rain
* R  roadway bit
// 0ther  
* aa  surfacetype
.
**0: GROUND
ulong nPeakEntries; // number of peaks in list, can be 0
**1: TIDAL
float Peaks[3]......;
**2: COASTLINE
/*If present, XZY values for each peak (X and Z must be aligned to cells (50.0)
**3: SEA
 
=== CellEnvSounds ===
corresponds to Config.cpp CfgEnvSounds class.
*0 none
*1 sea
*2 tree
*3 meadow
*4 hill
*5 rain
*0ther...
 
=== Peaks ===
 
   Ignored. OFP recalculates them at loading-time.
   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
When present, the XYZ co-ordinate of each peak.
 
These are the 'points of interest'. Ie 'bumps' in the terrain and are shown in visitor and map game as '24', '6' etc on various parts of the island that have 'bumps' (or 'depressions') relative to the general (cell) area.
 
see http://en.wikipedia.org/wiki/Maxima_and_minima
 
The coordinates are expressed in meters on the world grid, X and Y have to be divided by the map, or layer resolution to get the map or cell co-ordinate respectively.
 
In the case of official {{ofp}} islands, both resolutions are 50 meters. All layers, All maps, are 256x256 on 50meter cubes per cell.
 
 
=== CellTextureIndexes ===
Each value is index into the Asciiz Textures List.
 
index = 0 has a corresponding entry in the Textures List, but is not used.
 
=== CellExtFlags ===
XXXXabcc
 
Contains 3 subsections:
* cc 0-FF Random values (0..255)
*  b signed 7 -> -8 Random values, depends on texture color
*  a signed Random value, depends on texture color flag
 
Ignored. OFP recalculates them at loading-time.
 
Section can be filled with zero.
 
=== CellElevations ===
 
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
 
=== Texture ===
   Texture
   {
   {
   ulong nEntries; // Number of texture entries. At least 1
   asciiz Filename;
  entry0
  byte Color;
  {
   }
    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).
   };


Like all similar formats, there is a minimum of one entry. The 1st entry is a dummy and never accessed but typically contains the string


   Models
"data\more_anim.01.pac".
 
This is the transparent index value.
Most of the other textures have color values.
 
Although unusual, other entries ''could'' contain empty names. Where encountered, they would never be referenced.
=== Model ===
   Model
   {
   {
  ulong nEntries; //can be zero
  Entry0
  {
     asciiz Filename; //"data3d\thing.p3d"
     asciiz Filename; //"data3d\thing.p3d"
  }
   }
  ...
  EntryLast{...};
   };
 
  Objects{...}; //56 byte records, or none, see below
};


=== Object ===
Object
{
  ulong ObjectID;        // 4 gig of objects
  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.
}


Objects, if any, are indexes into the models named above (if any).
Objects, if any, are indexes into the models named above (if any).
Line 109: Line 154:
Objects, and the models they refer to, are the way to place buildings, trees, etc on the map.
Objects, and the models they refer to, are the way to place buildings, trees, etc on the map.


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.
The ObjectID is a unique value that identifies '''this''' PineTree
 
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 map. 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.
==Note1==
Transform[4][3];
Transform[4][3];


Line 149: Line 173:
The last row (M41...) happens to be the position of the object X Z Y co-ordinates, and is often referred to separately.
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 [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/fixedfunction/transforms/transforms.asp Microsoft].
For further information visit {{Link|http://msdn.microsoft.com/library/default.asp?url{{=}}/library/en-us/directx9_c/directx/graphics/programmingguide/fixedfunction/transforms/transforms.asp|Microsoft}}.


==FILE PACKING==
== FILE PACKING ==


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.
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 (256x256), unpacking consists of decoding the file up to that limit then checking the checksum.
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 (256x256), 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.
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|pbo file format]]
For further information on this packing method see [[PBO File Format]]


[[category:Operation Flashpoint: Modelling]]
{{GameCategory|ofp|Modelling}}
[[Category:BIS_File_Formats]]
[[Category:BIS_File_Formats]]

Latest revision as of 18:49, 8 November 2023

bi symbol white.png
Disclaimer: This page describes internal undocumented structures of Bohemia Interactive software.

This page contains unofficial information.

Some usage of this information may constitute a violation of the rights of Bohemia Interactive and is in no way endorsed or recommended by Bohemia Interactive.
Bohemia Interactive is not willing to tolerate use of such tools if it contravenes any general licenses granted to end users of this community wiki or BI products.

General

Flashpoint 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 BI Islands of Malden, Nogova and etc. OPRW files are, essentially, binarised.

This document does not provide information on the better known 4WVR format.

See Island File Formats for more info

Several versions of OPRW format exist.

  • Version2: Cold War Crisis. The original.
  • Version3: Resistance.
  • Version17: Elite
  • Version18: General Arma editing.
  • Version20: Arma's sara.pbo (at least)

This document describes ONLY Versions 2 & 3.

The only difference between these two formats is a 16 byte added map 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' maps. However this feature has been exploited heavily by map modellers to make some huge territories. Cat Afghansitan, and PMC Vietnam to name but two.

Conventions

Legend

see Generic FileFormat Data Types

Structure

OPRWv2_3
{
 WrpHeader  Header;
 ulong      PackedCellBitFlags[LayerDimensions];
 byte       PackedCellEnvSoundsp[LayerDimensions];
 ulong      nPeaks;
 XYZTriplet Peaks[nPeaks];////see http://en.wikipedia.org/wiki/Maxima_and_minima
 ushort     PackedCellTextureIndexes[LayerDimensions];
 ulong      PackedCellExtFlags[LayerDimensions];
 float      PackedCellElevations[MapDimensions];
 ulong      nTextures;
 Texture    Textures[nTextures];        // At least 1
 ulong      nModels;
 Model      Models[nModels];            //can be zero
 Object     Objects{...};               //56 byte records
 long      EndOfObjects;                //always -1
};

WrpHeader

 WrpHeader
 {
 char  Signature[4]; //"OPRW"
 ulong Version;      // 2(cwr) or 3 (Resistance)
 if (Resistance)
 {
  XYPair  LayerDimensions; // (texture) 256 x 256 eg
  XYPair  MapDimensions;   // (terrain) ditto
 }
}

This is a fairly common header througout all wrp formats (including WVR types). There are wrinkles to each one, so check the documentation for each.

Official bis Operation Flashpoint islands are ALL 256 x 256 map and layer dimensions on a 50meter cube 'cell' (the cell also has a height)

CellBitFlags

00000000 00000000 0iiiddgg00RF0Gaa
  • iii incline 0..7
  • dd damage 0..3
  • Ggg geometry levels 0..7
  • F forest bit
  • R roadway bit
  • aa surfacetype
    • 0: GROUND
    • 1: TIDAL
    • 2: COASTLINE
    • 3: SEA

CellEnvSounds

corresponds to Config.cpp CfgEnvSounds class.

  • 0 none
  • 1 sea
  • 2 tree
  • 3 meadow
  • 4 hill
  • 5 rain
  • 0ther...

Peaks

  Ignored. OFP recalculates them at loading-time.

When present, the XYZ co-ordinate of each peak.

These are the 'points of interest'. Ie 'bumps' in the terrain and are shown in visitor and map game as '24', '6' etc on various parts of the island that have 'bumps' (or 'depressions') relative to the general (cell) area.

see http://en.wikipedia.org/wiki/Maxima_and_minima

The coordinates are expressed in meters on the world grid, X and Y have to be divided by the map, or layer resolution to get the map or cell co-ordinate respectively.

In the case of official Operation Flashpoint islands, both resolutions are 50 meters. All layers, All maps, are 256x256 on 50meter cubes per cell.


CellTextureIndexes

Each value is index into the Asciiz Textures List.

index = 0 has a corresponding entry in the Textures List, but is not used.

CellExtFlags

XXXXabcc

Contains 3 subsections:

  • cc 0-FF Random values (0..255)
  • b signed 7 -> -8 Random values, depends on texture color
  • a signed Random value, depends on texture color flag

Ignored. OFP recalculates them at loading-time.

Section can be filled with zero.

CellElevations

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

Texture

 Texture
 {
  asciiz Filename;
  byte Color;
 }

Like all similar formats, there is a minimum of one entry. The 1st entry is a dummy and never accessed but typically contains the string

"data\more_anim.01.pac".

This is the transparent index value. Most of the other textures have color values.

Although unusual, other entries could contain empty names. Where encountered, they would never be referenced.

Model

 Model
 {
   asciiz Filename; //"data3d\thing.p3d"
 }

Object

Object
{
 ulong ObjectID;        // 4 gig of objects
 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.
}

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 map.

The ObjectID is a unique value that identifies this PineTree

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.

FILE PACKING

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 (256x256), 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