API Design

/* --- Texture Loading --- */

/* PVR texture header (matches hardware format) */
typedef struct {
    uint32_t    format;     /* SH_TEX_ARGB1555, SH_TEX_RGB565, SH_TEX_VQ, etc. */
    uint16_t    width;
    uint16_t    height;
    uint8_t     mipmaps;    /* 0 = no mipmaps, 1+ = mipmap chain included */
    uint8_t     twiddled;   /* 1 = Morton order, 0 = stride */
    uint16_t    reserved;
    uint32_t    data_size;  /* Bytes of pixel data following header */
} sh_tex_header_t;

/* Texture formats (maps to PVR2 hardware) */
typedef enum {
    SH_TEX_ARGB1555    = 0,
    SH_TEX_RGB565      = 1,
    SH_TEX_ARGB4444    = 2,
    SH_TEX_YUV422      = 3,
    SH_TEX_BUMP        = 4,    /* S/T angle pairs, 16-bit */
    SH_TEX_PAL4        = 5,    /* 4-bit paletted (16 colors) */
    SH_TEX_PAL8        = 6,    /* 8-bit paletted (256 colors) */
} sh_tex_format_t;

/* Texture handle (VRAM pointer + metadata) */
typedef struct {
    pvr_ptr_t       vram_addr;  /* PVR VRAM address */
    sh_tex_format_t format;
    uint16_t        width;
    uint16_t        height;
    uint8_t         mipmaps;
} sh_texture_t;

/* Load a .pvr file from filesystem, upload to VRAM, return handle.
   Uses DMA transfer if available (pvr_txr_load_dma). */
int sh_tex_load(const char *path, sh_texture_t *out);

/* Load a KOS .kmg file (for compatibility with existing KOS assets). */
int sh_tex_load_kmg(const char *path, sh_texture_t *out);

/* Free a texture's VRAM allocation. */
void sh_tex_free(sh_texture_t *tex);

/* Load VQ codebook + indices in one operation (for VQ textures). */
int sh_tex_load_vq(const char *path, sh_texture_t *out);


/* --- Mesh Loading --- */

/* Pre-sorted submesh (one per PVR2 polygon list) */
typedef struct {
    uint32_t    list_type;      /* PVR_LIST_OP_POLY, PVR_LIST_TR_POLY, etc. */
    uint32_t    vertex_count;
    uint32_t    strip_count;    /* Number of triangle strips */
    /* Vertex data follows in memory (sh_vertex_t[]) */
} sh_submesh_header_t;

/* Vertex format (matches pvr_vertex_t layout for zero-copy submission) */
typedef struct {
    uint32_t    flags;      /* PVR_CMD_VERTEX or PVR_CMD_VERTEX_EOL */
    float       x, y, z;   /* Screen-space or pre-transform */
    float       u, v;       /* Texture coordinates */
    uint32_t    base_color; /* ARGB packed */
    uint32_t    offset_color; /* ARGB packed (for bump/environment) */
} sh_vertex_t;

/* Mesh handle */
typedef struct {
    int             submesh_count;
    sh_submesh_header_t *submeshes;   /* Array of submesh headers */
    sh_vertex_t    *vertex_pool;      /* All vertices contiguous in RAM */
    void           *_raw;             /* Raw allocation (for free) */
} sh_mesh_t;

/* Load a pre-converted .shm mesh file. */
int sh_mesh_load(const char *path, sh_mesh_t *out);

/* Free mesh memory. */
void sh_mesh_free(sh_mesh_t *mesh);