.RES in IGI 2 -- Resource Archives (ILFF/IRES)

1. Architectural Role & Engine Purpose

The RES (Covert Strike Resource Archive) format packages all game data, terrain tiles, meshes, textures, audio, and scripts into consolidated disk volumes in I.G.I. 2: Covert Strike (2003).

In IGI 2, the resource system was significantly upgraded to include LZSS/zlib block compression, accelerated binary hash indexes, and multi-threaded streaming queues, cutting mission load times in half while packing vastly higher-resolution textures into smaller file sizes.

2. Binary File Layout & Memory Map Diagram

An IGI 2 RES archive consists of an outer ILFF/RES2 container header, a directory table, and compressed data blocks:

IGI 2 RES ARCHIVE — COMPRESSED VFS BINARY LAYOUT 0x00: Container Header (24 Bytes) RES2 CONTAINER FourCC "RES2" / "ILFF" | File Count (uint32) | Index Offset | Archive Size | Version 2.0 magic[4], file_count, index_offset, archive_size, ver_major (2), ver_minor (0), flags Directory Table (28 Bytes per File Entry) 28B ENTRY Name Hash (CRC32) | Data Offset | Packed Size | Unpacked Size | Compression (0=Raw, 1=LZSS, 2=Deflate) Entry: [CRC32: 4B] [Offset: 4B] [PackedSz: 4B] [UnpackSz: 4B] [CompType: 2B] [AssetType: 2B] [Res: 4B] Compressed Block Payload Stream LZSS / ZLIB Sector-aligned compressed asset blocks: High-resolution DXT5 textures, meshes, and sound Decompressed asynchronously in memory ring buffers without temporary disk extraction

3. Asynchronous Streaming & Decompression Pipeline Diagram

IGI 2 uses a background worker thread to decompress assets on the fly during gameplay transitions:

IGI 2 RES — ASYNCHRONOUS LZSS STREAMING PIPELINE 1. HASH LOOKUP • Target: "SOCOM.MEF" • CRC32 Binary Search • Locate Directory Entry 2. ASYNC DMA READ • Background IO Thread • Read Compressed Block • 2048-Byte Sector Align 3. LZSS DECOMPRESS • Inflate in Memory Ring • Packed: 18KB → 49KB • Zero CPU Temp Stalls 4. LOADER HAND-OFF • Deliver to MefLoader • Direct VBO Creation • Ready for Frame

4. C++ Struct Definitions

#pragma pack(push, 1)
struct Res2Header {
    char     magic[4];       // "RES2" or "ILFF"
    uint32_t file_count;     // Number of files in archive
    uint32_t index_offset;   // Offset to directory table
    uint32_t archive_size;   // Total file length
    uint16_t version_major;  // 2
    uint16_t version_minor;  // 0
    uint32_t flags;          // Sector alignment flags
};

struct Res2Entry {
    uint32_t name_hash;      // 32-bit CRC hash
    uint32_t data_offset;    // Offset in data stream
    uint32_t packed_size;    // Compressed size
    uint32_t unpacked_size;  // Decompressed size
    uint16_t compression;    // 0=Raw, 1=LZSS, 2=Deflate
    uint16_t asset_type;     // Asset category ID
    uint32_t reserved;
};
static_assert(sizeof(Res2Entry) == 28, "Res2Entry must be 28 bytes");
#pragma pack(pop)