whiteoutlib 0.1.4

Read and write Blizzard game assets from Rust: models (MDX, M2, M3), textures (BLP, DDS, PNG, JPEG, BMP, TGA, TIFF, GIF) and archives (CASC, MPQ).
Documentation
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2026 Fernando Sahmkow
//
// AUTO-GENERATED by scripts/gen_sno_defs.py — do not edit manually.

#pragma once

#include <whiteout/common_types.h>

#include <cstddef>
#include <span>

namespace whiteout {
namespace sno {

/// A single field inside a complex type definition.
struct SnoFieldDef {
    u32 typeHashes[3]; ///< Type hash chain (e.g. DT_VARIABLEARRAY, SubType, DT_NULL)
    u32 nameIndex;     ///< Index into the field-name string table
    u32 flags;
    i32 offset;             ///< Byte offset within the parent struct
    i32 arrayLength;        ///< Fixed array length (-1 if not a fixed array)
    i32 group;              ///< SNO group for DT_SNO / DT_GBID (-1 if N/A)
    i32 serializedBitCount; ///< If 1, value is a boolean
};

/// A type definition (basic or complex).
struct SnoTypeDef {
    u32 hash;
    u32 isBasic; ///< 1 = basic (leaf), 0 = complex (struct)
    u32 size;    ///< Serialized size in bytes (0 for variable-size basics)
    u32 flags;
    u32 fieldsOffset; ///< Start index into the global field array
    u32 fieldsCount;  ///< Number of fields
    u32 dwFormatHash; ///< Non-zero for root SNO types
};

/// Abstract interface for SNO type registries.
///
/// Both Diablo III and Diablo IV share the same field/type layout; only the
/// key used to resolve a root type differs (group ID vs. format hash).
class SnoTypeRegistry {
public:
    virtual ~SnoTypeRegistry() = default;

    /// Look up a type definition by its type hash.
    /// Returns nullptr if not found.
    virtual const SnoTypeDef* findType(u32 typeHash) const = 0;

    /// Look up the root type hash for a game-specific key
    /// (format hash for D4, group ID for D3).
    /// Returns 0 if not found.
    virtual u32 typeHashFromKey(u32 key) const = 0;

    /// Get the name of a type.
    virtual const char* typeName(const SnoTypeDef& def) const = 0;

    /// Get the fields of a complex type.
    virtual std::span<const SnoFieldDef> fields(const SnoTypeDef& def) const = 0;

    /// Get the name of a field.
    virtual const char* fieldName(const SnoFieldDef& def) const = 0;

    /// Look up a root type hash by its type name (e.g. "EffectGroupDefinition").
    /// Returns 0 if not found.  Default returns 0 (override in subclasses).
    virtual u32 typeHashFromName(const char* name) const {
        (void)name;
        return 0;
    }
};

} // namespace sno
} // namespace whiteout