#ifndef DOLPHIN_GXENUM_H
#define DOLPHIN_GXENUM_H

#include <dolphin/types.h>

#ifdef __cplusplus
extern "C" {
#endif

#ifdef TARGET_PC
#include <stdbool.h>

typedef bool GXBool;
#else
typedef u8 GXBool;
#endif

#define GX_FALSE ((GXBool)0)
#define GX_TRUE ((GXBool)1)

#define GX_ENABLE ((GXBool)1)
#define GX_DISABLE ((GXBool)0)

typedef enum {
  GX_PERSPECTIVE,
  GX_ORTHOGRAPHIC,
} GXProjectionType;

typedef enum {
  GX_NEVER,
  GX_LESS,
  GX_EQUAL,
  GX_LEQUAL,
  GX_GREATER,
  GX_NEQUAL,
  GX_GEQUAL,
  GX_ALWAYS,
} GXCompare;

typedef enum {
  GX_AOP_AND,
  GX_AOP_OR,
  GX_AOP_XOR,
  GX_AOP_XNOR,
  GX_MAX_ALPHAOP,
} GXAlphaOp;

typedef enum {
  GX_ZC_LINEAR,
  GX_ZC_NEAR,
  GX_ZC_MID,
  GX_ZC_FAR,
} GXZFmt16;

typedef enum {
  GX_GM_1_0,
  GX_GM_1_7,
  GX_GM_2_2,
} GXGamma;

typedef enum {
  GX_PF_RGB8_Z24,
  GX_PF_RGBA6_Z24,
  GX_PF_RGB565_Z16,
  GX_PF_Z24,
  GX_PF_Y8,
  GX_PF_U8,
  GX_PF_V8,
  GX_PF_YUV420,
} GXPixelFmt;

typedef enum {
  GX_QUADS = 0x80,
  GX_TRIANGLES = 0x90,
  GX_TRIANGLESTRIP = 0x98,
  GX_TRIANGLEFAN = 0xA0,
  GX_LINES = 0xA8,
  GX_LINESTRIP = 0xB0,
  GX_POINTS = 0xB8,
} GXPrimitive;

typedef enum {
  GX_VTXFMT0,
  GX_VTXFMT1,
  GX_VTXFMT2,
  GX_VTXFMT3,
  GX_VTXFMT4,
  GX_VTXFMT5,
  GX_VTXFMT6,
  GX_VTXFMT7,
  GX_MAX_VTXFMT,
} GXVtxFmt;

typedef enum {
  GX_VA_PNMTXIDX,
  GX_VA_TEX0MTXIDX,
  GX_VA_TEX1MTXIDX,
  GX_VA_TEX2MTXIDX,
  GX_VA_TEX3MTXIDX,
  GX_VA_TEX4MTXIDX,
  GX_VA_TEX5MTXIDX,
  GX_VA_TEX6MTXIDX,
  GX_VA_TEX7MTXIDX,
  GX_VA_POS,
  GX_VA_NRM,
  GX_VA_CLR0,
  GX_VA_CLR1,
  GX_VA_TEX0,
  GX_VA_TEX1,
  GX_VA_TEX2,
  GX_VA_TEX3,
  GX_VA_TEX4,
  GX_VA_TEX5,
  GX_VA_TEX6,
  GX_VA_TEX7,
  GX_POS_MTX_ARRAY,
  GX_NRM_MTX_ARRAY,
  GX_TEX_MTX_ARRAY,
  GX_LIGHT_ARRAY,
  GX_VA_NBT,
  GX_VA_MAX_ATTR,
  GX_VA_NULL = 0xFF,
} GXAttr;

typedef enum {
  GX_NONE,
  GX_DIRECT,
  GX_INDEX8,
  GX_INDEX16,
} GXAttrType;

#define _GX_TF_CTF 0x20
#define _GX_TF_ZTF 0x10

// Aurora-specific linear texture types
#define _GX_TF_PC 0x40

typedef enum {
  GX_TF_I4 = 0x0,
  GX_TF_I8 = 0x1,
  GX_TF_IA4 = 0x2,
  GX_TF_IA8 = 0x3,
  GX_TF_RGB565 = 0x4,
  GX_TF_RGB5A3 = 0x5,
  GX_TF_RGBA8 = 0x6,
  GX_TF_CMPR = 0xE,

  GX_CTF_R4 = 0x0 | _GX_TF_CTF,
  GX_CTF_RA4 = 0x2 | _GX_TF_CTF,
  GX_CTF_RA8 = 0x3 | _GX_TF_CTF,
  GX_CTF_YUVA8 = 0x6 | _GX_TF_CTF,
  GX_CTF_A8 = 0x7 | _GX_TF_CTF,
  GX_CTF_R8 = 0x8 | _GX_TF_CTF,
  GX_CTF_G8 = 0x9 | _GX_TF_CTF,
  GX_CTF_B8 = 0xA | _GX_TF_CTF,
  GX_CTF_RG8 = 0xB | _GX_TF_CTF,
  GX_CTF_GB8 = 0xC | _GX_TF_CTF,

  GX_TF_Z8 = 0x1 | _GX_TF_ZTF,
  GX_TF_Z16 = 0x3 | _GX_TF_ZTF,
  GX_TF_Z24X8 = 0x6 | _GX_TF_ZTF,

  GX_CTF_Z4 = 0x0 | _GX_TF_ZTF | _GX_TF_CTF,
  GX_CTF_Z8M = 0x9 | _GX_TF_ZTF | _GX_TF_CTF,
  GX_CTF_Z8L = 0xA | _GX_TF_ZTF | _GX_TF_CTF,
  GX_CTF_Z16L = 0xC | _GX_TF_ZTF | _GX_TF_CTF,

  GX_TF_A8 = GX_CTF_A8,

#ifdef TARGET_PC
  GX_TF_R8_PC = 0x1 | _GX_TF_PC,
  GX_TF_RG8_PC = 0x3 | _GX_TF_PC,
  GX_TF_RGBA8_PC = 0x6 | _GX_TF_PC,
  GX_TF_BC1_PC = 0xE | _GX_TF_PC,
#endif
} GXTexFmt;

typedef enum {
  GX_TF_C4 = 0x8,
  GX_TF_C8 = 0x9,
  GX_TF_C14X2 = 0xa,
} GXCITexFmt;

typedef enum {
  GX_CLAMP,
  GX_REPEAT,
  GX_MIRROR,
  GX_MAX_TEXWRAPMODE,
} GXTexWrapMode;

typedef enum {
  GX_NEAR,
  GX_LINEAR,
  GX_NEAR_MIP_NEAR,
  GX_LIN_MIP_NEAR,
  GX_NEAR_MIP_LIN,
  GX_LIN_MIP_LIN,
} GXTexFilter;

typedef enum {
  GX_ANISO_1,
  GX_ANISO_2,
  GX_ANISO_4,
  GX_MAX_ANISOTROPY,
} GXAnisotropy;

typedef enum {
  GX_TEXMAP0,
  GX_TEXMAP1,
  GX_TEXMAP2,
  GX_TEXMAP3,
  GX_TEXMAP4,
  GX_TEXMAP5,
  GX_TEXMAP6,
  GX_TEXMAP7,
  GX_MAX_TEXMAP,
  GX_TEXMAP_NULL = 0xFF,
  GX_TEX_DISABLE = 0x100,
} GXTexMapID;

typedef enum {
  GX_TEXCOORD0,
  GX_TEXCOORD1,
  GX_TEXCOORD2,
  GX_TEXCOORD3,
  GX_TEXCOORD4,
  GX_TEXCOORD5,
  GX_TEXCOORD6,
  GX_TEXCOORD7,
  GX_MAX_TEXCOORD,
  GX_TEXCOORD_NULL = 0xFF,
} GXTexCoordID;

typedef enum {
  GX_TEVSTAGE0,
  GX_TEVSTAGE1,
  GX_TEVSTAGE2,
  GX_TEVSTAGE3,
  GX_TEVSTAGE4,
  GX_TEVSTAGE5,
  GX_TEVSTAGE6,
  GX_TEVSTAGE7,
  GX_TEVSTAGE8,
  GX_TEVSTAGE9,
  GX_TEVSTAGE10,
  GX_TEVSTAGE11,
  GX_TEVSTAGE12,
  GX_TEVSTAGE13,
  GX_TEVSTAGE14,
  GX_TEVSTAGE15,
  GX_MAX_TEVSTAGE,
} GXTevStageID;

typedef enum {
  GX_MODULATE,
  GX_DECAL,
  GX_BLEND,
  GX_REPLACE,
  GX_PASSCLR,
} GXTevMode;

typedef enum {
  GX_MTX3x4,
  GX_MTX2x4,
} GXTexMtxType;

typedef enum {
  GX_TG_MTX3x4,
  GX_TG_MTX2x4,
  GX_TG_BUMP0,
  GX_TG_BUMP1,
  GX_TG_BUMP2,
  GX_TG_BUMP3,
  GX_TG_BUMP4,
  GX_TG_BUMP5,
  GX_TG_BUMP6,
  GX_TG_BUMP7,
  GX_TG_SRTG,
} GXTexGenType;

typedef enum {
  GX_PNMTX0 = 0,
  GX_PNMTX1 = 3,
  GX_PNMTX2 = 6,
  GX_PNMTX3 = 9,
  GX_PNMTX4 = 12,
  GX_PNMTX5 = 15,
  GX_PNMTX6 = 18,
  GX_PNMTX7 = 21,
  GX_PNMTX8 = 24,
  GX_PNMTX9 = 27,
} GXPosNrmMtx;

typedef enum {
  GX_TEXMTX0 = 30,
  GX_TEXMTX1 = 33,
  GX_TEXMTX2 = 36,
  GX_TEXMTX3 = 39,
  GX_TEXMTX4 = 42,
  GX_TEXMTX5 = 45,
  GX_TEXMTX6 = 48,
  GX_TEXMTX7 = 51,
  GX_TEXMTX8 = 54,
  GX_TEXMTX9 = 57,
  GX_IDENTITY = 60,
} GXTexMtx;

typedef enum {
  GX_COLOR0,
  GX_COLOR1,
  GX_ALPHA0,
  GX_ALPHA1,
  GX_COLOR0A0,
  GX_COLOR1A1,
  GX_COLOR_ZERO,
  GX_ALPHA_BUMP,
  GX_ALPHA_BUMPN,
  GX_COLOR_NULL = 0xFF,
} GXChannelID;

typedef enum {
  GX_TG_POS,
  GX_TG_NRM,
  GX_TG_BINRM,
  GX_TG_TANGENT,
  GX_TG_TEX0,
  GX_TG_TEX1,
  GX_TG_TEX2,
  GX_TG_TEX3,
  GX_TG_TEX4,
  GX_TG_TEX5,
  GX_TG_TEX6,
  GX_TG_TEX7,
  GX_TG_TEXCOORD0,
  GX_TG_TEXCOORD1,
  GX_TG_TEXCOORD2,
  GX_TG_TEXCOORD3,
  GX_TG_TEXCOORD4,
  GX_TG_TEXCOORD5,
  GX_TG_TEXCOORD6,
  GX_TG_COLOR0,
  GX_TG_COLOR1,
  GX_MAX_TEXGENSRC,
} GXTexGenSrc;

typedef enum {
  GX_BM_NONE,
  GX_BM_BLEND,
  GX_BM_LOGIC,
  GX_BM_SUBTRACT,
  GX_MAX_BLENDMODE,
} GXBlendMode;

typedef enum {
  GX_BL_ZERO,
  GX_BL_ONE,
  GX_BL_SRCCLR,
  GX_BL_INVSRCCLR,
  GX_BL_SRCALPHA,
  GX_BL_INVSRCALPHA,
  GX_BL_DSTALPHA,
  GX_BL_INVDSTALPHA,
  GX_BL_DSTCLR = GX_BL_SRCCLR,
  GX_BL_INVDSTCLR = GX_BL_INVSRCCLR,
} GXBlendFactor;

typedef enum {
  GX_LO_CLEAR,
  GX_LO_AND,
  GX_LO_REVAND,
  GX_LO_COPY,
  GX_LO_INVAND,
  GX_LO_NOOP,
  GX_LO_XOR,
  GX_LO_OR,
  GX_LO_NOR,
  GX_LO_EQUIV,
  GX_LO_INV,
  GX_LO_REVOR,
  GX_LO_INVCOPY,
  GX_LO_INVOR,
  GX_LO_NAND,
  GX_LO_SET,
} GXLogicOp;

typedef enum {
  GX_POS_XY = 0,
  GX_POS_XYZ = 1,
  GX_NRM_XYZ = 0,
  GX_NRM_NBT = 1,
  GX_NRM_NBT3 = 2,
  GX_CLR_RGB = 0,
  GX_CLR_RGBA = 1,
  GX_TEX_S = 0,
  GX_TEX_ST = 1,
} GXCompCnt;

typedef enum {
  GX_U8 = 0,
  GX_S8 = 1,
  GX_U16 = 2,
  GX_S16 = 3,
  GX_F32 = 4,
  GX_RGB565 = 0,
  GX_RGB8 = 1,
  GX_RGBX8 = 2,
  GX_RGBA4 = 3,
  GX_RGBA6 = 4,
  GX_RGBA8 = 5,
} GXCompType;

typedef enum {
  GX_PTTEXMTX0 = 64,
  GX_PTTEXMTX1 = 67,
  GX_PTTEXMTX2 = 70,
  GX_PTTEXMTX3 = 73,
  GX_PTTEXMTX4 = 76,
  GX_PTTEXMTX5 = 79,
  GX_PTTEXMTX6 = 82,
  GX_PTTEXMTX7 = 85,
  GX_PTTEXMTX8 = 88,
  GX_PTTEXMTX9 = 91,
  GX_PTTEXMTX10 = 94,
  GX_PTTEXMTX11 = 97,
  GX_PTTEXMTX12 = 100,
  GX_PTTEXMTX13 = 103,
  GX_PTTEXMTX14 = 106,
  GX_PTTEXMTX15 = 109,
  GX_PTTEXMTX16 = 112,
  GX_PTTEXMTX17 = 115,
  GX_PTTEXMTX18 = 118,
  GX_PTTEXMTX19 = 121,
  GX_PTIDENTITY = 125,
} GXPTTexMtx;

typedef enum {
  GX_TEVPREV,
  GX_TEVREG0,
  GX_TEVREG1,
  GX_TEVREG2,
  GX_MAX_TEVREG,
} GXTevRegID;

typedef enum {
  GX_DF_NONE,
  GX_DF_SIGN,
  GX_DF_CLAMP,
} GXDiffuseFn;

typedef enum {
  GX_SRC_REG,
  GX_SRC_VTX,
} GXColorSrc;

typedef enum {
  GX_AF_SPEC,
  GX_AF_SPOT,
  GX_AF_NONE,
} GXAttnFn;

typedef enum {
  GX_LIGHT0 = 0x001,
  GX_LIGHT1 = 0x002,
  GX_LIGHT2 = 0x004,
  GX_LIGHT3 = 0x008,
  GX_LIGHT4 = 0x010,
  GX_LIGHT5 = 0x020,
  GX_LIGHT6 = 0x040,
  GX_LIGHT7 = 0x080,
  GX_MAX_LIGHT = 0x100,
  GX_LIGHT_NULL = 0,
} GXLightID;

typedef enum {
  GX_TO_ZERO,
  GX_TO_SIXTEENTH,
  GX_TO_EIGHTH,
  GX_TO_FOURTH,
  GX_TO_HALF,
  GX_TO_ONE,
  GX_MAX_TEXOFFSET,
} GXTexOffset;

typedef enum {
  GX_SP_OFF,
  GX_SP_FLAT,
  GX_SP_COS,
  GX_SP_COS2,
  GX_SP_SHARP,
  GX_SP_RING1,
  GX_SP_RING2,
} GXSpotFn;

typedef enum {
  GX_DA_OFF,
  GX_DA_GENTLE,
  GX_DA_MEDIUM,
  GX_DA_STEEP,
} GXDistAttnFn;

typedef enum {
  GX_CULL_NONE,
  GX_CULL_FRONT,
  GX_CULL_BACK,
  GX_CULL_ALL

} GXCullMode;

typedef enum { GX_TEV_SWAP0 = 0, GX_TEV_SWAP1, GX_TEV_SWAP2, GX_TEV_SWAP3, GX_MAX_TEVSWAP } GXTevSwapSel;

typedef enum { GX_CH_RED = 0, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA } GXTevColorChan;

typedef enum _GXFogType {
  GX_FOG_NONE = 0,
  GX_FOG_PERSP_LIN = 2,
  GX_FOG_PERSP_EXP = 4,
  GX_FOG_PERSP_EXP2 = 5,
  GX_FOG_PERSP_REVEXP = 6,
  GX_FOG_PERSP_REVEXP2 = 7,
  GX_FOG_ORTHO_LIN = 10,
  GX_FOG_ORTHO_EXP = 12,
  GX_FOG_ORTHO_EXP2 = 13,
  GX_FOG_ORTHO_REVEXP = 14,
  GX_FOG_ORTHO_REVEXP2 = 15,
  GX_FOG_LIN = GX_FOG_PERSP_LIN,
  GX_FOG_EXP = GX_FOG_PERSP_EXP,
  GX_FOG_EXP2 = GX_FOG_PERSP_EXP2,
  GX_FOG_REVEXP = GX_FOG_PERSP_REVEXP,
  GX_FOG_REVEXP2 = GX_FOG_PERSP_REVEXP2,
} GXFogType;

typedef enum {
  GX_CC_CPREV,
  GX_CC_APREV,
  GX_CC_C0,
  GX_CC_A0,
  GX_CC_C1,
  GX_CC_A1,
  GX_CC_C2,
  GX_CC_A2,
  GX_CC_TEXC,
  GX_CC_TEXA,
  GX_CC_RASC,
  GX_CC_RASA,
  GX_CC_ONE,
  GX_CC_HALF,
  GX_CC_KONST,
  GX_CC_ZERO
} GXTevColorArg;

typedef enum {
  GX_CA_APREV,
  GX_CA_A0,
  GX_CA_A1,
  GX_CA_A2,
  GX_CA_TEXA,
  GX_CA_RASA,
  GX_CA_KONST,
  GX_CA_ZERO
} GXTevAlphaArg;

typedef enum {
  GX_TEV_ADD = 0,
  GX_TEV_SUB = 1,
  GX_TEV_COMP_R8_GT = 8,
  GX_TEV_COMP_R8_EQ = 9,
  GX_TEV_COMP_GR16_GT = 10,
  GX_TEV_COMP_GR16_EQ = 11,
  GX_TEV_COMP_BGR24_GT = 12,
  GX_TEV_COMP_BGR24_EQ = 13,
  GX_TEV_COMP_RGB8_GT = 14,
  GX_TEV_COMP_RGB8_EQ = 15,
  GX_TEV_COMP_A8_GT = GX_TEV_COMP_RGB8_GT,
  GX_TEV_COMP_A8_EQ = GX_TEV_COMP_RGB8_EQ
} GXTevOp;

typedef enum { GX_TB_ZERO, GX_TB_ADDHALF, GX_TB_SUBHALF, GX_MAX_TEVBIAS } GXTevBias;

typedef enum { GX_CS_SCALE_1, GX_CS_SCALE_2, GX_CS_SCALE_4, GX_CS_DIVIDE_2, GX_MAX_TEVSCALE } GXTevScale;

typedef enum {
  GX_TEV_KCSEL_8_8 = 0x00,
  GX_TEV_KCSEL_7_8 = 0x01,
  GX_TEV_KCSEL_6_8 = 0x02,
  GX_TEV_KCSEL_5_8 = 0x03,
  GX_TEV_KCSEL_4_8 = 0x04,
  GX_TEV_KCSEL_3_8 = 0x05,
  GX_TEV_KCSEL_2_8 = 0x06,
  GX_TEV_KCSEL_1_8 = 0x07,
  GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8,
  GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8,
  GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8,
  GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8,
  GX_TEV_KCSEL_K0 = 0x0C,
  GX_TEV_KCSEL_K1 = 0x0D,
  GX_TEV_KCSEL_K2 = 0x0E,
  GX_TEV_KCSEL_K3 = 0x0F,
  GX_TEV_KCSEL_K0_R = 0x10,
  GX_TEV_KCSEL_K1_R = 0x11,
  GX_TEV_KCSEL_K2_R = 0x12,
  GX_TEV_KCSEL_K3_R = 0x13,
  GX_TEV_KCSEL_K0_G = 0x14,
  GX_TEV_KCSEL_K1_G = 0x15,
  GX_TEV_KCSEL_K2_G = 0x16,
  GX_TEV_KCSEL_K3_G = 0x17,
  GX_TEV_KCSEL_K0_B = 0x18,
  GX_TEV_KCSEL_K1_B = 0x19,
  GX_TEV_KCSEL_K2_B = 0x1A,
  GX_TEV_KCSEL_K3_B = 0x1B,
  GX_TEV_KCSEL_K0_A = 0x1C,
  GX_TEV_KCSEL_K1_A = 0x1D,
  GX_TEV_KCSEL_K2_A = 0x1E,
  GX_TEV_KCSEL_K3_A = 0x1F
} GXTevKColorSel;

typedef enum {
  GX_TEV_KASEL_8_8 = 0x00,
  GX_TEV_KASEL_7_8 = 0x01,
  GX_TEV_KASEL_6_8 = 0x02,
  GX_TEV_KASEL_5_8 = 0x03,
  GX_TEV_KASEL_4_8 = 0x04,
  GX_TEV_KASEL_3_8 = 0x05,
  GX_TEV_KASEL_2_8 = 0x06,
  GX_TEV_KASEL_1_8 = 0x07,
  GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8,
  GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8,
  GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8,
  GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8,
  GX_TEV_KASEL_K0_R = 0x10,
  GX_TEV_KASEL_K1_R = 0x11,
  GX_TEV_KASEL_K2_R = 0x12,
  GX_TEV_KASEL_K3_R = 0x13,
  GX_TEV_KASEL_K0_G = 0x14,
  GX_TEV_KASEL_K1_G = 0x15,
  GX_TEV_KASEL_K2_G = 0x16,
  GX_TEV_KASEL_K3_G = 0x17,
  GX_TEV_KASEL_K0_B = 0x18,
  GX_TEV_KASEL_K1_B = 0x19,
  GX_TEV_KASEL_K2_B = 0x1A,
  GX_TEV_KASEL_K3_B = 0x1B,
  GX_TEV_KASEL_K0_A = 0x1C,
  GX_TEV_KASEL_K1_A = 0x1D,
  GX_TEV_KASEL_K2_A = 0x1E,
  GX_TEV_KASEL_K3_A = 0x1F
} GXTevKAlphaSel;

typedef enum { GX_KCOLOR0 = 0, GX_KCOLOR1, GX_KCOLOR2, GX_KCOLOR3, GX_MAX_KCOLOR } GXTevKColorID;

typedef enum {
  GX_ZT_DISABLE,
  GX_ZT_ADD,
  GX_ZT_REPLACE,
  GX_MAX_ZTEXOP,
} GXZTexOp;

typedef enum {
  GX_ITF_8,
  GX_ITF_5,
  GX_ITF_4,
  GX_ITF_3,
  GX_MAX_ITFORMAT,
} GXIndTexFormat;

typedef enum {
  GX_ITB_NONE,
  GX_ITB_S,
  GX_ITB_T,
  GX_ITB_ST,
  GX_ITB_U,
  GX_ITB_SU,
  GX_ITB_TU,
  GX_ITB_STU,
  GX_MAX_ITBIAS,
} GXIndTexBiasSel;

typedef enum {
  GX_ITBA_OFF,
  GX_ITBA_S,
  GX_ITBA_T,
  GX_ITBA_U,
  GX_MAX_ITBALPHA,
} GXIndTexAlphaSel;

typedef enum {
  GX_ITM_OFF,
  GX_ITM_0,
  GX_ITM_1,
  GX_ITM_2,
  GX_ITM_S0 = 5,
  GX_ITM_S1,
  GX_ITM_S2,
  GX_ITM_T0 = 9,
  GX_ITM_T1,
  GX_ITM_T2,
} GXIndTexMtxID;

typedef enum {
  GX_ITW_OFF,
  GX_ITW_256,
  GX_ITW_128,
  GX_ITW_64,
  GX_ITW_32,
  GX_ITW_16,
  GX_ITW_0,
  GX_MAX_ITWRAP,
} GXIndTexWrap;

typedef enum {
  GX_INDTEXSTAGE0,
  GX_INDTEXSTAGE1,
  GX_INDTEXSTAGE2,
  GX_INDTEXSTAGE3,
  GX_MAX_INDTEXSTAGE,
} GXIndTexStageID;

typedef enum {
  GX_ITS_1,
  GX_ITS_2,
  GX_ITS_4,
  GX_ITS_8,
  GX_ITS_16,
  GX_ITS_32,
  GX_ITS_64,
  GX_ITS_128,
  GX_ITS_256,
  GX_MAX_ITSCALE,
} GXIndTexScale;

typedef enum {
  GX_PERF0_VERTICES,
  GX_PERF0_CLIP_VTX,
  GX_PERF0_CLIP_CLKS,
  GX_PERF0_XF_WAIT_IN,
  GX_PERF0_XF_WAIT_OUT,
  GX_PERF0_XF_XFRM_CLKS,
  GX_PERF0_XF_LIT_CLKS,
  GX_PERF0_XF_BOT_CLKS,
  GX_PERF0_XF_REGLD_CLKS,
  GX_PERF0_XF_REGRD_CLKS,
  GX_PERF0_CLIP_RATIO,

  GX_PERF0_TRIANGLES,
  GX_PERF0_TRIANGLES_CULLED,
  GX_PERF0_TRIANGLES_PASSED,
  GX_PERF0_TRIANGLES_SCISSORED,
  GX_PERF0_TRIANGLES_0TEX,
  GX_PERF0_TRIANGLES_1TEX,
  GX_PERF0_TRIANGLES_2TEX,
  GX_PERF0_TRIANGLES_3TEX,
  GX_PERF0_TRIANGLES_4TEX,
  GX_PERF0_TRIANGLES_5TEX,
  GX_PERF0_TRIANGLES_6TEX,
  GX_PERF0_TRIANGLES_7TEX,
  GX_PERF0_TRIANGLES_8TEX,
  GX_PERF0_TRIANGLES_0CLR,
  GX_PERF0_TRIANGLES_1CLR,
  GX_PERF0_TRIANGLES_2CLR,

  GX_PERF0_QUAD_0CVG,
  GX_PERF0_QUAD_NON0CVG,
  GX_PERF0_QUAD_1CVG,
  GX_PERF0_QUAD_2CVG,
  GX_PERF0_QUAD_3CVG,
  GX_PERF0_QUAD_4CVG,
  GX_PERF0_AVG_QUAD_CNT,

  GX_PERF0_CLOCKS,
  GX_PERF0_NONE,
} GXPerf0;

typedef enum {
  GX_PERF1_TEXELS,
  GX_PERF1_TX_IDLE,
  GX_PERF1_TX_REGS,
  GX_PERF1_TX_MEMSTALL,
  GX_PERF1_TC_CHECK1_2,
  GX_PERF1_TC_CHECK3_4,
  GX_PERF1_TC_CHECK5_6,
  GX_PERF1_TC_CHECK7_8,
  GX_PERF1_TC_MISS,

  GX_PERF1_VC_ELEMQ_FULL,
  GX_PERF1_VC_MISSQ_FULL,
  GX_PERF1_VC_MEMREQ_FULL,
  GX_PERF1_VC_STATUS7,
  GX_PERF1_VC_MISSREP_FULL,
  GX_PERF1_VC_STREAMBUF_LOW,
  GX_PERF1_VC_ALL_STALLS,
  GX_PERF1_VERTICES,

  GX_PERF1_FIFO_REQ,
  GX_PERF1_CALL_REQ,
  GX_PERF1_VC_MISS_REQ,
  GX_PERF1_CP_ALL_REQ,

  GX_PERF1_CLOCKS,
  GX_PERF1_NONE,
} GXPerf1;

typedef enum {
  GX_VC_POS = 0,
  GX_VC_NRM = 1,
  GX_VC_CLR0 = 2,
  GX_VC_CLR1 = 3,
  GX_VC_TEX0 = 4,
  GX_VC_TEX1 = 5,
  GX_VC_TEX2 = 6,
  GX_VC_TEX3 = 7,
  GX_VC_TEX4 = 8,
  GX_VC_TEX5 = 9,
  GX_VC_TEX6 = 10,
  GX_VC_TEX7 = 11,
  GX_VC_ALL = 15,
} GXVCachePerf;

typedef enum {
  GX_CLIP_ENABLE = 0,
  GX_CLIP_DISABLE = 1,
} GXClipMode;

typedef enum {
  GX_CLAMP_NONE = 0,
  GX_CLAMP_TOP = 1,
  GX_CLAMP_BOTTOM = 2,
} GXFBClamp;

typedef enum {
  GX_TLUT0 = 0,
  GX_TLUT1 = 1,
  GX_TLUT2 = 2,
  GX_TLUT3 = 3,
  GX_TLUT4 = 4,
  GX_TLUT5 = 5,
  GX_TLUT6 = 6,
  GX_TLUT7 = 7,
  GX_TLUT8 = 8,
  GX_TLUT9 = 9,
  GX_TLUT10 = 10,
  GX_TLUT11 = 11,
  GX_TLUT12 = 12,
  GX_TLUT13 = 13,
  GX_TLUT14 = 14,
  GX_TLUT15 = 15,
  GX_BIGTLUT0 = 16,
  GX_BIGTLUT1 = 17,
  GX_BIGTLUT2 = 18,
  GX_BIGTLUT3 = 19,
} GXTlut;

typedef enum {
  GX_TL_IA8,
  GX_TL_RGB565,
  GX_TL_RGB5A3,
  GX_MAX_TLUTFMT,
} GXTlutFmt;

typedef enum {
  GX_TLUT_16 = 1,
  GX_TLUT_32 = 2,
  GX_TLUT_64 = 4,
  GX_TLUT_128 = 8,
  GX_TLUT_256 = 16,
  GX_TLUT_512 = 32,
  GX_TLUT_1K = 64,
  GX_TLUT_2K = 128,
  GX_TLUT_4K = 256,
  GX_TLUT_8K = 512,
  GX_TLUT_16K = 1024,
} GXTlutSize;

typedef enum {
    GX_READ_00,
    GX_READ_FF,
    GX_READ_NONE,
} GXAlphaReadMode;

typedef enum {
  GX_TEXCACHE_32K,
  GX_TEXCACHE_128K,
  GX_TEXCACHE_512K,
  GX_TEXCACHE_NONE,
} GXTexCacheSize;

typedef enum {
  GX_MT_XF_FLUSH = 1,
  GX_MT_DL_SAVE_CONTEXT = 2,
  GX_MT_NULL = 0,
} GXMiscToken;

typedef enum {
  GX_CMD_LOAD_INDX_A = 0x20,
  GX_CMD_LOAD_INDX_B = 0x28,
  GX_CMD_LOAD_INDX_C = 0x30,
  GX_CMD_LOAD_INDX_D = 0x38,

  GX_CMD_LOAD_CP_REG = 0x08,
  GX_CMD_LOAD_XF_REG = 0x10,
  GX_CMD_LOAD_BP_REG = 0x61,
} GXCommand;

typedef enum {
  GX_CP_REG_MTXIDXA = 0x30,      // Matrix index A
  GX_CP_REG_MTXIDXB = 0x40,      // Matrix index B
  GX_CP_REG_VCD_LO = 0x50,       // Vertex descriptor (lo)
  GX_CP_REG_VCD_HI = 0x60,       // Vertex descriptor (hi)
  GX_CP_REG_VAT_GRP0 = 0x70,     // Vertex attribute table (group 0)
  GX_CP_REG_VAT_GRP1 = 0x80,     // Vertex attribute table (group 1)
  GX_CP_REG_VAT_GRP2 = 0x90,     // Vertex attribute table (group 2)
  GX_CP_REG_ARRAYBASE = 0xA0,    // Vertex array start/base
  GX_CP_REG_ARRAYSTRIDE = 0xB0,  // Vertex array stride
} GXCPRegs;

#ifdef __cplusplus
}
#endif

#endif
