DDS (DirectDraw Surface)
The .dds extension in KOTOR does not represent a standard Microsoft DirectDraw Surface file. Instead, the engine strictly expects a proprietary format consisting of a bespoke 20-byte configuration prefix followed by raw DXT compression blocks. The vanilla parsing logic completely ignores standard 124-byte DDS magic headers.
At a Glance
| Property | Value |
|---|---|
| Extension(s) | .dds |
| Magic Signature | None (Proprietary 20-Byte Prefix) |
| Type | BioWare DirectDraw Wrapper |
| Rust Reference | View rakata_formats::Dds in Rustdocs |
Data Model Structure
rakata-formats is built to natively parse both standard Microsoft DDS architecture and KotOR’s proprietary CResDDS format transparently. When evaluating a .dds file via rakata_formats::Dds:
- Bilateral Read Path: If the file begins with the standard Microsoft
DDSmagic bytes, Rakata leverages a standard pipeline to extract the payload. If those magic bytes are missing, Rakata immediately pivots and parses the data natively as a proprietary K1CResDDS20-byte payload. - Strict Serialization: Regardless of which variation is ingested from the disk, Rakata will strictly emit valid 20-byte KotOR-compliant payloads during binary serialization.
Engine Audits & Decompilation
The following documents the engine’s exact load sequence for DDS textures mapped from swkotor.exe.
(Decompilation logic for this section was audited and verified via native Ghidra pipeline against swkotor.exe, explicitly pulling from CResDDS::GetDDSAttrib at 0x00710ee0.)
| Pipeline Event | Ghidra Provenance & Engine Behavior |
|---|---|
| Prefix Stripping | The engine’s parser explicitly expects and strips a proprietary 20-byte magic header wrapper prepended to the DDS buffer: width (+0x00), height (+0x04), byte code (+0x08), base-size (+0x0C), and an alpha_mean FLOAT (+0x10). |
| Block Calculation | The runtime completely mimics the TPC logic for memory block sizing. Fundamentally, the algorithm determines the 3D dimensions via the formula: (pixel_type == 4) * 8 + 8. Code 3 explicitly evaluates into 8-byte texture blocks, while Code 4 evaluates to 16-byte blocks. |
Tip
Reserved Gaps: The bytes spanning
+0x09to+0x0Bin the header prefix are entirely ignored by theGetDDSAttribread path. We preserve them strictly for round-trip fidelity.