diff --git a/configure.py b/configure.py index c48ebc31b..403dba82e 100755 --- a/configure.py +++ b/configure.py @@ -1232,7 +1232,7 @@ config.libs = [ [ Object(NonMatching, "dolphin/gx/GXInit.c", extra_cflags=["-opt nopeephole"]), Object(Matching, "dolphin/gx/GXFifo.c"), - Object(NonMatching, "dolphin/gx/GXAttr.c"), + Object(Matching, "dolphin/gx/GXAttr.c"), Object(NonMatching, "dolphin/gx/GXMisc.c"), Object(NonMatching, "dolphin/gx/GXGeometry.c"), Object(NonMatching, "dolphin/gx/GXFrameBuf.c"), diff --git a/include/dolphin/gx/GX.h b/include/dolphin/gx/GX.h index 3371092e0..7a5f7ea2b 100644 --- a/include/dolphin/gx/GX.h +++ b/include/dolphin/gx/GX.h @@ -42,6 +42,8 @@ extern "C" { (reg) = ((u32) (reg) & ~(((1 << (nbits)) - 1) << (shift))) | \ ((u32) (value) << (shift)); +#define GET_REG_FIELD(reg, size, shift) ((int)((reg) >> (shift)) & ((1 << (size)) - 1)) + #define SET_REG_FIELD(reg, size, shift, val) \ (reg) = ((u32)(reg) & ~(((1 << (size)) - 1) << (shift))) | ((u32)(val) << (shift)); \ diff --git a/include/dolphin/gx/GXAttr.h b/include/dolphin/gx/GXAttr.h index 9c4940990..6a2ea4568 100644 --- a/include/dolphin/gx/GXAttr.h +++ b/include/dolphin/gx/GXAttr.h @@ -36,6 +36,7 @@ void GXSetNumTexGens(u8 numTexGens); void GXGetVtxAttrFmtv(GXVtxFmt param_0, GXVtxAttrFmtList* param_1); void GXGetVtxAttrFmt(GXVtxFmt param_0, int param_1, GXCompCnt* param_2, GXCompType* param_3, u8* param_4); +void GXGetVtxDesc(GXAttr attr, GXAttrType* type); void GXGetVtxDescv(GXVtxDescList* attrPtr); static inline void GXSetTexCoordGen(GXTexCoordID dst, GXTexGenType type, GXTexGenSrc src, u32 mtx) { diff --git a/src/dolphin/gx/GXAttr.c b/src/dolphin/gx/GXAttr.c index d9981b613..3a044d7fc 100644 --- a/src/dolphin/gx/GXAttr.c +++ b/src/dolphin/gx/GXAttr.c @@ -1,42 +1,34 @@ #include "dolphin/gx/GXAttr.h" #include "dolphin/gx/GX.h" -static inline void SETVCDATTR(GXAttr name, GXAttrType type) { - switch (name) { +static inline void SETVCDATTR(GXAttr attr, GXAttrType type) { + switch (attr) { case GX_VA_PNMTXIDX: GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_POSMTXIDX_ST, GX_CP_VCD_LO_POSMTXIDX_END); break; case GX_VA_TEX0MTXIDX: - GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX0MTXIDX_ST, - GX_CP_VCD_LO_TEX0MTXIDX_END); + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX0MTXIDX_ST, GX_CP_VCD_LO_TEX0MTXIDX_END); break; case GX_VA_TEX1MTXIDX: - GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX1MTXIDX_ST, - GX_CP_VCD_LO_TEX1MTXIDX_END); + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX1MTXIDX_ST, GX_CP_VCD_LO_TEX1MTXIDX_END); break; case GX_VA_TEX2MTXIDX: - GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX2MTXIDX_ST, - GX_CP_VCD_LO_TEX2MTXIDX_END); + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX2MTXIDX_ST, GX_CP_VCD_LO_TEX2MTXIDX_END); break; case GX_VA_TEX3MTXIDX: - GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX3MTXIDX_ST, - GX_CP_VCD_LO_TEX3MTXIDX_END); + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX3MTXIDX_ST, GX_CP_VCD_LO_TEX3MTXIDX_END); break; case GX_VA_TEX4MTXIDX: - GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX4MTXIDX_ST, - GX_CP_VCD_LO_TEX4MTXIDX_END); + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX4MTXIDX_ST, GX_CP_VCD_LO_TEX4MTXIDX_END); break; case GX_VA_TEX5MTXIDX: - GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX5MTXIDX_ST, - GX_CP_VCD_LO_TEX5MTXIDX_END); + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX5MTXIDX_ST, GX_CP_VCD_LO_TEX5MTXIDX_END); break; case GX_VA_TEX6MTXIDX: - GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX6MTXIDX_ST, - GX_CP_VCD_LO_TEX6MTXIDX_END); + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX6MTXIDX_ST, GX_CP_VCD_LO_TEX6MTXIDX_END); break; case GX_VA_TEX7MTXIDX: - GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX7MTXIDX_ST, - GX_CP_VCD_LO_TEX7MTXIDX_END); + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX7MTXIDX_ST, GX_CP_VCD_LO_TEX7MTXIDX_END); break; case GX_VA_POS: GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_POS_ST, GX_CP_VCD_LO_POS_END); @@ -92,6 +84,29 @@ static inline void SETVCDATTR(GXAttr name, GXAttrType type) { } } +static void __GXXfVtxSpecs(void) { + u32 nCols = 0; + u32 nNrm; + u32 nTex; + u32 reg; + + nCols = GET_REG_FIELD(gx->vcdLo, 2, 13) ? 1 : 0; + nCols += GET_REG_FIELD(gx->vcdLo, 2, 15) ? 1 : 0; + nNrm = gx->hasBiNrms ? 2 : gx->hasNrms ? 1 : 0; + nTex = 0; + nTex += GET_REG_FIELD(gx->vcdHi, 2, 0) ? 1 : 0; + nTex += GET_REG_FIELD(gx->vcdHi, 2, 2) ? 1 : 0; + nTex += GET_REG_FIELD(gx->vcdHi, 2, 4) ? 1 : 0; + nTex += GET_REG_FIELD(gx->vcdHi, 2, 6) ? 1 : 0; + nTex += GET_REG_FIELD(gx->vcdHi, 2, 8) ? 1 : 0; + nTex += GET_REG_FIELD(gx->vcdHi, 2, 10) ? 1 : 0; + nTex += GET_REG_FIELD(gx->vcdHi, 2, 12) ? 1 : 0; + nTex += GET_REG_FIELD(gx->vcdHi, 2, 14) ? 1 : 0; + reg = (nCols) | (nNrm << 2) | (nTex << 4); + GX_WRITE_XF_REG(8, reg); + gx->bpSentNot = GX_TRUE; +} + void GXSetVtxDesc(GXAttr name, GXAttrType type) { SETVCDATTR(name, type); @@ -120,25 +135,6 @@ void GXSetVtxDescv(GXVtxDescList* list) { gx->dirtyState |= GX_DIRTY_VCD; } -static void __GXXfVtxSpecs(void) { - u32 normCount, colorCount, texCount; - - normCount = gx->hasBiNrms ? 2 : (gx->hasNrms ? 1 : 0); - - // Both fields in one access - colorCount = 33 - __cntlzw((gx->vcdLo & (0xf << 0xd)) >> 0xd); - colorCount /= 2; // equivalent to /=2 and >>= 1 - - // All 16 assigned bits in VCD_Hi - texCount = 33 - __cntlzw((gx->vcdHi & (0xffff << 0)) >> 0); - texCount /= 2; // equivalent to /=2 and >>= 1 - - GX_XF_LOAD_REG(GX_XF_REG_INVERTEXSPEC, (colorCount) | (normCount << 2) | (texCount << 4)); - gx->bpSentNot = GX_TRUE; - - return; -} - void __GXSetVCD(void) { GX_CP_LOAD_REG(GX_CP_REG_VCD_LO, gx->vcdLo); GX_CP_LOAD_REG(GX_CP_REG_VCD_HI, gx->vcdHi); @@ -195,105 +191,45 @@ void __GXCalculateVLim(void) { gx->vLim = vlim; } -void GXGetVtxDesc(int param_0, GXAttrType* param_1) { - int local_38; +void GXGetVtxDesc(GXAttr attr, GXAttrType* type) { + u32 cpType; - switch (param_0) { - case 0: - local_38 = gx->vcdLo & 1; - break; - case 1: - local_38 = (gx->vcdLo & 2) >> 1; - break; - case 2: - local_38 = (gx->vcdLo & 4) >> 2; - break; - case 3: - local_38 = (gx->vcdLo & 8) >> 3; - break; - case 4: - local_38 = (gx->vcdLo & 0x10) >> 4; - break; - case 5: - local_38 = (gx->vcdLo & 0x20) >> 5; - break; - case 6: - local_38 = (gx->vcdLo & 0x40) >> 6; - break; - case 7: - local_38 = (gx->vcdLo & 0x80) >> 7; - break; - case 8: - local_38 = (gx->vcdLo & 0x100) >> 8; - break; - case 9: - local_38 = (gx->vcdLo & 0x600) >> 9; - break; - case 10: - if (gx->hasNrms != 0) { - local_38 = (gx->vcdLo & 0x1800) >> 11; - } else { - local_38 = 0; - } - break; - case 0x19: - if (gx->hasBiNrms != 0) { - local_38 = (gx->vcdLo & 0x1800) >> 11; - } else { - local_38 = 0; - } - break; - case 11: - local_38 = (gx->vcdLo & 0x6000) >> 13; - break; - case 12: - local_38 = (gx->vcdLo & 0x18000) >> 15; - break; - case 13: - local_38 = (gx->vcdHi & 3); - break; - case 14: - local_38 = (gx->vcdHi & 0xC) >> 2; - break; - case 15: - local_38 = (gx->vcdHi & 0x30) >> 4; - break; - case 16: - local_38 = (gx->vcdHi & 0xC0) >> 6; - break; - case 17: - local_38 = (gx->vcdHi & 0x300) >> 8; - break; - case 18: - local_38 = (gx->vcdHi & 0xC00) >> 10; - break; - case 19: - local_38 = (gx->vcdHi & 0x3000) >> 12; - break; - case 20: - local_38 = (gx->vcdHi & 0xC000) >> 14; - break; - default: - local_38 = 0; - break; + switch (attr) { + case GX_VA_PNMTXIDX: cpType = GET_REG_FIELD(gx->vcdLo, 1, 0); break; + case GX_VA_TEX0MTXIDX: cpType = GET_REG_FIELD(gx->vcdLo, 1, 1); break; + case GX_VA_TEX1MTXIDX: cpType = GET_REG_FIELD(gx->vcdLo, 1, 2); break; + case GX_VA_TEX2MTXIDX: cpType = GET_REG_FIELD(gx->vcdLo, 1, 3); break; + case GX_VA_TEX3MTXIDX: cpType = GET_REG_FIELD(gx->vcdLo, 1, 4); break; + case GX_VA_TEX4MTXIDX: cpType = GET_REG_FIELD(gx->vcdLo, 1, 5); break; + case GX_VA_TEX5MTXIDX: cpType = GET_REG_FIELD(gx->vcdLo, 1, 6); break; + case GX_VA_TEX6MTXIDX: cpType = GET_REG_FIELD(gx->vcdLo, 1, 7); break; + case GX_VA_TEX7MTXIDX: cpType = GET_REG_FIELD(gx->vcdLo, 1, 8); break; + case GX_VA_POS: cpType = GET_REG_FIELD(gx->vcdLo, 2, 9); break; + case GX_VA_NRM: cpType = gx->hasNrms ? GET_REG_FIELD(gx->vcdLo, 2, 11) : 0; break; + case GX_VA_NBT: cpType = gx->hasBiNrms ? GET_REG_FIELD(gx->vcdLo, 2, 11) : 0; break; + case GX_VA_CLR0: cpType = GET_REG_FIELD(gx->vcdLo, 2, 13); break; + case GX_VA_CLR1: cpType = GET_REG_FIELD(gx->vcdLo, 2, 15); break; + case GX_VA_TEX0: cpType = GET_REG_FIELD(gx->vcdHi, 2, 0); break; + case GX_VA_TEX1: cpType = GET_REG_FIELD(gx->vcdHi, 2, 2); break; + case GX_VA_TEX2: cpType = GET_REG_FIELD(gx->vcdHi, 2, 4); break; + case GX_VA_TEX3: cpType = GET_REG_FIELD(gx->vcdHi, 2, 6); break; + case GX_VA_TEX4: cpType = GET_REG_FIELD(gx->vcdHi, 2, 8); break; + case GX_VA_TEX5: cpType = GET_REG_FIELD(gx->vcdHi, 2, 10); break; + case GX_VA_TEX6: cpType = GET_REG_FIELD(gx->vcdHi, 2, 12); break; + case GX_VA_TEX7: cpType = GET_REG_FIELD(gx->vcdHi, 2, 14); break; + default: cpType = 0; break; } - - *param_1 = local_38; + *type = cpType; } -void GXGetVtxDescv(GXVtxDescList* attrPtr) { - int i; +void GXGetVtxDescv(GXVtxDescList* vcd) { + GXAttr attr; - for (i = 0; i <= 0x14; i++) { - attrPtr[i].attr = (GXAttr)i; - GXGetVtxDesc(i, &attrPtr[i].type); + for (attr = 0; attr < GX_VA_MAX_ATTR; attr++) { + vcd[attr].attr = attr; + GXGetVtxDesc(attr, &vcd[attr].type); } - - attrPtr[i].attr = (GXAttr)0x19; - GXGetVtxDesc(0x19, &attrPtr[i].type); - - i++; - attrPtr[i].attr = (GXAttr)0xFF; + vcd[attr].attr = 0xFF; } void GXClearVtxDesc(void) { @@ -329,13 +265,11 @@ static inline void SETVAT(u32* vatA, u32* vatB, u32* vatC, GXAttr attr, GXCompCn break; case GX_VA_CLR0: GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_CLRDIFF_CNT_ST, GX_CP_VAT_GRP0_CLRDIFF_CNT_END); - GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_CLRDIFF_TYPE_ST, - GX_CP_VAT_GRP0_CLRDIFF_TYPE_END); + GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_CLRDIFF_TYPE_ST, GX_CP_VAT_GRP0_CLRDIFF_TYPE_END); break; case GX_VA_CLR1: GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_CLRSPEC_CNT_ST, GX_CP_VAT_GRP0_CLRSPEC_CNT_END); - GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_CLRSPEC_TYPE_ST, - GX_CP_VAT_GRP0_CLRSPEC_TYPE_END); + GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_CLRSPEC_TYPE_ST, GX_CP_VAT_GRP0_CLRSPEC_TYPE_END); break; case GX_VA_TEX0: GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_TXC0_CNT_ST, GX_CP_VAT_GRP0_TXC0_CNT_END); @@ -409,343 +343,243 @@ void GXSetVtxAttrFmtv(GXVtxFmt format, GXVtxAttrFmtList* list) { } void __GXSetVAT(void) { - u32 i = 0; - u32 dirtyVAT = gx->dirtyVAT; - do { - if (dirtyVAT & (1)) { - GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP0 | i, gx->vatA[i]); - GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP1 | i, gx->vatB[i]); - GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP2 | i, gx->vatC[i]); - } - dirtyVAT >>= 1; - i++; - } while (dirtyVAT != 0); + u8 i; + for (i = 0; i < 8; i++) { + if (gx->dirtyVAT & (1 << (u8)i)) { + GX_WRITE_SOME_REG4(8, i | 0x70, gx->vatA[i], i - 12); + GX_WRITE_SOME_REG4(8, i | 0x80, gx->vatB[i], i - 12); + GX_WRITE_SOME_REG4(8, i | 0x90, gx->vatC[i], i - 12); + } + } gx->dirtyVAT = 0; } -static u8 GetFracForNrm(int param_0) { - int var_r31; +static inline u8 GetFracForNrm(GXCompType type) { + u8 frac; - switch (param_0) { - case 1: - var_r31 = 6; + switch (type) { + case GX_S8: + frac = 6; break; - case 3: - var_r31 = 14; + case GX_S16: + frac = 14; break; default: - case 2: - var_r31 = 0; + case GX_U16: + frac = 0; break; } - return var_r31; + return frac; } -void GXGetVtxAttrFmtv(GXVtxFmt param_0, GXVtxAttrFmtList* param_1) { - s32 tmp; - s32 tmp2; - s32 tmp3; - int i; +void GXGetVtxAttrFmt(GXVtxFmt fmt, int attr, GXCompCnt* cnt, GXCompType* type, u8* frac) { + u32 *va; + u32 *vb; + u32 *vc; -#ifdef DEBUG - // not fully matching - /* tmp = 1; - if (data_8074d3c8 != 0) { - OSPanic("GXAttr.c", 941, "\'GXGetVtxAttrFmtv\' is not allowed between GXBegin/GXEnd"); - tmp = 0; - } - - tmp2 = 1; - if (param_1 == NULL) { - OSPanic("GXAttr.c", 942, "GXSetVtxAttrFmt: list pointer is NULL"); - tmp2 = 0; - } - - tmp3 = 1; - if (param_0 >= 8) { - OSPanic("GXAttr.c", 943, "GXSetVtxAttrFmt: Format Index is out of range"); - tmp3 = 0; - } */ -#endif - - for (i = 9; i <= 0x14; i++) { - param_1->attr = i; - GXGetVtxAttrFmt(param_0, i, ¶m_1->cnt, ¶m_1->type, ¶m_1->frac); - param_1++; - } - - param_1->attr = 0xFF; -} - -void GXGetVtxAttrFmt(GXVtxFmt param_0, int param_1, GXCompCnt* param_2, GXCompType* param_3, - u8* param_4) { - s32 tmp; - s32 tmp2; - GXCompCnt* tmp_1; - GXCompCnt* tmp_2; - u32* tmp_3; - -#ifdef DEBUG - // not fully matching - /* tmp = 1; - if (data_8074d3c8) { - OSPanic("GXAttr.c", 844, "\'GXGetVtxAttrFmt\' is not allowed between GXBegin/GXEnd"); - tmp = 0; - } - - tmp2 = 1; - if (param_0 >= 8) { - OSPanic("GXAttr.c", 845, "GXSetVtxAttrFmt: Format Index is out of range"); - tmp2 = 0; - } */ -#endif - - tmp_1 = (GXCompCnt*)&gx->vatA[param_0]; - tmp_2 = (GXCompCnt*)&gx->vatB[param_0]; - tmp_3 = &gx->vatC[param_0]; - - switch (param_1) { - case 9: - *param_2 = *tmp_1 & 1; - *param_3 = (*tmp_1 & 0xE) >> 1; - *param_4 = (*tmp_1 & 0x1F0) >> 4; - break; - case 10: - case 0x19: - *param_2 = (*tmp_1 & 0x200) >> 9; - if (*param_2 == 1 && ((*tmp_1 & 0x80000000) >> 31) != 0) { - *param_2 = 2; + va = &gx->vatA[fmt]; + vb = &gx->vatB[fmt]; + vc = &gx->vatC[fmt]; + switch (attr) { + case GX_VA_POS: + *cnt = GET_REG_FIELD(*va, 1, 0); + *type = GET_REG_FIELD(*va, 3, 1); + *frac = GET_REG_FIELD(*va, 5, 4); + return; + case GX_VA_NRM: + case GX_VA_NBT: + *cnt = GET_REG_FIELD(*va, 1, 9); + if (*cnt == GX_TEX_ST && (u8)(*va >> 0x1F) != 0) { + *cnt = GX_NRM_NBT3; } - - *param_3 = (*tmp_1 & 0x1C00) >> 10; - *param_4 = GetFracForNrm(*param_3); - break; - case 11: - *param_2 = (*tmp_1 & 0x2000) >> 0xd; - *param_3 = (*tmp_1 & 0x1C000) >> 0xe; - *param_4 = 0; - break; - case 12: - *param_2 = (*tmp_1 & 0x20000) >> 0x11; - *param_3 = (*tmp_1 & 0x1C0000) >> 0x12; - *param_4 = 0; - break; - case 13: - *param_2 = (*tmp_1 & 0x200000) >> 0x15; - *param_3 = (*tmp_1 & 0x1C00000) >> 0x16; - *param_4 = ((*tmp_1 & 0x3e000000)) >> 25; - break; - case 14: - *param_2 = *tmp_2 & 1; - *param_3 = (*tmp_2 & 0xE) >> 1; - *param_4 = (*tmp_2 & 0x1F0) >> 4; - break; - case 15: - *param_2 = (*tmp_2 & 0x200) >> 9; - *param_3 = (*tmp_2 & 0x1C00) >> 10; - *param_4 = (*tmp_2 & 0x3E000) >> 13; - break; - case 16: - *param_2 = (*tmp_2 & 0x40000) >> 0x12; - *param_3 = (*tmp_2 & 0x380000) >> 0x13; - *param_4 = (*tmp_2 & 0x7C00000) >> 0x16; - break; - case 17: - *param_2 = (*tmp_2 & 0x8000000) >> 0x1B; - *param_3 = (*tmp_2 & 0x70000000) >> 0x1C; - *param_4 = (*tmp_3 & 0x1F); - break; - case 18: - *param_2 = (*tmp_3 & 0x20) >> 5; - *param_3 = (*tmp_3 & 0x1C0) >> 6; - *param_4 = (*tmp_3 & 0x3E00) >> 9; - break; - case 19: - *param_2 = (*tmp_3 & 0x4000) >> 0xe; - *param_3 = (*tmp_3 & 0x38000) >> 0xf; - *param_4 = (*tmp_3 & 0x7c0000) >> 0x12; - break; - case 20: - *param_2 = (*tmp_3 & 0x800000) >> 0x17; - *param_3 = (*tmp_3 & 0x7000000) >> 0x18; - *param_4 = (*tmp_3 & 0xF8000000) >> 0x1b; - break; + *type = GET_REG_FIELD(*va, 3, 10); + *frac = GetFracForNrm(*type); + return; + case GX_VA_CLR0: + *cnt = GET_REG_FIELD(*va, 1, 13); + *type = GET_REG_FIELD(*va, 3, 14); + *frac = 0; + return; + case GX_VA_CLR1: + *cnt = GET_REG_FIELD(*va, 1, 17); + *type = GET_REG_FIELD(*va, 3, 18); + *frac = 0; + return; + case GX_VA_TEX0: + *cnt = GET_REG_FIELD(*va, 1, 21); + *type = GET_REG_FIELD(*va, 3, 22); + *frac = (u8)(*va >> 0x19U) & 0x1F; + return; + case GX_VA_TEX1: + *cnt = GET_REG_FIELD(*vb, 1, 0); + *type = GET_REG_FIELD(*vb, 3, 1); + *frac = (u8)(*vb >> 4U) & 0x1F; + return; + case GX_VA_TEX2: + *cnt = GET_REG_FIELD(*vb, 1, 9); + *type = GET_REG_FIELD(*vb, 3, 10); + *frac = (u8)(*vb >> 0xDU) & 0x1F; + return; + case GX_VA_TEX3: + *cnt = GET_REG_FIELD(*vb, 1, 18); + *type = GET_REG_FIELD(*vb, 3, 19); + *frac = (u8)(*vb >> 0x16U) & 0x1F; + return; + case GX_VA_TEX4: + *cnt = GET_REG_FIELD(*vb, 1, 27); + *type = GET_REG_FIELD(*vb, 3, 28); + *frac = GET_REG_FIELD(*vc, 5, 0); + return; + case GX_VA_TEX5: + *cnt = GET_REG_FIELD(*vc, 1, 5); + *type = GET_REG_FIELD(*vc, 3, 6); + *frac = (u8)(*vc >> 9U) & 0x1F; + return; + case GX_VA_TEX6: + *cnt = GET_REG_FIELD(*vc, 1, 14); + *type = GET_REG_FIELD(*vc, 3, 15); + *frac = (u8)(*vc >> 0x12) & 0x1F; + return; + case GX_VA_TEX7: + *cnt = GET_REG_FIELD(*vc, 1, 23); + *type = GET_REG_FIELD(*vc, 3, 24); + *frac = (int)(*vc >> 0x1BU); + return; default: - *param_2 = 1; - *param_3 = 0; - *param_4 = 0; + *cnt = GX_TEX_ST; + *type = GX_RGB565; + *frac = 0; + return; } } -void GXSetArray(GXAttr attr, void* basePtr, u8 stride) { - s32 newAttr; - s32 attrReg; +void GXGetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* vat) { + GXAttr attr; - newAttr = attr; - if (newAttr == GX_VA_NBT) { - newAttr = GX_VA_NRM; + for (attr = GX_VA_POS; attr <= GX_VA_TEX7; attr++) { + vat->attr = attr; + GXGetVtxAttrFmt(fmt, attr, &vat->cnt, &vat->type, &vat->frac); + vat++; } + vat->attr = GX_VA_NULL; +} - attrReg = newAttr - GX_VA_POS; +void GXSetArray(GXAttr attr, void* base_ptr, u8 stride) { + GXAttr cpAttr; + u32 phyAddr; - GX_CP_LOAD_REG(GX_BP_REG_SETMODE0_TEX4 | attrReg, - // Address -> offset? - (u32)basePtr & ~0xC0000000); - - GX_CP_LOAD_REG(GX_BP_REG_SETIMAGE2_TEX4 | attrReg, stride); + if (attr == GX_VA_NBT) { + attr = GX_VA_NRM; + } + cpAttr = attr - GX_VA_POS; + phyAddr = (u32)base_ptr & 0x3FFFFFFF; + GX_WRITE_SOME_REG2(8, cpAttr | GX_BP_REG_SETMODE0_TEX4, phyAddr, cpAttr - 12); + GX_WRITE_SOME_REG3(8, cpAttr | GX_BP_REG_SETIMAGE2_TEX4, stride, cpAttr - 12); } void GXInvalidateVtxCache(void) { GXFIFO.u8 = GX_FIFO_CMD_INVAL_VTX; } -void GXSetTexCoordGen2(GXTexCoordID id, GXTexGenType type, GXTexGenSrc src, u32 texMtxIdx, - GXBool normalize, u32 dualTexMtxIdx) { - u32 reg; - u32 inputRow; - GXXfTexReg inputForm; +void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx, GXBool normalize, u32 pt_texmtx) { + u32 reg = 0; + u32 row; + u32 bumprow; // unused + u32 form; + GXAttr mtxIdAttr; - reg = 0; - inputForm = GX_XF_TEX_FORM_AB11; - inputRow = 5; - - switch (src) { - case GX_TG_POS: - inputRow = 0; - inputForm = GX_XF_TEX_FORM_ABC1; - break; - case GX_TG_NRM: - inputRow = 1; - inputForm = GX_XF_TEX_FORM_ABC1; - break; - case GX_TG_BINRM: - inputRow = 3; - inputForm = GX_XF_TEX_FORM_ABC1; - break; - case GX_TG_TANGENT: - inputRow = 4; - inputForm = GX_XF_TEX_FORM_ABC1; - break; - case GX_TG_COLOR0: - inputRow = 2; - break; - case GX_TG_COLOR1: - inputRow = 2; - break; - case GX_TG_TEX0: - inputRow = 5; - break; - case GX_TG_TEX1: - inputRow = 6; - break; - case GX_TG_TEX2: - inputRow = 7; - break; - case GX_TG_TEX3: - inputRow = 8; - break; - case GX_TG_TEX4: - inputRow = 9; - break; - case GX_TG_TEX5: - inputRow = 10; - break; - case GX_TG_TEX6: - inputRow = 11; - break; - case GX_TG_TEX7: - inputRow = 12; + form = 0; + row = 5; + switch (src_param) { + case GX_TG_POS: row = 0; form = 1; break; + case GX_TG_NRM: row = 1; form = 1; break; + case GX_TG_BINRM: row = 3; form = 1; break; + case GX_TG_TANGENT: row = 4; form = 1; break; + case GX_TG_COLOR0: row = 2; break; + case GX_TG_COLOR1: row = 2; break; + case GX_TG_TEX0: row = 5; break; + case GX_TG_TEX1: row = 6; break; + case GX_TG_TEX2: row = 7; break; + case GX_TG_TEX3: row = 8; break; + case GX_TG_TEX4: row = 9; break; + case GX_TG_TEX5: row = 10; break; + case GX_TG_TEX6: row = 11; break; + case GX_TG_TEX7: row = 12; break; + case GX_TG_TEXCOORD0: bumprow; break; + case GX_TG_TEXCOORD1: bumprow; break; + case GX_TG_TEXCOORD2: bumprow; break; + case GX_TG_TEXCOORD3: bumprow; break; + case GX_TG_TEXCOORD4: bumprow; break; + case GX_TG_TEXCOORD5: bumprow; break; + case GX_TG_TEXCOORD6: bumprow; break; + default: break; } - - switch (type) { - case GX_TG_NRM: - GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST, - GX_XF_TEX_PROJTYPE_END); // 2x4 projection - GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); - GX_SET_REG(reg, GX_TG_POS, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); - GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); + switch (func) + { + case GX_TG_MTX2x4: + SET_REG_FIELD(reg, 1, 1, 0); + SET_REG_FIELD(reg, 1, 2, form); + SET_REG_FIELD(reg, 3, 4, 0); + SET_REG_FIELD(reg, 5, 7, row); break; - case GX_TG_POS: - GX_SET_REG(reg, GX_XF_TEX_PROJ_STQ, GX_XF_TEX_PROJTYPE_ST, - GX_XF_TEX_PROJTYPE_END); // 3x4 projection - GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); - GX_SET_REG(reg, GX_TG_POS, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); - GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); + case GX_TG_MTX3x4: + SET_REG_FIELD(reg, 1, 1, 1); + SET_REG_FIELD(reg, 1, 2, form); + SET_REG_FIELD(reg, 3, 4, 0); + SET_REG_FIELD(reg, 5, 7, row); break; - case GX_TG_BUMP0: - case GX_TG_BUMP1: - case GX_TG_BUMP2: - case GX_TG_BUMP3: - case GX_TG_BUMP4: - case GX_TG_BUMP5: - case GX_TG_BUMP6: - case GX_TG_BUMP7: - GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST, - GX_XF_TEX_PROJTYPE_END); // 2x4 projection - GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); - GX_SET_REG(reg, GX_TG_NRM, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); - GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); - GX_SET_REG(reg, src - GX_TG_TEXCOORD0, GX_XF_TEX_BUMPSRCTEX_ST, GX_XF_TEX_BUMPSRCTEX_END); - GX_SET_REG(reg, type - GX_TG_BUMP0, GX_XF_TEX_BUMPSRCLIGHT_ST, GX_XF_TEX_BUMPSRCLIGHT_END); + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + SET_REG_FIELD(reg, 1, 1, 0); + SET_REG_FIELD(reg, 1, 2, form); + SET_REG_FIELD(reg, 3, 4, 1); + SET_REG_FIELD(reg, 5, 7, row); + SET_REG_FIELD(reg, 3, 12, src_param - 12); + SET_REG_FIELD(reg, 3, 15, func - 2); break; case GX_TG_SRTG: - GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST, - GX_XF_TEX_PROJTYPE_END); // 2x4 projection - GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); - - if (src == GX_TG_COLOR0) { - GX_SET_REG(reg, GX_XF_TG_CLR0, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); + SET_REG_FIELD(reg, 1, 1, 0); + SET_REG_FIELD(reg, 1, 2, form); + if (src_param == GX_TG_COLOR0) { + SET_REG_FIELD(reg, 3, 4, 2); } else { - GX_SET_REG(reg, GX_XF_TG_CLR1, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); + SET_REG_FIELD(reg, 3, 4, 3); } - GX_SET_REG(reg, 2, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); + SET_REG_FIELD(reg, 5, 7, 2); break; default: break; } - - GX_XF_LOAD_REG(GX_XF_REG_TEX0 + id, reg); - + GX_WRITE_XF_REG(dst_coord + 0x40, reg); reg = 0; - GX_SET_REG(reg, dualTexMtxIdx - 0x40, GX_XF_MTXIDX0_GEOM_ST, GX_XF_MTXIDX0_GEOM_END); - GX_SET_REG(reg, normalize, GX_XF_DUALTEX_NORMALISE_ST, GX_XF_DUALTEX_NORMALISE_END); - - GX_XF_LOAD_REG(GX_XF_REG_DUALTEX0 + id, reg); - - switch (id) { - case GX_TEXCOORD0: - GX_SET_REG(gx->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX0_ST, GX_XF_MTXIDX0_TEX0_END); - break; - case GX_TEXCOORD1: - GX_SET_REG(gx->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX1_ST, GX_XF_MTXIDX0_TEX1_END); - break; - case GX_TEXCOORD2: - GX_SET_REG(gx->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX2_ST, GX_XF_MTXIDX0_TEX2_END); - break; - case GX_TEXCOORD3: - GX_SET_REG(gx->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX3_ST, GX_XF_MTXIDX0_TEX3_END); - break; - case GX_TEXCOORD4: - GX_SET_REG(gx->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX4_ST, GX_XF_MTXIDX1_TEX4_END); - break; - case GX_TEXCOORD5: - GX_SET_REG(gx->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX5_ST, GX_XF_MTXIDX1_TEX5_END); - break; - case GX_TEXCOORD6: - GX_SET_REG(gx->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX6_ST, GX_XF_MTXIDX1_TEX6_END); - break; - default: - GX_SET_REG(gx->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX7_ST, GX_XF_MTXIDX1_TEX7_END); - break; + SET_REG_FIELD(reg, 6, 0, pt_texmtx - 64); + SET_REG_FIELD(reg, 1, 8, normalize); + GX_WRITE_XF_REG(dst_coord + 0x50, reg); + switch (dst_coord) { + case GX_TEXCOORD0: SET_REG_FIELD(gx->matIdxA, 6, 6, mtx); break; + case GX_TEXCOORD1: SET_REG_FIELD(gx->matIdxA, 6, 12, mtx); break; + case GX_TEXCOORD2: SET_REG_FIELD(gx->matIdxA, 6, 18, mtx); break; + case GX_TEXCOORD3: SET_REG_FIELD(gx->matIdxA, 6, 24, mtx); break; + case GX_TEXCOORD4: SET_REG_FIELD(gx->matIdxB, 6, 0, mtx); break; + case GX_TEXCOORD5: SET_REG_FIELD(gx->matIdxB, 6, 6, mtx); break; + case GX_TEXCOORD6: SET_REG_FIELD(gx->matIdxB, 6, 12, mtx); break; + default: SET_REG_FIELD(gx->matIdxB, 6, 18, mtx); break; } - __GXSetMatrixIndex(id + 1); + mtxIdAttr = dst_coord + 1; + __GXSetMatrixIndex(mtxIdAttr); } -void GXSetNumTexGens(u8 count) { - GX_SET_REG(gx->genMode, count, GX_BP_GENMODE_NUMTEX_ST, GX_BP_GENMODE_NUMTEX_END); - GX_XF_LOAD_REG(GX_XF_REG_NUMTEX, count); +void GXSetNumTexGens(u8 nTexGens) { + SET_REG_FIELD(gx->genMode, 4, 0, nTexGens); + GX_WRITE_XF_REG(0x3F, nTexGens); gx->dirtyState |= GX_DIRTY_GEN_MODE; }