.SPR -- 2D Billboarding Sprites

1. Architectural Role & Engine Purpose

The SPR (Sprite File) format powers 2D animated visual elements in Project I.G.I. 1, including weapon muzzle flashes, explosion bursts, bullet impact sparks, water splashes, blood splatters, and tactical HUD overlays (ammo counters, crosshairs, binoculars).

Sprites in IGI 1 are screen-aligned or view-oriented billboard elements. The format packs multiple animation frames into a single stream with per-frame pivot offsets, allowing arbitrary rotational and translational anchoring relative to 3D weapon muzzles or world-space impact points.

2. Binary File Layout & Memory Map Diagram

An SPR file consists of a header with frame counts and bounding dimensions, followed by a frame offset directory, and the sequential frame data payloads:

SPR ANIMATED SPRITE — 2D FRAME SEQUENCE BINARY LAYOUT 0x00: Sprite Header (16 Bytes) 16 BYTES Magic FourCC | Version | Frame Count | Playback FPS | Max Width & Height | Blend Mode magic, version, frame_count, fps, max_w, max_h, blend_mode Frame Offset Table DIRECTORY Array of 32-bit offsets to individual frame payloads uint32_t frame_offsets[frame_count] Per-Frame Header (16 Bytes) PIVOT ANCHOR Frame Width, Height, Hotspot X, Hotspot Y Anchor Sub-pixel pivot alignment for weapon barrels Frame Pixel Streams (ARGB1555 / RLE Compressed) PIXELS Contiguous 16-bit color scanlines with 1-bit alpha or run-length encoded transparency [Frame 0 Payload] → [Frame 1 Payload] → ... → [Frame N Payload]

3. Engine Pipeline & Sprite Rendering Flow Diagram

Sprites are updated by the particle and FX subsystem each tick and rendered as camera-facing quads in Direct3D 7:

SPR SPRITE — ANIMATION TICK & BILLBOARD RENDERING PIPELINE 1. FX TRIGGER • Weapon Muzzle Flash • Explosion Detonation • Bullet Impact Spark 2. FRAME TICK • DeltaTime Evaluation • Fetch Active Frame Index • Read Hotspot Pivot X/Y 3. BILLBOARD QUAD • Anchor to Barrel Tip • Camera-Facing 4 Vertices • View-Space Transform 4. ALPHA BLIT • D3D Alpha Blend • Additive (ONE, ONE) • Render Screen Quad

4. Architectural Mechanics & Engine Implementation Details

Innerloop designed the sprite engine for extreme lightweight instantiation:

  • Sub-Pixel Hotspot Pivots: Each frame specifies an explicit hotspot_x and hotspot_y origin. For muzzle flashes, the hotspot is positioned exactly at the weapon barrel tip, ensuring that orientation changes don't cause sprite detachment.
  • Additive vs Alpha Blend: Sprites support multiple blending modes encoded in the frame header. Explosion fireballs and muzzle flashes use additive blending (ONE, ONE), while smoke puffs and blood use linear alpha blending (SRC_ALPHA, INV_SRC_ALPHA).
  • Dynamic Memory Pooling: Active sprite instances share read-only memory pointers to the loaded SPR buffer in RAM, avoiding duplicate memory copies.

5. C++ Struct Definitions

#pragma pack(push, 1)
struct SprHeader {
    uint16_t magic;         // Sprite magic identifier
    uint16_t version;       // Format version
    uint16_t frame_count;   // Total number of animation frames
    uint16_t fps;           // Playback framerate
    uint16_t max_width;     // Maximum frame width
    uint16_t max_height;    // Maximum frame height
    uint32_t flags;         // Blending and format flags
};

struct SprFrameDesc {
    uint16_t width;         // Frame width in pixels
    uint16_t height;        // Frame height in pixels
    int16_t  hotspot_x;     // Anchor X offset relative to center
    int16_t  hotspot_y;     // Anchor Y offset relative to center
    uint32_t data_offset;   // Byte offset to pixel payload
    uint32_t blend_mode;    // 0=Alpha, 1=Additive, 2=ColorKey
};
static_assert(sizeof(SprHeader) == 16, "SprHeader must be 16 bytes");
#pragma pack(pop)