File Formats

From BF2 Technical Information Wiki
Jump to navigation Jump to search

Image Files

The majority of the image files within the Battlefield 2 directory structure have the PNG file extension, however most of these image files are in fact DDS files with an incorrect file extension. There are a few image files that really are PNG files (mainly within Battlefield 2\mods\bf2\Objects\), and can be easily loaded by an image viewer/editor.

The image files in Menu_client.zip are packed into a DDS Texture Atlas file. Basicly, an atlas file combines a lot of small images into one big image to improve reading performance. An index file with coordinates is used to locate the individual images in the Atlas. The Atlas images and index files are located in Menu_client.zip/Atlas.

Basic File Format Data Types

String

struct String {
    uint len;
    char cstr[len];
}

Vec2

struct Vec2 {
    float x;
    float y;
}

Vec3

struct Vec3 {
    float x;
    float y;
    float z;
}

Point

struct Point {
    float x;
    float y;
    float z;
}

Mat4

struct Mat4 {
    float m[4][4];
}

Axis-Aligned Bounding Box

Used for collosion detection.

struct AABB {
    Point endpoint1;
    Point endpoint2;
}

Mesh File Formats

A mesh describes how an object in the world needs to be rendered, all mesh file formats use little endian byte order.

Common Mesh Data Types

Header
struct Header {
    uint u1;
    uint version;
    uint u2; // not used
    uint u3; // not used
    uint u5; // not used
    char u6; // not used
}
VertexElement
struct VertexElement {
    ushort flag;
    ushort offset;
    ushort varType;
    ushort usage;
}
Geometry
struct Geometry {
    uint numGeom; // number of geometric objects in this file
    uint numLods[numGeom];
    uint numVertexElements;
    VertexElement vertexElements[numVertexElements]; // based on D3DXVERTEXELEMENT9
    uint vertexFormat;
    uint vertexStride;
    uint numVertices;
    float vertices[numVertices * (vertexStride / vertexFormat);
    uint numIndices;
    ushort indices[numIndices];
}

.staticmesh File Format

The .staticmesh format is used for meshes without animations, below is a description of the file layout in a C like syntax.

struct StaticMesh {
    Header header;
    Geometry geometry;
    uint u6;
    struct Lod {
        Vec3 u1;
        Vec3 u2;
        uint numNodes;
        Mat4 nodes[numNodes]; // nodes are the respective origins of the objects?
    } lods[sum(geometry.numLods, geometry.numGeom)]; // each geometric object can have multiple lods
    struct {
        uint numMaterials;
        struct Material {
            uint alphaMode; // opaque = 0, blend = 1, alphatest = 2
            String shaderFile;
            String technique;
            uint numTextureMaps;
            String textureMapFiles[numTextureMaps];
            uint verticesStartIndex;
            uint indicesStartIndex;
            uint numIndices;
            uint numVertices;
            uint u1;
            ushort u2;
            ushort u3;
            Vec3 u4;
            Vec3 u5;
        } materials[numMaterials];
    } geomMaterials[sum(geometry.numLods, geometry.numGeom)];
}

.bundledmesh File Format

struct BundledMesh {
    Header header;
    Geometry geometry;
    uint u6;
    struct Lod {
        Vec3 u1;
        Vec3 u2;
        uint numNodes; // not used?
    } lods[sum(geometry.numLods, geometry.numGeom)]; // each geometric object can have multiple lods
    struct {
        uint numMaterials;
        struct Material {
            uint alphaMode; // opaque = 0, blend = 1, alphatest = 2
            String shaderFile;
            String technique;
            uint numTextureMaps;
            String textureMapFiles[numTextureMaps];
            uint verticesStartIndex;
            uint indicesStartIndex;
            uint numIndices;
            uint numVertices;
            uint u1;
            ushort u2;
            ushort u3;
        } materials[numMaterials];
    } geomMaterials[sum(geometry.numLods, geometry.numGeom)];
}

.skinnedmesh File Format

struct SkinnedMesh {
    Header header;
    Geometry geometry;
    struct Lod {
        Vec3 u1;
        Vec3 u2;
        uint numRigs;
        struct Rig {
            uint numBones;
            struct Bone {
                uint id;
                Mat4 mat; // inverse bone matrix
            } bones[numBones];
        } rigs[numRigs];
    } lods[sum(geometry.numLods, geometry.numGeom)]; // each geometric object can have multiple lods
    struct {
        uint numMaterials;
        struct Material {
            String shaderFile;
            String technique;
            uint numTextureMaps;
            String textureMapFiles[numTextureMaps];
            uint verticesStartIndex;
            uint indicesStartIndex;
            uint numIndices;
            uint numVertices;
            uint u1;
            ushort u2;
            ushort u3;
        } materials[numMaterials];
    } geomMaterials[sum(geometry.numLods, geometry.numGeom)];
}

.mesh File Format

It seems that .mesh files are only used for road data. Note that this file has a different layout.

struct RoadCompiled {
    uint version; // version number consists of major and minor version, latest is 65540, 65540 >> 16 = 1, 65540 % 65536 = 4 (v1.4)
    Vec3 u1;
    uint u2;
    Vec3 u3;
    Vec3 u4;
    uint u5;
    uint numVertices;
    struct {
        Vec3 u1;
        Vec2 u3;
        Vec2 u4;
        uint u6;
    } vertices[numVertices];
    uint numIndices;
    ushort indices[numIndices];
    uint numUnk;
    struct {
        uint u1;
        uint u2;
        uint u3;
        Vec3 u4;
    } unk[numUnk];    
}

terraindata.raw

The terraindata.raw file describes the terrain of a level in BF2.

struct TerrainData {
    uint version;
    Vec3 primaryWorldScale;
    Vec3 secondaryWorldScale;
    float u1;
    float u2;
    float u3;
    uint patchSize;
    bool subdividePatches;
    uint numPatches;
    uint patchColormapSize;
    uint lowDetailmapSize;
    char* colorMapbaseName; // the following strings use a newline character ('\n') as terminator instead of the normal null terminated C string
    char* detailMapbaseName;
    char* lowDetailMapbaseName;
    char* lightmapBaseName;
    Vec2 farSideTiling;
    float farSideTilingHi;
    float farSideTilingLow;
    float farYOffset;
    Vec3 terrainSunColor;
    Vec3 terrainSkyColor;
    Vec3 terrainWaterColor;
    uint numLayers; // This is always 6 for BF2, these are the layers as found in the terrain editor
    struct {
        char* detailTexturePath;
        char planeMap;
        Vec2 sideTiling;
        float topTiling;
        float yOffset;
        bool envMap;
    } layers[numLayers];
    uint u6[32 * 21];
    uint u7[6 * 85];
    uint numIndices;
    ushort indices[numIndices];
    bool vertexFormat;
    struct QuadPatch { // This describes a rectangular region of the main terrain
        uint u1;
        uint u2;
        uint u3;
        uint u4;
        Vec3 u5;
        uint u6;
        struct {
            float u1;
            float u2;
            float u3;
            float u4;
            uint u5;
            uint u6;
        } compactVertexData[(patchSize + 1) * (patchSize + 1)];
        struct {
            int magic;
            uint i;
            Vec3 zero1; // always 0/0/0, no longer in use?
            float zero2; // no longer in use?
            uint numChartIndices;
            uint numChartIndicesDiv3; // this is equal to numChartIndices / 3
            uint four; // always the value 4
            uint numSubIndexQuads;
            struct SubIndexQuad {
                uint u1;
                uint u2;
                uint u3;
                uint u4;
                uint u5;
                uint u6;
            } subIndexQuads[numSubIndexQuads];
            ushort chartIndices[numChartIndices];
        } detailCharts[]; // this array is terminated like a string, it ends when the magic field of the next detail chart is -1
        uint terminator; // this will be -1, see above comment
    } patches[numPatches * numPatches];
    // here should be the data for the surrounding terrain and maybe some other data, not yet clear.
}

External Links

Microsoft Developer Network DDS File Reference

PNG File Information

DDS File Convertor

Nvidia DDS Plugin for reading and writing DDS files in Adobe Photoshop

Nvidia texture atlas tools reading and creating tool