//
// Generated by dtk
// Translation Unit: J3DMatBlock.cpp
//

#include "JSystem/J3DGraphBase/J3DMatBlock.h"
#include "JSystem/J3DGraphBase/J3DSys.h"
#include "JSystem/J3DGraphBase/J3DStruct.h"
#include "JSystem/J3DGraphBase/J3DTevs.h"
#include "JSystem/J3DGraphBase/J3DTexture.h"
#include "JSystem/J3DGraphBase/J3DTransform.h"
#include "dolphin/gd/GDBase.h"
#include "dolphin/os/OS.h"
#include "dolphin/types.h"
#include "MSL_C/string.h"

inline GXAttnFn J3DColorChan::getAttnFn() {
    u8 attnFnTbl[] = { GX_AF_NONE, GX_AF_SPEC, GX_AF_NONE, GX_AF_SPOT };
    return GXAttnFn(attnFnTbl[mChanCtrl >> 9 & 0x03]);
}

extern bool isTexNoReg(void*);
extern u16 getTexNoReg(void*);
extern void loadTexNo(u32, const u16 &);

extern void J3DGDSetTevColorS10(GXTevRegID, GXColorS10);
extern void J3DGDSetTevKColor(GXTevKColorID, GXColor);

int SizeOfLoadMatColors = 13;
int SizeOfLoadAmbColors = 13;
int SizeOfLoadColorChans = 21;

int SizeOfJ3DColorBlockLightOffLoad = SizeOfLoadMatColors + SizeOfLoadColorChans;
int SizeOfJ3DColorBlockAmbientOnLoad = SizeOfLoadMatColors + SizeOfLoadAmbColors + SizeOfLoadColorChans;

inline void loadMatColors(const J3DGXColor* color) {
    J3DGDWriteXFCmdHdr(0x100C, 2);
    J3DGDWrite_u32(*(u32*)color);
    J3DGDWrite_u32(*(u32*)(color + 1));
}

inline void loadAmbColors(const J3DGXColor* color) {
    J3DGDWriteXFCmdHdr(0x100A, 2);
    J3DGDWrite_u32(*(u32*)color);
    J3DGDWrite_u32(*(u32*)(color + 1));
}

inline void loadTexCoordScale(GXTexCoordID coord, const J3DTexCoordScaleInfo& info) {
    J3DGDSetTexCoordScale2(coord, info.field_0x00, info.field_0x04 == 1, 0, info.field_0x02, info.field_0x06 == 1, 0);
}

inline void loadTevColor(u32 reg, const J3DGXColorS10& color) {
    J3DGDSetTevColorS10(GXTevRegID(reg + 1), color.mColor);
}

inline void loadTevKColor(u32 reg, const J3DGXColor& color) {
    J3DGDSetTevKColor(GXTevKColorID(reg), color.mColor);
}

inline void loadZCompLoc(u8 compLoc) {
    J3DGDSetZCompLoc(compLoc);
}

/* 802DF794-802DF7E4       .text initialize__21J3DColorBlockLightOffFv */
void J3DColorBlockLightOff::initialize() {
    mColorChanNum = 0;
    for (u32 i = 0; i < ARRAY_SIZE(mMatColor); i++)
        mMatColor[i] = j3dDefaultColInfo;
    mMatColorOffset = 0;
    mColorChanOffset = 0;
}

/* 802DF7E4-802DF870       .text initialize__22J3DColorBlockAmbientOnFv */
void J3DColorBlockAmbientOn::initialize() {
    mColorChanNum = 0;
    for (u32 i = 0; i < ARRAY_SIZE(mMatColor); i++)
        mMatColor[i] = j3dDefaultColInfo;
    for (u32 i = 0; i < ARRAY_SIZE(mAmbColor); i++)
        mAmbColor[i] = j3dDefaultAmbInfo;
    mMatColorOffset = 0;
    mColorChanOffset = 0;
}

/* 802DF870-802DF91C       .text initialize__20J3DColorBlockLightOnFv */
void J3DColorBlockLightOn::initialize() {
    mColorChanNum = 0;
    for (u32 i = 0; i < ARRAY_SIZE(mMatColor); i++)
        mMatColor[i] = j3dDefaultColInfo;
    for (u32 i = 0; i < ARRAY_SIZE(mAmbColor); i++)
        mAmbColor[i] = j3dDefaultAmbInfo;
    for (u32 i = 0; i < ARRAY_SIZE(mLight); i++)
        mLight[i] = NULL;
    mMatColorOffset = 0;
    mColorChanOffset = 0;
}

/* 802DF91C-802DF94C       .text initialize__21J3DTexGenBlockPatchedFv */
void J3DTexGenBlockPatched::initialize() {
    mTexGenNum = 0;
    for (u32 i = 0; i < 8; i++)
        mTexMtx[i] = NULL;
    mTexMtxOffset = 0;
}

/* 802DF94C-802DF97C       .text initialize__15J3DTexGenBlock4Fv */
void J3DTexGenBlock4::initialize() {
    mTexGenNum = 0;
    for (u32 i = 0; i < 4; i++)
        mTexMtx[i] = NULL;
    mTexMtxOffset = 0;
}

/* 802DF97C-802DF9AC       .text initialize__19J3DTexGenBlockBasicFv */
void J3DTexGenBlockBasic::initialize() {
    mTexGenNum = 0;
    for (u32 i = 0; i < 8; i++)
        mTexMtx[i] = NULL;
    mTexMtxOffset = 0;
}

/* 802DF9AC-802DF9B8       .text initialize__15J3DTevBlockNullFv */
void J3DTevBlockNull::initialize() {
    mTexNoOffset = 0;
}

/* 802DF9B8-802DFABC       .text initialize__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::initialize() {
    for (u32 i = 0; i < ARRAY_SIZE(mTexNo); i++)
        mTexNo[i] = 0xFFFF;
    for (u32 i = 0; i < ARRAY_SIZE(mTevStage); i++) {
        mTevStage[i].field_0x0 = 0xC0 + i * 2;
        mTevStage[i].field_0x4 = 0xC1 + i * 2;
    }
    for (u32 i = 0; i < 3; i++)
        mTevColor[i] = j3dDefaultTevColor;
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        mTevKColor[i] = j3dDefaultTevKColor;
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColorSel); i++)
        mTevKColorSel[i] = GX_TEV_KCSEL_K0;
    mTevStageNum = 1;
    mTexNoOffset = 0;
    mTevRegOffset = 0;
}

/* 802DFABC-802DFAE4       .text initialize__12J3DTevBlock1Fv */
void J3DTevBlock1::initialize() {
    mTexNo[0] = 0xFFFF;
    mTevStage[0].field_0x0 = 0xC0;
    mTevStage[0].field_0x4 = 0xC1;
    mTexNoOffset = 0;
}

/* 802DFAE4-802DFBBC       .text initialize__12J3DTevBlock2Fv */
void J3DTevBlock2::initialize() {
    mTexNo[0] = 0xFFFF;
    mTexNo[1] = 0xFFFF;
    mTevStageNum = 1;

    mTevStage[0].field_0x0 = 0xC0;
    mTevStage[0].field_0x4 = 0xC1;
    mTevStage[1].field_0x0 = 0xC2;
    mTevStage[1].field_0x4 = 0xC3;
    mTevKColorSel[0] = GX_TEV_KCSEL_K0;
    mTevKColorSel[1] = GX_TEV_KCSEL_K0;
    mTevKAlphaSel[0] = GX_TEV_KASEL_K0_A;
    mTevKAlphaSel[1] = GX_TEV_KASEL_K0_A;

    for (u32 i = 0; i < 3; i++)
        mTevColor[i] = j3dDefaultTevColor;
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        mTevKColor[i] = j3dDefaultTevKColor;
    mTexNoOffset = 0;
    mTevRegOffset = 0;
}

/* 802DFBBC-802DFCCC       .text initialize__12J3DTevBlock4Fv */
void J3DTevBlock4::initialize() {
    mTexNo[0] = 0xFFFF;
    mTexNo[1] = 0xFFFF;
    mTexNo[2] = 0xFFFF;
    mTexNo[3] = 0xFFFF;
    mTevStageNum = 1;

    mTevStage[0].field_0x0 = 0xC0;
    mTevStage[0].field_0x4 = 0xC1;
    mTevStage[1].field_0x0 = 0xC2;
    mTevStage[1].field_0x4 = 0xC3;
    mTevStage[2].field_0x0 = 0xC4;
    mTevStage[2].field_0x4 = 0xC5;
    mTevStage[3].field_0x0 = 0xC6;
    mTevStage[3].field_0x4 = 0xC7;
    mTevKColorSel[0] = GX_TEV_KCSEL_K0;
    mTevKColorSel[1] = GX_TEV_KCSEL_K0;
    mTevKColorSel[2] = GX_TEV_KCSEL_K0;
    mTevKColorSel[3] = GX_TEV_KCSEL_K0;
    mTevKAlphaSel[0] = GX_TEV_KASEL_K0_A;
    mTevKAlphaSel[1] = GX_TEV_KASEL_K0_A;
    mTevKAlphaSel[2] = GX_TEV_KASEL_K0_A;
    mTevKAlphaSel[3] = GX_TEV_KASEL_K0_A;

    for (u32 i = 0; i < 3; i++)
        mTevColor[i] = j3dDefaultTevColor;
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        mTevKColor[i] = j3dDefaultTevKColor;
    mTexNoOffset = 0;
    mTevRegOffset = 0;
}

/* 802DFCCC-802DFDF0       .text initialize__13J3DTevBlock16Fv */
void J3DTevBlock16::initialize() {
    for (u32 i = 0; i < ARRAY_SIZE(mTexNo); i++)
        mTexNo[i] = 0xFFFF;
    mTevStageNum = 1;
    for (u32 i = 0; i < 3; i++)
        mTevColor[i] = j3dDefaultTevColor;
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        mTevKColor[i] = j3dDefaultTevKColor;
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColorSel); i++)
        mTevKColorSel[i] = GX_TEV_KCSEL_K0;
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColorSel); i++)
        mTevKAlphaSel[i] = GX_TEV_KASEL_K0_A;
    for (u32 i = 0; i < ARRAY_SIZE(mTevStage); i++) {
        mTevStage[i].field_0x0 = 0xC0 + i * 2;
        mTevStage[i].field_0x4 = 0xC1 + i * 2;
    }
    mTexNoOffset = 0;
    mTevRegOffset = 0;
}

/* 802DFDF0-802DFDFC       .text initialize__15J3DIndBlockFullFv */
void J3DIndBlockFull::initialize() {
    mIndTexStageNum = 0;
}

/* 802DFDFC-802DFE20       .text initialize__16J3DPEBlockFogOffFv */
void J3DPEBlockFogOff::initialize() {
    mAlphaComp.mAlphaCmpID = 0xFFFF;
    mZMode.mZModeID = 0xFFFF;
    mZCompLoc = 0xFF;
    mDither = 1;
}

/* 802DFE20-802DFE50       .text initialize__14J3DPEBlockFullFv */
void J3DPEBlockFull::initialize() {
    mFog = NULL;
    mAlphaComp.mAlphaCmpID = 0xFFFF;
    mZMode.mZModeID = 0xFFFF;
    mZCompLoc = 0xFF;
    mDither = 1;
    mFogOffset = 0;
}

/* 802DFE50-802DFE58       .text countDLSize__21J3DColorBlockLightOffFv */
s32 J3DColorBlockLightOff::countDLSize() {
    return 0x22;
}

/* 802DFE58-802DFE60       .text countDLSize__22J3DColorBlockAmbientOnFv */
s32 J3DColorBlockAmbientOn::countDLSize() {
    return 0x2f;
}

/* 802DFE60-802DFE68       .text countDLSize__20J3DColorBlockLightOnFv */
s32 J3DColorBlockLightOn::countDLSize() {
    return 0x26f;
}

/* 802DFE68-802DFE70       .text countDLSize__21J3DTexGenBlockPatchedFv */
s32 J3DTexGenBlockPatched::countDLSize() {
    return 0x1a8;
}

/* 802DFE70-802DFE78       .text countDLSize__15J3DTexGenBlock4Fv */
s32 J3DTexGenBlock4::countDLSize() {
    return 0xfe;
}

/* 802DFE78-802DFE80       .text countDLSize__19J3DTexGenBlockBasicFv */
s32 J3DTexGenBlockBasic::countDLSize() {
    return 0x1f2;
}

/* 802DFE80-802DFE88       .text countDLSize__18J3DTevBlockPatchedFv */
s32 J3DTevBlockPatched::countDLSize() {
    return 0x230;
}

/* 802DFE88-802DFE90       .text countDLSize__12J3DTevBlock1Fv */
s32 J3DTevBlock1::countDLSize() {
    return 0x69;
}

/* 802DFE90-802DFE98       .text countDLSize__12J3DTevBlock2Fv */
s32 J3DTevBlock2::countDLSize() {
    return 0x14f;
}

/* 802DFE98-802DFEA0       .text countDLSize__12J3DTevBlock4Fv */
s32 J3DTevBlock4::countDLSize() {
    return 0x244;
}

/* 802DFEA0-802DFEA8       .text countDLSize__13J3DTevBlock16Fv */
s32 J3DTevBlock16::countDLSize() {
    return 0x3e8;
}

/* 802DFEA8-802DFEB0       .text countDLSize__15J3DIndBlockFullFv */
s32 J3DIndBlockFull::countDLSize() {
    return 0x8c;
}

/* 802DFEB0-802DFEB8       .text countDLSize__13J3DPEBlockOpaFv */
s32 J3DPEBlockOpa::countDLSize() {
    return 0x1e;
}

/* 802DFEB8-802DFEC0       .text countDLSize__17J3DPEBlockTexEdgeFv */
s32 J3DPEBlockTexEdge::countDLSize() {
    return 0x1e;
}

/* 802DFEC0-802DFEC8       .text countDLSize__13J3DPEBlockXluFv */
s32 J3DPEBlockXlu::countDLSize() {
    return 0x1e;
}

/* 802DFEC8-802DFED0       .text countDLSize__16J3DPEBlockFogOffFv */
s32 J3DPEBlockFogOff::countDLSize() {
    return 0x1e;
}

/* 802DFED0-802DFED8       .text countDLSize__14J3DPEBlockFullFv */
s32 J3DPEBlockFull::countDLSize() {
    return 0x55;
}

/* 802DFED8-802E0438       .text load__21J3DColorBlockLightOffFv */
void J3DColorBlockLightOff::load() {
    GDOverflowCheck(SizeOfJ3DColorBlockLightOffLoad);
    mMatColorOffset = GDGetCurrOffset();
    loadMatColors(mMatColor);
    mColorChanOffset = GDGetCurrOffset();
    J3DGDWriteXFCmdHdr(0x100E, 4);
    mColorChan[0].load();
    mColorChan[2].load();
    mColorChan[1].load();
    mColorChan[3].load();
    /* Nonmatching */
}

/* 802E0438-802E0AC0       .text load__22J3DColorBlockAmbientOnFv */
void J3DColorBlockAmbientOn::load() {
    GDOverflowCheck(SizeOfJ3DColorBlockAmbientOnLoad);
    mMatColorOffset = GDGetCurrOffset();
    loadMatColors(mMatColor);
    loadAmbColors(mAmbColor);
    mColorChanOffset = GDGetCurrOffset();
    J3DGDWriteXFCmdHdr(0x100E, 4);
    mColorChan[0].load();
    mColorChan[2].load();
    mColorChan[1].load();
    mColorChan[3].load();
    /* Nonmatching */
}

/* 802E0AC0-802E1180       .text load__20J3DColorBlockLightOnFv */
void J3DColorBlockLightOn::load() {
    GDOverflowCheck(SizeOfJ3DColorBlockAmbientOnLoad);
    mMatColorOffset = GDGetCurrOffset();
    loadMatColors(mMatColor);
    loadAmbColors(mAmbColor);
    mColorChanOffset = GDGetCurrOffset();
    J3DGDWriteXFCmdHdr(0x100E, 4);
    mColorChan[0].load();
    mColorChan[2].load();
    mColorChan[1].load();
    mColorChan[3].load();
    for (u32 i = 0; i < 8; i++) {
        if (mLight[i]) {
            mLight[i]->load(i);
        }
    }
    /* Nonmatching */
}

/* 802E1180-802E11CC       .text patch__21J3DColorBlockLightOffFv */
void J3DColorBlockLightOff::patch() {
    patchMatColor();
    patchLight();
}

/* 802E11CC-802E1378       .text patchMatColor__21J3DColorBlockLightOffFv */
void J3DColorBlockLightOff::patchMatColor() {
    GDSetCurrOffset(mMatColorOffset);
    u8* start = GDGetCurrPointer();
    GDOverflowCheck(SizeOfLoadMatColors);
    loadMatColors(mMatColor);
    u8* end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E1378-802E17B4       .text patchLight__21J3DColorBlockLightOffFv */
void J3DColorBlockLightOff::patchLight() {
    GDSetCurrOffset(mColorChanOffset);
    u8* start = GDGetCurrPointer();
    GDOverflowCheck(SizeOfLoadColorChans);
    J3DGDWriteXFCmdHdr(0x100E, 4);
    mColorChan[0].load();
    mColorChan[2].load();
    mColorChan[1].load();
    mColorChan[3].load();
    u8* end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
    /* Nonmatching */
}

/* 802E17B4-802E1800       .text patch__20J3DColorBlockLightOnFv */
void J3DColorBlockLightOn::patch() {
    patchMatColor();
    patchLight();
}

/* 802E1800-802E19AC       .text patchMatColor__20J3DColorBlockLightOnFv */
void J3DColorBlockLightOn::patchMatColor() {
    GDSetCurrOffset(mMatColorOffset);
    u8* start = GDGetCurrPointer();
    GDOverflowCheck(SizeOfLoadMatColors);
    loadMatColors(mMatColor);
    u8* end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E19AC-802E1E18       .text patchLight__20J3DColorBlockLightOnFv */
void J3DColorBlockLightOn::patchLight() {
    /* Nonmatching */
    GDSetCurrOffset(mColorChanOffset);
    u8* start = GDGetCurrPointer();
    GDOverflowCheck(SizeOfLoadColorChans);
    J3DGDWriteXFCmdHdr(0x100E, 4);
    mColorChan[0].load();
    mColorChan[2].load();
    mColorChan[1].load();
    mColorChan[3].load();
    for (u32 i = 0; i < 8; i++) {
        if (mLight[i]) {
            mLight[i]->load(i);
        }
    }
    u8* end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
    /* Nonmatching */
}

/* 802E1E18-802E1E80       .text diff__21J3DColorBlockLightOffFUl */
void J3DColorBlockLightOff::diff(u32 flag) {
    if ((flag & 0x1) != 0)
        diffMatColor();
    if ((flag & 0x2) != 0)
        diffLight();
}

/* 802E1E80-802E1FFC       .text diffMatColor__21J3DColorBlockLightOffFv */
void J3DColorBlockLightOff::diffMatColor() {
    GDOverflowCheck(SizeOfLoadMatColors);
    loadMatColors(mMatColor);
}

/* 802E1FFC-802E2408       .text diffLight__21J3DColorBlockLightOffFv */
void J3DColorBlockLightOff::diffLight() {
    GDOverflowCheck(SizeOfLoadColorChans);
    J3DGDWriteXFCmdHdr(0x100E, 4);
    mColorChan[0].load();
    mColorChan[2].load();
    mColorChan[1].load();
    mColorChan[3].load();
    /* Nonmatching */
}

/* 802E2408-802E2478       .text diff__20J3DColorBlockLightOnFUl */
void J3DColorBlockLightOn::diff(u32 flag) {
    if ((flag & 0x1))
        diffMatColor();
    if ((flag & 0x2) || (flag >> 4) & 0x0f)
        diffLight();
}

/* 802E2478-802E25F4       .text diffMatColor__20J3DColorBlockLightOnFv */
void J3DColorBlockLightOn::diffMatColor() {
    GDOverflowCheck(SizeOfLoadMatColors);
    loadMatColors(mMatColor);
}

/* 802E25F4-802E2A38       .text diffLight__20J3DColorBlockLightOnFv */
void J3DColorBlockLightOn::diffLight() {
    GDOverflowCheck(SizeOfLoadColorChans);
    J3DGDWriteXFCmdHdr(0x100E, 4);
    mColorChan[0].load();
    mColorChan[2].load();
    mColorChan[1].load();
    mColorChan[3].load();
    for (u32 i = 0; i < ARRAY_SIZE(mLight); i++)
        if (mLight[i] != NULL)
            mLight[i]->load(i);
}

/* 802E2A38-802E2ACC       .text load__15J3DTexGenBlock4Fv */
void J3DTexGenBlock4::load() {
    mTexMtxOffset = GDGetCurrOffset();
    for (u32 i = 0; i < 4; i++) {
        if (mTexMtx[i] && mTexCoord[i].getTexGenMtx() != GX_IDENTITY) {
            mTexMtx[i]->load(i);
        }
    }
    if (mTexGenNum != 0) {
        loadTexCoordGens(mTexGenNum, mTexCoord);
    }
}

/* 802E2ACC-802E2B60       .text load__19J3DTexGenBlockBasicFv */
void J3DTexGenBlockBasic::load() {
    mTexMtxOffset = GDGetCurrOffset();
    for (u32 i = 0; i < 8; i++) {
        if (mTexMtx[i] && mTexCoord[i].getTexGenMtx() != GX_IDENTITY) {
            mTexMtx[i]->load(i);
        }
    }
    if (mTexGenNum != 0) {
        loadTexCoordGens(mTexGenNum, mTexCoord);
    }
}

/* 802E2B60-802E2BF0       .text patch__21J3DTexGenBlockPatchedFv */
void J3DTexGenBlockPatched::patch() {
    GDSetCurrOffset(mTexMtxOffset);
    u8* start = GDGetCurrPointer();
    for (u32 i = 0; i < 8; i++) {
        if (mTexMtx[i]) {
            mTexMtx[i]->load(i);
        }
    }
    u8* end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E2BF0-802E2C8C       .text patch__15J3DTexGenBlock4Fv */
void J3DTexGenBlock4::patch() {
    GDSetCurrOffset(mTexMtxOffset);
    u8* start = GDGetCurrPointer();
    for (u32 i = 0; i < 4; i++) {
        if (mTexMtx[i] && mTexCoord[i].getTexGenMtx() != GX_IDENTITY) {
            mTexMtx[i]->load(i);
        }
    }
    u8* end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E2C8C-802E2D28       .text patch__19J3DTexGenBlockBasicFv */
void J3DTexGenBlockBasic::patch() {
    GDSetCurrOffset(mTexMtxOffset);
    u8* start = GDGetCurrPointer();
    for (u32 i = 0; i < 8; i++) {
        if (mTexMtx[i] && mTexCoord[i].getTexGenMtx() != GX_IDENTITY) {
            mTexMtx[i]->load(i);
        }
    }
    u8* end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E2D28-802E2D90       .text diff__21J3DTexGenBlockPatchedFUl */
void J3DTexGenBlockPatched::diff(u32 flag) {
    if ((flag >> 8) & 0x0f) {
        diffTexMtx();
        if (flag & 0x1000)
            diffTexGen();
    }
}

/* 802E2D90-802E2DF0       .text diffTexMtx__21J3DTexGenBlockPatchedFv */
void J3DTexGenBlockPatched::diffTexMtx() {
    for (u32 i = 0; i < ARRAY_SIZE(mTexMtx); ++i) {
        if (mTexMtx[i] != NULL) {
            mTexMtx[i]->load(i);
        }
    }
}

/* 802E2DF0-802E2ED0       .text diffTexGen__21J3DTexGenBlockPatchedFv */
void J3DTexGenBlockPatched::diffTexGen() {
    u32 num = mTexGenNum;
    if (num > 0) {
        J3DGDWriteXFCmdHdr(0x1040, num);
    }
    for (u32 i = 0; i < num; ++i) {
        J3DGDSetTexCoordGen((GXTexGenType)mTexCoord[i].mTexGenType,
                            (GXTexGenSrc)mTexCoord[i].mTexGenSrc);
    }
}

/* 802E2ED0-802E3110       .text load__12J3DTevBlock1Fv */
void J3DTevBlock1::load() {
    mTexNoOffset = GDGetCurrOffset();
    GDOverflowCheck(0x69);
    if (mTexNo[0] != 0xffff) {
        loadTexNo(0, mTexNo[0]);
    }
    J3DGDSetTevOrder(
        GX_TEVSTAGE0,
        GXTexCoordID(mTevOrder[0].getTevOrderInfo().mTexCoord),
        GXTexMapID(mTevOrder[0].getTevOrderInfo().mTexMap),
        GXChannelID(mTevOrder[0].getTevOrderInfo().mColorChan),
        GX_TEXCOORD_NULL,
        GX_TEXMAP_NULL,
        GX_COLOR_NULL
    );
    loadTexCoordScale(
        GXTexCoordID(mTevOrder[0].getTevOrderInfo().mTexCoord),
        J3DSys::sTexCoordScaleTable[mTevOrder[0].getTevOrderInfo().mTexMap & 7]
    );
    mTevStage[0].load(0);
    mIndTevStage[0].load(0);
}

/* 802E3110-802E362C       .text load__12J3DTevBlock2Fv */
void J3DTevBlock2::load() {
    u8 tevStageNum = mTevStageNum;
    mTexNoOffset = GDGetCurrOffset();
    for (u32 i = 0; i < 2; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }
    J3DGDSetTevOrder(
        GX_TEVSTAGE0,
        GXTexCoordID(mTevOrder[0].getTevOrderInfo().mTexCoord),
        GXTexMapID(mTevOrder[0].getTevOrderInfo().mTexMap),
        GXChannelID(mTevOrder[0].getTevOrderInfo().mColorChan),
        GXTexCoordID(mTevOrder[1].getTevOrderInfo().mTexCoord),
        GXTexMapID(mTevOrder[1].getTevOrderInfo().mTexMap),
        GXChannelID(mTevOrder[1].getTevOrderInfo().mColorChan)
    );
    loadTexCoordScale(
        GXTexCoordID(mTevOrder[0].getTevOrderInfo().mTexCoord),
        J3DSys::sTexCoordScaleTable[mTevOrder[0].getTevOrderInfo().mTexMap & 7]
    );
    loadTexCoordScale(
        GXTexCoordID(mTevOrder[1].getTevOrderInfo().mTexCoord & 7),
        J3DSys::sTexCoordScaleTable[mTevOrder[1].getTevOrderInfo().mTexMap & 7]
    );
    mTevRegOffset = GDGetCurrOffset();
    for (u32 i = 0; i < 3; i++) {
        loadTevColor(i, mTevColor[i]);
    }
    for (u32 i = 0; i < 4; i++) {
        loadTevKColor(i, mTevKColor[i]);
    }
    for (u32 i = 0; i < tevStageNum; i++) {
        mTevStage[i].load(i);
        mIndTevStage[i].load(i);
    }
    for (u32 i = 0; i < 16; i += 4) {
        J3DGDSetTevKonstantSel_SwapModeTable(
            GXTevStageID(i),
            GXTevKColorSel(mTevKColorSel[0]),
            GXTevKAlphaSel(mTevKAlphaSel[0]),
            GXTevKColorSel(mTevKColorSel[1]),
            GXTevKAlphaSel(mTevKAlphaSel[1]),
            GXTevColorChan(mTevSwapModeTable[i / 4].getR()),
            GXTevColorChan(mTevSwapModeTable[i / 4].getG())
        );
        J3DGDSetTevKonstantSel_SwapModeTable(
            GXTevStageID(i + 2),
            GXTevKColorSel(mTevKColorSel[0]),
            GXTevKAlphaSel(mTevKAlphaSel[0]),
            GXTevKColorSel(mTevKColorSel[1]),
            GXTevKAlphaSel(mTevKAlphaSel[1]),
            GXTevColorChan(mTevSwapModeTable[i / 4].getB()),
            GXTevColorChan(mTevSwapModeTable[i / 4].getA())
        );
    }
}

/* 802E362C-802E3B70       .text load__12J3DTevBlock4Fv */
void J3DTevBlock4::load() {
    u8 tevStageNum = mTevStageNum;
    mTexNoOffset = GDGetCurrOffset();
    for (u32 i = 0; i < 4; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }
    for (u32 i = 0; i < tevStageNum; i += 2) {
        J3DGDSetTevOrder(
            GXTevStageID(i),
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord),
            GXTexMapID(mTevOrder[i].getTevOrderInfo().mTexMap),
            GXChannelID(mTevOrder[i].getTevOrderInfo().mColorChan),
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord),
            GXTexMapID(mTevOrder[i + 1].getTevOrderInfo().mTexMap),
            GXChannelID(mTevOrder[i + 1].getTevOrderInfo().mColorChan)
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i].getTevOrderInfo().mTexMap & 7]
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i + 1].getTevOrderInfo().mTexMap & 7]
        );
    }
    mTevRegOffset = GDGetCurrOffset();
    for (u32 i = 0; i < 3; i++) {
        loadTevColor(i, mTevColor[i]);
    }
    for (u32 i = 0; i < 4; i++) {
        loadTevKColor(i, mTevKColor[i]);
    }
    for (u32 i = 0; i < tevStageNum; i++) {
        mTevStage[i].load(i);
        mIndTevStage[i].load(i);
    }
    for (u32 i = 0; i < 16; i += 4) {
        J3DGDSetTevKonstantSel_SwapModeTable(
            GXTevStageID(i),
            GXTevKColorSel(mTevKColorSel[0]),
            GXTevKAlphaSel(mTevKAlphaSel[0]),
            GXTevKColorSel(mTevKColorSel[1]),
            GXTevKAlphaSel(mTevKAlphaSel[1]),
            GXTevColorChan(mTevSwapModeTable[i / 4].getR()),
            GXTevColorChan(mTevSwapModeTable[i / 4].getG())
        );
        J3DGDSetTevKonstantSel_SwapModeTable(
            GXTevStageID(i + 2),
            GXTevKColorSel(mTevKColorSel[2]),
            GXTevKAlphaSel(mTevKAlphaSel[2]),
            GXTevKColorSel(mTevKColorSel[3]),
            GXTevKAlphaSel(mTevKAlphaSel[3]),
            GXTevColorChan(mTevSwapModeTable[i / 4].getB()),
            GXTevColorChan(mTevSwapModeTable[i / 4].getA())
        );
    }
}

/* 802E3B70-802E40B8       .text load__13J3DTevBlock16Fv */
void J3DTevBlock16::load() {
    u8 tevStageNum = mTevStageNum;
    mTexNoOffset = GDGetCurrOffset();
    for (u32 i = 0; i < 8; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }
    for (u32 i = 0; i < tevStageNum; i += 2) {
        J3DGDSetTevOrder(
            GXTevStageID(i),
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord),
            GXTexMapID(mTevOrder[i].getTevOrderInfo().mTexMap),
            GXChannelID(mTevOrder[i].getTevOrderInfo().mColorChan),
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord),
            GXTexMapID(mTevOrder[i + 1].getTevOrderInfo().mTexMap),
            GXChannelID(mTevOrder[i + 1].getTevOrderInfo().mColorChan)
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i].getTevOrderInfo().mTexMap & 7]
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i + 1].getTevOrderInfo().mTexMap & 7]
        );
    }
    mTevRegOffset = GDGetCurrOffset();
    for (u32 i = 0; i < 3; i++) {
        loadTevColor(i, mTevColor[i]);
    }
    for (u32 i = 0; i < 4; i++) {
        loadTevKColor(i, mTevKColor[i]);
    }
    for (u32 i = 0; i < tevStageNum; i++) {
        mTevStage[i].load(i);
        mIndTevStage[i].load(i);
    }
    for (u32 i = 0; i < 16; i += 4) {
        J3DGDSetTevKonstantSel_SwapModeTable(
            GXTevStageID(i),
            GXTevKColorSel(mTevKColorSel[i]),
            GXTevKAlphaSel(mTevKAlphaSel[i]),
            GXTevKColorSel(mTevKColorSel[i + 1]),
            GXTevKAlphaSel(mTevKAlphaSel[i + 1]),
            GXTevColorChan(mTevSwapModeTable[i / 4].getR()),
            GXTevColorChan(mTevSwapModeTable[i / 4].getG())
        );
        J3DGDSetTevKonstantSel_SwapModeTable(
            GXTevStageID(i + 2),
            GXTevKColorSel(mTevKColorSel[i + 2]),
            GXTevKAlphaSel(mTevKAlphaSel[i + 2]),
            GXTevKColorSel(mTevKColorSel[i + 3]),
            GXTevKAlphaSel(mTevKAlphaSel[i + 3]),
            GXTevColorChan(mTevSwapModeTable[i / 4].getB()),
            GXTevColorChan(mTevSwapModeTable[i / 4].getA())
        );
    }
}

/* 802E40B8-802E414C       .text patchTexNo__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::patchTexNo() {
    GDSetCurrOffset(mTexNoOffset);
    u8* start = GDGetCurrPointer();

    for (u32 i = 0; i < 8; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }

    u8* end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E414C-802E4218       .text patchTevReg__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::patchTevReg() {
    GDSetCurrOffset(mTevRegOffset);
    u8 *pStart = GDGetCurrPointer();

    for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++)
        J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i].mColor);
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i].mColor);

    u8 *pEnd = GDGetCurrPointer();
    DCFlushRange(pStart, pEnd - pStart);
}

/* 802E4218-802E4394       .text patchTexNoAndTexCoordScale__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::patchTexNoAndTexCoordScale() {
    GDSetCurrOffset(mTexNoOffset);
    u8 *start = GDGetCurrPointer();

    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < 8; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }

    for (u32 i = 0; i < tevStageNum; i += 2) {
        J3DGDSetTevOrder(
            GXTevStageID(i),
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord),
            GXTexMapID(mTevOrder[i].getTevOrderInfo().mTexMap),
            GXChannelID(mTevOrder[i].getTevOrderInfo().mColorChan),
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord),
            GXTexMapID(mTevOrder[i + 1].getTevOrderInfo().mTexMap),
            GXChannelID(mTevOrder[i + 1].getTevOrderInfo().mColorChan)
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i].getTevOrderInfo().mTexMap & 7]
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i + 1].getTevOrderInfo().mTexMap & 7]
        );
    }

    u8 *end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E4394-802E43E0       .text patch__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::patch() {
    patchTexNo();
    patchTevReg();
}

/* 802E43E0-802E4450       .text patchTexNo__12J3DTevBlock1Fv */
void J3DTevBlock1::patchTexNo() {
    GDSetCurrOffset(mTexNoOffset);
    u8 *pStart = GDGetCurrPointer();

    if (mTexNo[0] != 0xFFFF)
        loadTexNo(0, mTexNo[0]);

    u8 *pEnd = GDGetCurrPointer();
    DCFlushRange(pStart, pEnd - pStart);
}

/* 802E4450-802E4454       .text patchTevReg__12J3DTevBlock1Fv */
void J3DTevBlock1::patchTevReg() {
}

/* 802E4454-802E4538       .text patchTexNoAndTexCoordScale__12J3DTevBlock1Fv */
void J3DTevBlock1::patchTexNoAndTexCoordScale() {
    GDSetCurrOffset(mTexNoOffset);
    u8 *start = GDGetCurrPointer();

    if (mTexNo[0] != 0xffff) {
        loadTexNo(0, mTexNo[0]);
    }

    J3DGDSetTevOrder(
        GX_TEVSTAGE0,
        GXTexCoordID(mTevOrder[0].getTevOrderInfo().mTexCoord),
        GXTexMapID(mTevOrder[0].getTevOrderInfo().mTexMap),
        GXChannelID(mTevOrder[0].getTevOrderInfo().mColorChan),
        GX_TEXCOORD_NULL,
        GX_TEXMAP_NULL,
        GX_COLOR_NULL
    );
    loadTexCoordScale(
        GXTexCoordID(mTevOrder[0].getTevOrderInfo().mTexCoord),
        J3DSys::sTexCoordScaleTable[mTevOrder[0].getTevOrderInfo().mTexMap & 7]
    );

    u8 *end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E4538-802E4564       .text patch__12J3DTevBlock1Fv */
void J3DTevBlock1::patch() {
    patchTexNo();
}

/* 802E4564-802E45F8       .text patchTexNo__12J3DTevBlock2Fv */
void J3DTevBlock2::patchTexNo() {
    GDSetCurrOffset(mTexNoOffset);
    u8 *start = GDGetCurrPointer();

    for (u32 i = 0; i < 2; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }

    u8 *end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E45F8-802E46C4       .text patchTevReg__12J3DTevBlock2Fv */
void J3DTevBlock2::patchTevReg() {
    GDSetCurrOffset(mTevRegOffset);
    u8 *pStart = GDGetCurrPointer();

    for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++)
        J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i].mColor);
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i].mColor);

    u8 *pEnd = GDGetCurrPointer();
    DCFlushRange(pStart, pEnd - pStart);
}

/* 802E46C4-802E4814       .text patchTexNoAndTexCoordScale__12J3DTevBlock2Fv */
void J3DTevBlock2::patchTexNoAndTexCoordScale() {
    GDSetCurrOffset(mTexNoOffset);
    u8 *start = GDGetCurrPointer();

    for (u32 i = 0; i < 2; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }

    J3DGDSetTevOrder(
        GX_TEVSTAGE0,
        GXTexCoordID(mTevOrder[0].getTevOrderInfo().mTexCoord),
        GXTexMapID(mTevOrder[0].getTevOrderInfo().mTexMap),
        GXChannelID(mTevOrder[0].getTevOrderInfo().mColorChan),
        GXTexCoordID(mTevOrder[1].getTevOrderInfo().mTexCoord),
        GXTexMapID(mTevOrder[1].getTevOrderInfo().mTexMap),
        GXChannelID(mTevOrder[1].getTevOrderInfo().mColorChan)
    );
    loadTexCoordScale(
        GXTexCoordID(mTevOrder[0].getTevOrderInfo().mTexCoord),
        J3DSys::sTexCoordScaleTable[mTevOrder[0].getTevOrderInfo().mTexMap & 7]
    );
    loadTexCoordScale(
        GXTexCoordID(mTevOrder[1].getTevOrderInfo().mTexCoord & 7),
        J3DSys::sTexCoordScaleTable[mTevOrder[1].getTevOrderInfo().mTexMap & 7]
    );

    u8 *end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E4814-802E4860       .text patch__12J3DTevBlock2Fv */
void J3DTevBlock2::patch() {
    patchTexNo();
    patchTevReg();
}

/* 802E4860-802E48F4       .text patchTexNo__12J3DTevBlock4Fv */
void J3DTevBlock4::patchTexNo() {
    GDSetCurrOffset(mTexNoOffset);
    u8 *start = GDGetCurrPointer();

    for (u32 i = 0; i < 4; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }

    u8 *end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E48F4-802E49C0       .text patchTevReg__12J3DTevBlock4Fv */
void J3DTevBlock4::patchTevReg() {
    GDSetCurrOffset(mTevRegOffset);
    u8 *pStart = GDGetCurrPointer();

    for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++)
        J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i].mColor);
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i].mColor);

    u8 *pEnd = GDGetCurrPointer();
    DCFlushRange(pStart, pEnd - pStart);
}

/* 802E49C0-802E4B3C       .text patchTexNoAndTexCoordScale__12J3DTevBlock4Fv */
void J3DTevBlock4::patchTexNoAndTexCoordScale() {
    GDSetCurrOffset(mTexNoOffset);
    u8 *start = GDGetCurrPointer();

    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < 8; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }

    for (u32 i = 0; i < tevStageNum; i += 2) {
        J3DGDSetTevOrder(
            GXTevStageID(i),
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord),
            GXTexMapID(mTevOrder[i].getTevOrderInfo().mTexMap),
            GXChannelID(mTevOrder[i].getTevOrderInfo().mColorChan),
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord),
            GXTexMapID(mTevOrder[i + 1].getTevOrderInfo().mTexMap),
            GXChannelID(mTevOrder[i + 1].getTevOrderInfo().mColorChan)
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i].getTevOrderInfo().mTexMap & 7]
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i + 1].getTevOrderInfo().mTexMap & 7]
        );
    }

    u8 *end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E4B3C-802E4B88       .text patch__12J3DTevBlock4Fv */
void J3DTevBlock4::patch() {
    patchTexNo();
    patchTevReg();
}

/* 802E4B88-802E4C1C       .text patchTexNo__13J3DTevBlock16Fv */
void J3DTevBlock16::patchTexNo() {
    GDSetCurrOffset(mTexNoOffset);
    u8 *start = GDGetCurrPointer();

    for (u32 i = 0; i < 8; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }

    u8 *end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E4C1C-802E4CE8       .text patchTevReg__13J3DTevBlock16Fv */
void J3DTevBlock16::patchTevReg() {
    GDSetCurrOffset(mTevRegOffset);
    u8 *pStart = GDGetCurrPointer();

    for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++)
        J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i].mColor);
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i].mColor);

    u8 *pEnd = GDGetCurrPointer();
    DCFlushRange(pStart, pEnd - pStart);
}

/* 802E4CE8-802E4E64       .text patchTexNoAndTexCoordScale__13J3DTevBlock16Fv */
void J3DTevBlock16::patchTexNoAndTexCoordScale() {
    GDSetCurrOffset(mTexNoOffset);
    u8 *start = GDGetCurrPointer();

    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < 8; i++) {
        if (mTexNo[i] != 0xffff) {
            loadTexNo(i, mTexNo[i]);
        }
    }

    for (u32 i = 0; i < tevStageNum; i += 2) {
        J3DGDSetTevOrder(
            GXTevStageID(i),
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord),
            GXTexMapID(mTevOrder[i].getTevOrderInfo().mTexMap),
            GXChannelID(mTevOrder[i].getTevOrderInfo().mColorChan),
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord),
            GXTexMapID(mTevOrder[i + 1].getTevOrderInfo().mTexMap),
            GXChannelID(mTevOrder[i + 1].getTevOrderInfo().mColorChan)
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i].getTevOrderInfo().mTexMap & 7]
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i + 1].getTevOrderInfo().mTexMap & 7]
        );
    }

    u8 *end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
}

/* 802E4E64-802E4EB0       .text patch__13J3DTevBlock16Fv */
void J3DTevBlock16::patch() {
    patchTexNo();
    patchTevReg();
}

/* 802E4EB0-802E4F6C       .text diff__11J3DTevBlockFUl */
void J3DTevBlock::diff(u32 flag) {
    if ((flag >> 16) & 0x0f)
        diffTexNo();
    if (flag & 0x4000000)
        diffTexCoordScale();
    if ((flag >> 20) & 0x0f) {
        diffTevStage();
        if (flag & 0x8000000)
            diffTevStageIndirect();
    }
    if (flag & 0x01000000)
        diffTevReg();
}

/* 802E4F6C-802E4FD0       .text diffTexNo__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::diffTexNo() {
    for (u32 i = 0; i < ARRAY_SIZE(mTexNo); i++)
        if (mTexNo[i] != 0xFFFF)
            loadTexNo(i, mTexNo[i]);
}

/* 802E4FD0-802E50E4       .text diffTevStage__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::diffTevStage() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i++) {
        mTevStage[i].load(i);
    }
}

/* 802E50E4-802E5194       .text diffTevStageIndirect__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::diffTevStageIndirect() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i++) {
        mIndTevStage[i].load(i);
    }
}

/* 802E5194-802E5230       .text diffTevReg__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::diffTevReg() {
    for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++)
        J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i].mColor);
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i].mColor);
}

/* 802E5230-802E5328       .text diffTexCoordScale__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::diffTexCoordScale() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i += 2) {
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i].getTevOrderInfo().mTexMap & 7]
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i + 1].getTevOrderInfo().mTexMap & 7]
        );
    }
}

/* 802E5328-802E5360       .text diffTexNo__12J3DTevBlock1Fv */
void J3DTevBlock1::diffTexNo() {
    if (mTexNo[0] != 0xFFFF)
        loadTexNo(0, mTexNo[0]);
}

/* 802E5360-802E5364       .text diffTevReg__12J3DTevBlock1Fv */
void J3DTevBlock1::diffTevReg() {
}

/* 802E5364-802E5454       .text diffTevStage__12J3DTevBlock1Fv */
void J3DTevBlock1::diffTevStage() {
    mTevStage[0].load(0);
}

/* 802E5454-802E54D4       .text diffTevStageIndirect__12J3DTevBlock1Fv */
void J3DTevBlock1::diffTevStageIndirect() {
    mIndTevStage[0].load(0);
}

/* 802E54D4-802E553C       .text diffTexCoordScale__12J3DTevBlock1Fv */
void J3DTevBlock1::diffTexCoordScale() {
    loadTexCoordScale(
        GXTexCoordID(mTevOrder[0].getTevOrderInfo().mTexCoord),
        J3DSys::sTexCoordScaleTable[mTevOrder[0].getTevOrderInfo().mTexMap & 7]
    );
}

/* 802E553C-802E55A0       .text diffTexNo__12J3DTevBlock2Fv */
void J3DTevBlock2::diffTexNo() {
    for (u32 i = 0; i < ARRAY_SIZE(mTexNo); i++)
        if (mTexNo[i] != 0xFFFF)
            loadTexNo(i, mTexNo[i]);
}

/* 802E55A0-802E563C       .text diffTevReg__12J3DTevBlock2Fv */
void J3DTevBlock2::diffTevReg() {
    for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++)
        J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i].mColor);
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i].mColor);
}

/* 802E563C-802E5750       .text diffTevStage__12J3DTevBlock2Fv */
void J3DTevBlock2::diffTevStage() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i++) {
        mTevStage[i].load(i);
    }
}

/* 802E5750-802E5800       .text diffTevStageIndirect__12J3DTevBlock2Fv */
void J3DTevBlock2::diffTevStageIndirect() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i++) {
        mIndTevStage[i].load(i);
    }
}

/* 802E5800-802E58C4       .text diffTexCoordScale__12J3DTevBlock2Fv */
void J3DTevBlock2::diffTexCoordScale() {
    loadTexCoordScale(
        GXTexCoordID(mTevOrder[0].getTevOrderInfo().mTexCoord),
        J3DSys::sTexCoordScaleTable[mTevOrder[0].getTevOrderInfo().mTexMap & 7]
    );
    loadTexCoordScale(
        GXTexCoordID(mTevOrder[1].getTevOrderInfo().mTexCoord & 7),
        J3DSys::sTexCoordScaleTable[mTevOrder[1].getTevOrderInfo().mTexMap & 7]
    );
}

/* 802E58C4-802E5928       .text diffTexNo__12J3DTevBlock4Fv */
void J3DTevBlock4::diffTexNo() {
    for (u32 i = 0; i < ARRAY_SIZE(mTexNo); i++)
        if (mTexNo[i] != 0xFFFF)
            loadTexNo(i, mTexNo[i]);
}

/* 802E5928-802E59C4       .text diffTevReg__12J3DTevBlock4Fv */
void J3DTevBlock4::diffTevReg() {
    for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++)
        J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i].mColor);
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i].mColor);
}

/* 802E59C4-802E5AD8       .text diffTevStage__12J3DTevBlock4Fv */
void J3DTevBlock4::diffTevStage() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i++) {
        mTevStage[i].load(i);
    }
}

/* 802E5AD8-802E5B88       .text diffTevStageIndirect__12J3DTevBlock4Fv */
void J3DTevBlock4::diffTevStageIndirect() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i++) {
        mIndTevStage[i].load(i);
    }
}

/* 802E5B88-802E5C80       .text diffTexCoordScale__12J3DTevBlock4Fv */
void J3DTevBlock4::diffTexCoordScale() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i += 2) {
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i].getTevOrderInfo().mTexMap & 7]
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i + 1].getTevOrderInfo().mTexMap & 7]
        );
    }
}

/* 802E5C80-802E5CE4       .text diffTexNo__13J3DTevBlock16Fv */
void J3DTevBlock16::diffTexNo() {
    for (u32 i = 0; i < ARRAY_SIZE(mTexNo); i++)
        if (mTexNo[i] != 0xFFFF)
            loadTexNo(i, mTexNo[i]);
}

/* 802E5CE4-802E5D80       .text diffTevReg__13J3DTevBlock16Fv */
void J3DTevBlock16::diffTevReg() {
    for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++)
        J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i].mColor);
    for (u32 i = 0; i < ARRAY_SIZE(mTevKColor); i++)
        J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i].mColor);
}

/* 802E5D80-802E5E94       .text diffTevStage__13J3DTevBlock16Fv */
void J3DTevBlock16::diffTevStage() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i++) {
        mTevStage[i].load(i);
    }
}

/* 802E5E94-802E5F44       .text diffTevStageIndirect__13J3DTevBlock16Fv */
void J3DTevBlock16::diffTevStageIndirect() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i++) {
        mIndTevStage[i].load(i);
    }
}

/* 802E5F44-802E603C       .text diffTexCoordScale__13J3DTevBlock16Fv */
void J3DTevBlock16::diffTexCoordScale() {
    u8 tevStageNum = mTevStageNum;
    for (u32 i = 0; i < tevStageNum; i += 2) {
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i].getTevOrderInfo().mTexMap & 7]
        );
        loadTexCoordScale(
            GXTexCoordID(mTevOrder[i + 1].getTevOrderInfo().mTexCoord & 7),
            J3DSys::sTexCoordScaleTable[mTevOrder[i + 1].getTevOrderInfo().mTexMap & 7]
        );
    }
}

extern void patchTexNo_PtrToIdx(u32 texID, const u16& idx);

/* 802E603C-802E6120       .text ptrToIndex__13J3DTevBlock16Fv */
void J3DTevBlock16::ptrToIndex() {
    GDSetCurrOffset(mTexNoOffset);
    u8* pStart = GDGetCurrPointer();

    u32 offs = 0;
    for (u32 i = 0; i < 8; i++) {
        if (mTexNo[i] != 0xFFFF) {
            GDSetCurrOffset(mTexNoOffset + offs);
            patchTexNo_PtrToIdx(i, mTexNo[i]);
            offs += 0x14;
            if (j3dSys.getTexture()->getResTIMG(mTexNo[i])->indexTexture == 1)
                offs += 0x23;
        }
    }

    u8 *pEnd = GDGetCurrPointer();
    DCFlushRange(pStart, pEnd - pStart);
}

/* 802E6120-802E6204       .text ptrToIndex__18J3DTevBlockPatchedFv */
void J3DTevBlockPatched::ptrToIndex() {
    GDSetCurrOffset(mTexNoOffset);
    u8* pStart = GDGetCurrPointer();

    u32 offs = 0;
    for (u32 i = 0; i < 8; i++) {
        if (mTexNo[i] != 0xFFFF) {
            GDSetCurrOffset(mTexNoOffset + offs);
            patchTexNo_PtrToIdx(i, mTexNo[i]);
            offs += 0x14;
            if (j3dSys.getTexture()->getResTIMG(mTexNo[i])->indexTexture == 1)
                offs += 0x23;
        }
    }

    u8 *pEnd = GDGetCurrPointer();
    DCFlushRange(pStart, pEnd - pStart);
}

/* 802E6204-802E6298       .text indexToPtr_private__11J3DTevBlockFUl */
void J3DTevBlock::indexToPtr_private(u32 offs) {
    GDSetCurrOffset(offs);
    u8* pStart = GDGetCurrPointer();

    for (u32 i = 0; ; i++) {
        u8* pDL = GDGetCurrPointer();
        if (!isTexNoReg(pDL))
            break;

        u16 texNoReg = getTexNoReg(pDL);
        loadTexNo(i, texNoReg);
    }

    u8 *pEnd = GDGetCurrPointer();
    DCFlushRange(pStart, pEnd - pStart);
}

/* 802E6298-802E6494       .text load__15J3DIndBlockFullFv */
void J3DIndBlockFull::load() {
    /* Nonmatching */
    u8 indTexStageNum = mIndTexStageNum;
    for (u32 i = 0; i < indTexStageNum; i++) {
        mIndTexMtx[i].load(i);
    }
    for (u32 i = 0; i < indTexStageNum; i += 2) {
        J3DGDSetIndTexCoordScale(
            GXIndTexStageID(i),
            GXIndTexScale(mIndTexCoordScale[i].getScaleS()),
            GXIndTexScale(mIndTexCoordScale[i].getScaleT()),
            GXIndTexScale(mIndTexCoordScale[i + 1].getScaleS()),
            GXIndTexScale(mIndTexCoordScale[i + 1].getScaleT())
        );
    }
    loadTexCoordScale(GXTexCoordID(mIndTexOrder[0].getCoord()), J3DSys::sTexCoordScaleTable[mIndTexOrder[0].getMap() & 7]);
    loadTexCoordScale(GXTexCoordID(mIndTexOrder[1].getCoord()), J3DSys::sTexCoordScaleTable[mIndTexOrder[1].getMap() & 7]);
    loadTexCoordScale(GXTexCoordID(mIndTexOrder[2].getCoord()), J3DSys::sTexCoordScaleTable[mIndTexOrder[2].getMap() & 7]);
    loadTexCoordScale(GXTexCoordID(mIndTexOrder[3].getCoord()), J3DSys::sTexCoordScaleTable[mIndTexOrder[3].getMap() & 7]);
    J3DGDSetIndTexOrder(
        indTexStageNum,
        GXTexCoordID(mIndTexOrder[0].getCoord()),
        GXTexMapID(mIndTexOrder[0].getMap()),
        GXTexCoordID(mIndTexOrder[1].getCoord()),
        GXTexMapID(mIndTexOrder[1].getMap()),
        GXTexCoordID(mIndTexOrder[2].getCoord()),
        GXTexMapID(mIndTexOrder[2].getMap()),
        GXTexCoordID(mIndTexOrder[3].getCoord()),
        GXTexMapID(mIndTexOrder[3].getMap())
    );
}

/* 802E6494-802E657C       .text diff__15J3DIndBlockFullFUl */
void J3DIndBlockFull::diff(u32 flag) {
    /* Nonmatching */
    if ((flag & 0x08000000) == 0) {
        return;
    }
    u8 indTexStageNum = mIndTexStageNum;
    J3DGDSetIndTexStageNum(indTexStageNum);
    mIndTexMtx[0].load(0);
    J3DGDSetIndTexCoordScale(
        GXIndTexStageID(0),
        GXIndTexScale(mIndTexCoordScale[0].getScaleS()),
        GXIndTexScale(mIndTexCoordScale[0].getScaleT()),
        GXIndTexScale(mIndTexCoordScale[1].getScaleS()),
        GXIndTexScale(mIndTexCoordScale[1].getScaleT())
    );
    loadTexCoordScale(GXTexCoordID(mIndTexOrder[0].getCoord()), J3DSys::sTexCoordScaleTable[mIndTexOrder[0].getMap() & 7]);
    J3DGDSetIndTexOrder(
        indTexStageNum,
        GXTexCoordID(mIndTexOrder[0].getCoord()),
        GXTexMapID(mIndTexOrder[0].getMap()),
        GXTexCoordID(mIndTexOrder[1].getCoord()),
        GXTexMapID(mIndTexOrder[1].getMap()),
        GXTexCoordID(mIndTexOrder[2].getCoord()),
        GXTexMapID(mIndTexOrder[2].getMap()),
        GXTexCoordID(mIndTexOrder[3].getCoord()),
        GXTexMapID(mIndTexOrder[3].getMap())
    );
}

/* 802E657C-802E683C       .text load__13J3DPEBlockOpaFv */
void J3DPEBlockOpa::load() {
    GDOverflowCheck(0x1e);
    J3DGDSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
    J3DGDSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_COPY);
    J3DGDSetZMode(1, GX_LEQUAL, 1);
    J3DGDSetZCompLoc(1);
}

/* 802E683C-802E6B04       .text load__17J3DPEBlockTexEdgeFv */
void J3DPEBlockTexEdge::load() {
    GDOverflowCheck(0x1e);
    J3DGDSetAlphaCompare(GX_GEQUAL, 0x80, GX_AOP_AND, GX_LEQUAL, 0xff);
    J3DGDSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_COPY);
    J3DGDSetZMode(1, GX_LEQUAL, 1);
    J3DGDSetZCompLoc(0);
}

/* 802E6B04-802E6DC8       .text load__13J3DPEBlockXluFv */
void J3DPEBlockXlu::load() {
    GDOverflowCheck(0x1e);
    J3DGDSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND,GX_ALWAYS, 0);
    J3DGDSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_COPY);
    J3DGDSetZMode(1, GX_LEQUAL, 0);
    J3DGDSetZCompLoc(1);
}

/* 802E6DC8-802E7250       .text load__16J3DPEBlockFogOffFv */
void J3DPEBlockFogOff::load() {
    GDOverflowCheck(0x1e);
    mAlphaComp.load();
    mBlend.load(mDither);
    mZMode.load();
    loadZCompLoc(mZCompLoc);
    /* Nonmatching */
}

/* 802E7250-802E7538       .text diffBlend__16J3DPEBlockFogOffFv */
void J3DPEBlockFogOff::diffBlend() {
    GDOverflowCheck(0xf);
    mBlend.load(mDither);
    mZMode.load();
    /* Nonmatching */
}

/* 802E7538-802E7A1C       .text load__14J3DPEBlockFullFv */
void J3DPEBlockFull::load() {
    mFogOffset = GDGetCurrOffset();
    GDOverflowCheck(0x55);
    if (mFog) {
        mFog->load();
    }
    mAlphaComp.load();
    mBlend.load(mDither);
    mZMode.load();
    loadZCompLoc(mZCompLoc);
    /* Nonmatching */
}

/* 802E7A1C-802E7AD8       .text patch__14J3DPEBlockFullFv */
void J3DPEBlockFull::patch() {
    GDSetCurrOffset(mFogOffset);
    GDOverflowCheck(0x37);
    u8* start = GDGetCurrPointer();
    if (mFog) {
        mFog->load();
    }
    u8* end = GDGetCurrPointer();
    DCFlushRange(start, end - start);
    /* Nonmatching */
}

/* 802E7AD8-802E7B5C       .text diffFog__14J3DPEBlockFullFv */
void J3DPEBlockFull::diffFog() {
    GDOverflowCheck(0x37);
    if (mFog) {
        mFog->load();
    }
}

/* 802E7B5C-802E7E44       .text diffBlend__14J3DPEBlockFullFv */
void J3DPEBlockFull::diffBlend() {
    GDOverflowCheck(0xf);
    mBlend.load(mDither);
    mZMode.load();
    /* Nonmatching */
}

/* 802E7E44-802E7EAC       .text diff__14J3DPEBlockFullFUl */
void J3DPEBlockFull::diff(u32 flag) {
    if ((flag & 0x10000000))
        diffFog();
    if ((flag & 0x20000000))
        diffBlend();
}

/* 802E7EAC-802E7F88       .text reset__21J3DColorBlockLightOffFP13J3DColorBlock */
void J3DColorBlockLightOff::reset(J3DColorBlock* pBlock) {
    mColorChanNum = pBlock->getColorChanNum();

    for (u32 i = 0; i < ARRAY_SIZE(mMatColor); i++)
        mMatColor[i] = *pBlock->getMatColor(i);
    for (u32 i = 0; i < ARRAY_SIZE(mColorChan); i++)
        mColorChan[i] = *pBlock->getColorChan(i);
}

/* 802E7F88-802E80D8       .text reset__22J3DColorBlockAmbientOnFP13J3DColorBlock */
void J3DColorBlockAmbientOn::reset(J3DColorBlock* pBlock) {
    mColorChanNum = pBlock->getColorChanNum();

    for (u32 i = 0; i < ARRAY_SIZE(mMatColor); i++)
        mMatColor[i] = *pBlock->getMatColor(i);
    for (u32 i = 0; i < ARRAY_SIZE(mColorChan); i++)
        mColorChan[i] = *pBlock->getColorChan(i);
    for (u32 i = 0; i < ARRAY_SIZE(mAmbColor); i++)
        if (pBlock->getAmbColor(i) != NULL)
            mAmbColor[i] = *pBlock->getAmbColor(i);
}

/* 802E80D8-802E8228       .text reset__20J3DColorBlockLightOnFP13J3DColorBlock */
void J3DColorBlockLightOn::reset(J3DColorBlock* pBlock) {
    mColorChanNum = pBlock->getColorChanNum();

    for (u32 i = 0; i < ARRAY_SIZE(mMatColor); i++)
        mMatColor[i] = *pBlock->getMatColor(i);
    for (u32 i = 0; i < ARRAY_SIZE(mColorChan); i++)
        mColorChan[i] = *pBlock->getColorChan(i);
    for (u32 i = 0; i < ARRAY_SIZE(mAmbColor); i++)
        if (pBlock->getAmbColor(i) != NULL)
            mAmbColor[i] = *pBlock->getAmbColor(i);
}

/* 802E8228-802E8354       .text reset__21J3DTexGenBlockPatchedFP14J3DTexGenBlock */
void J3DTexGenBlockPatched::reset(J3DTexGenBlock* pBlock) {
    mTexGenNum = pBlock->getTexGenNum();
    for (u32 i = 0; i < 8; i++)
        mTexCoord[i] = *pBlock->getTexCoord(i);
    for (u32 i = 0; i < 8; i++) {
        if (pBlock->getTexMtx(i) != NULL) {
            if (mTexMtx[i] != NULL) {
                memcpy(mTexMtx[i], pBlock->getTexMtx(i), sizeof(*mTexMtx[i]));
                DCStoreRange(mTexMtx[i], sizeof(*mTexMtx[i]));
            } else {
                OSReport("Error : TexMtx[%d] is Null.\n", i);
            }
        }
    }
}

/* 802E8354-802E84B4       .text reset__15J3DTexGenBlock4FP14J3DTexGenBlock */
void J3DTexGenBlock4::reset(J3DTexGenBlock* pBlock) {
    mTexGenNum = pBlock->getTexGenNum();
    for (u32 i = 0; i < 4; i++)
        mTexCoord[i] = *pBlock->getTexCoord(i);
    for (u32 i = 0; i < 4; i++) {
        if (pBlock->getTexMtx(i) != NULL) {
            if (mTexMtx[i] != NULL) {
                memcpy(mTexMtx[i], pBlock->getTexMtx(i), sizeof(*mTexMtx[i]));
                DCStoreRange(mTexMtx[i], sizeof(*mTexMtx[i]));
            } else {
                OSReport("Error : TexMtx[%d] is Null.\n", i);
            }
        }
    }

    mNBTScale = *pBlock->getNBTScale();
}

/* 802E84B4-802E8614       .text reset__19J3DTexGenBlockBasicFP14J3DTexGenBlock */
void J3DTexGenBlockBasic::reset(J3DTexGenBlock* pBlock) {
    mTexGenNum = pBlock->getTexGenNum();
    for (u32 i = 0; i < 8; i++)
        mTexCoord[i] = *pBlock->getTexCoord(i);
    for (u32 i = 0; i < 8; i++) {
        if (pBlock->getTexMtx(i) != NULL) {
            if (mTexMtx[i] != NULL) {
                memcpy(mTexMtx[i], pBlock->getTexMtx(i), sizeof(*mTexMtx[i]));
                DCStoreRange(mTexMtx[i], sizeof(*mTexMtx[i]));
            } else {
                OSReport("Error : TexMtx[%d] is Null.\n", i);
            }
        }
    }

    mNBTScale = *pBlock->getNBTScale();
}

/* 802E8614-802E87D0       .text reset__18J3DTevBlockPatchedFP11J3DTevBlock */
void J3DTevBlockPatched::reset(J3DTevBlock* pBlock) {
    mTevStageNum = pBlock->getTevStageNum();
    for (u32 i = 0; i < 8; i++)
        mTexNo[i] = pBlock->getTexNo(i);
    for (u32 i = 0; i < 4; i++)
        mTevColor[i] = *pBlock->getTevColor(i);
    for (u32 i = 0; i < 4; i++)
        mTevKColor[i] = *pBlock->getTevKColor(i);
    for (u32 i = 0; i < 8; i++) {
        mTevStage[i] = *pBlock->getTevStage(i);
        mIndTevStage[i] = *pBlock->getIndTevStage(i);
    }
}

/* 802E87D0-802E88B8       .text reset__12J3DTevBlock1FP11J3DTevBlock */
void J3DTevBlock1::reset(J3DTevBlock* pBlock) {
    mTexNo[0] = pBlock->getTexNo(0);
    mTevOrder[0] = *pBlock->getTevOrder(0);
    mTevStage[0] = *pBlock->getTevStage(0);
    mIndTevStage[0] = *pBlock->getIndTevStage(0);
}

/* 802E88B8-802E8BB8       .text reset__12J3DTevBlock2FP11J3DTevBlock */
void J3DTevBlock2::reset(J3DTevBlock* pBlock) {
    mTevStageNum = pBlock->getTevStageNum();
    mTexNo[0] = pBlock->getTexNo(0);
    mTexNo[1] = pBlock->getTexNo(1);
    mTevStage[0] = *pBlock->getTevStage(0);
    mTevStage[1] = *pBlock->getTevStage(1);
    mIndTevStage[0] = *pBlock->getIndTevStage(0);
    mIndTevStage[1] = *pBlock->getIndTevStage(1);
    mTevOrder[0] = *pBlock->getTevOrder(0);
    mTevOrder[1] = *pBlock->getTevOrder(1);
    mTevKColorSel[0] = pBlock->getTevKColorSel(0);
    mTevKColorSel[1] = pBlock->getTevKColorSel(1);
    mTevKAlphaSel[0] = pBlock->getTevKAlphaSel(0);
    mTevKAlphaSel[1] = pBlock->getTevKAlphaSel(1);
    for (u32 i = 0; i < 4; i++)
        mTevColor[i] = *pBlock->getTevColor(i);
    for (u32 i = 0; i < 4; i++)
        mTevKColor[i] = *pBlock->getTevKColor(i);
    for (u32 i = 0; i < 4; i++)
        mTevSwapModeTable[i] = *pBlock->getTevSwapModeTable(i);
}

/* 802E8BB8-802E9090       .text reset__12J3DTevBlock4FP11J3DTevBlock */
void J3DTevBlock4::reset(J3DTevBlock* pBlock) {
    mTevStageNum = pBlock->getTevStageNum();
    mTexNo[0] = pBlock->getTexNo(0);
    mTexNo[1] = pBlock->getTexNo(1);
    mTexNo[2] = pBlock->getTexNo(2);
    mTexNo[3] = pBlock->getTexNo(3);
    mTevStage[0] = *pBlock->getTevStage(0);
    mTevStage[1] = *pBlock->getTevStage(1);
    mTevStage[2] = *pBlock->getTevStage(2);
    mTevStage[3] = *pBlock->getTevStage(3);
    mIndTevStage[0] = *pBlock->getIndTevStage(0);
    mIndTevStage[1] = *pBlock->getIndTevStage(1);
    mIndTevStage[2] = *pBlock->getIndTevStage(2);
    mIndTevStage[3] = *pBlock->getIndTevStage(3);
    mTevOrder[0] = *pBlock->getTevOrder(0);
    mTevOrder[1] = *pBlock->getTevOrder(1);
    mTevOrder[2] = *pBlock->getTevOrder(2);
    mTevOrder[3] = *pBlock->getTevOrder(3);
    mTevKColorSel[0] = pBlock->getTevKColorSel(0);
    mTevKColorSel[1] = pBlock->getTevKColorSel(1);
    mTevKColorSel[2] = pBlock->getTevKColorSel(2);
    mTevKColorSel[3] = pBlock->getTevKColorSel(3);
    mTevKAlphaSel[0] = pBlock->getTevKAlphaSel(0);
    mTevKAlphaSel[1] = pBlock->getTevKAlphaSel(1);
    mTevKAlphaSel[2] = pBlock->getTevKAlphaSel(2);
    mTevKAlphaSel[3] = pBlock->getTevKAlphaSel(3);
    for (u32 i = 0; i < 4; i++)
        mTevColor[i] = *pBlock->getTevColor(i);
    for (u32 i = 0; i < 4; i++)
        mTevKColor[i] = *pBlock->getTevKColor(i);
    for (u32 i = 0; i < 4; i++)
        mTevSwapModeTable[i] = *pBlock->getTevSwapModeTable(i);
}

/* 802E9090-802E932C       .text reset__13J3DTevBlock16FP11J3DTevBlock */
void J3DTevBlock16::reset(J3DTevBlock* pBlock) {
    mTevStageNum = pBlock->getTevStageNum();
    for (u32 i = 0; i < 8; i++)
        mTexNo[i] = pBlock->getTexNo(i);
    for (u32 i = 0; i < 16; i++)
        mTevOrder[i] = *pBlock->getTevOrder(i);
    for (u32 i = 0; i < 16; i++) {
        mTevStage[i] = *pBlock->getTevStage(i);
        mIndTevStage[i] = *pBlock->getIndTevStage(i);
    }
    for (u32 i = 0; i < 4; i++)
        mTevColor[i] = *pBlock->getTevColor(i);
    for (u32 i = 0; i < 4; i++)
        mTevKColor[i] = *pBlock->getTevKColor(i);
    for (u32 i = 0; i < 16; i++)
        mTevKColorSel[i] = pBlock->getTevKColorSel(i);
    for (u32 i = 0; i < 16; i++)
        mTevKAlphaSel[i] = pBlock->getTevKAlphaSel(i);
    for (u32 i = 0; i < 4; i++)
        mTevSwapModeTable[i] = *pBlock->getTevSwapModeTable(i);
}

/* 802E932C-802E947C       .text reset__15J3DIndBlockFullFP11J3DIndBlock */
void J3DIndBlockFull::reset(J3DIndBlock* pBlock) {
    mIndTexStageNum = pBlock->getIndTexStageNum();
    for (u32 i = 0; i < 4; i++)
        mIndTexOrder[i] = *pBlock->getIndTexOrder(i);
    for (u32 i = 0; i < 3; i++)
        mIndTexMtx[i] = *pBlock->getIndTexMtx(i);
    for (u32 i = 0; i < 4; i++)
        mIndTexCoordScale[i] = *pBlock->getIndTexCoordScale(i);
}

/* 802E947C-802E957C       .text reset__16J3DPEBlockFogOffFP10J3DPEBlock */
void J3DPEBlockFogOff::reset(J3DPEBlock* pBlock) {
    switch (pBlock->getType()) {
    case 'PEFL':
    case 'PEFG':
        mAlphaComp = *pBlock->getAlphaComp();
        mBlend = *pBlock->getBlend();
        mZMode = *pBlock->getZMode();
        mZCompLoc = pBlock->getZCompLoc();
        break;
    }
}

/* 802E957C-802E96C8       .text reset__14J3DPEBlockFullFP10J3DPEBlock */
void J3DPEBlockFull::reset(J3DPEBlock* pBlock) {
    if (pBlock->getFog() != NULL) {
        memcpy(mFog, pBlock->getFog(), sizeof(*mFog));
        DCStoreRange(mFog, sizeof(*mFog));
    }

    switch (pBlock->getType()) {
    case 'PEFL':
    case 'PEFG':
        mAlphaComp = *pBlock->getAlphaComp();
        mBlend = *pBlock->getBlend();
        mZMode = *pBlock->getZMode();
        mZCompLoc = pBlock->getZCompLoc();
        break;
    }
}

/* 802E96C8-802E9920       .text calc__21J3DTexGenBlockPatchedFPA4_Cf */
void J3DTexGenBlockPatched::calc(const Mtx modelMtx) {
    if (!((j3dSys.mFlags >> 2) & 0x01) || !j3dSys.checkFlag(J3DSysFlag_SkinNrmCpu)) {
        for (s32 i = 0; i < (s32)ARRAY_SIZE(mTexMtx); i++) {
            if (mTexMtx[i] == NULL)
                continue;

            u32 mode = mTexMtx[i]->getTexMtxInfo().mInfo & 0x7F;
            if (mode == J3DTexMtxMode_EnvmapOld || mode == J3DTexMtxMode_Envmap || mode == J3DTexMtxMode_EnvmapBasic) {
                Mtx viewMtx;
                MTXConcat(j3dSys.getViewMtx(), modelMtx, viewMtx);
                viewMtx[0][3] = 0.0f;
                viewMtx[1][3] = 0.0f;
                viewMtx[2][3] = 0.0f;
                mTexMtx[i]->setViewMtx(viewMtx);
            } else if (mode == J3DTexMtxMode_Projmap || mode == J3DTexMtxMode_ProjmapBasic) {
                mTexMtx[i]->setViewMtx(modelMtx);
            } else if (mode == J3DTexMtxMode_ViewProjmap || mode == J3DTexMtxMode_ViewProjmapBasic) {
                Mtx viewMtx;
                MTXConcat(j3dSys.getViewMtx(), modelMtx, viewMtx);
                mTexMtx[i]->setViewMtx(viewMtx);
            } else if (mode == J3DTexMtxMode_EnvmapOldEffectMtx || mode == J3DTexMtxMode_EnvmapEffectMtx || mode == J3DTexMtxMode_Unknown5) {
                mTexMtx[i]->setViewMtx(modelMtx);
                mTexMtx[i]->getViewMtx()[0][3] = 0.0f;
                mTexMtx[i]->getViewMtx()[1][3] = 0.0f;
                mTexMtx[i]->getViewMtx()[2][3] = 0.0f;
            }

            mTexMtx[i]->calc();
        }
    } else {
        for (s32 i = 0; i < (s32)ARRAY_SIZE(mTexMtx); i++) {
            if (mTexMtx[i] == NULL)
                continue;

            u32 mode = mTexMtx[i]->getTexMtxInfo().mInfo & 0x7F;
            if (mode == J3DTexMtxMode_Envmap || mode == J3DTexMtxMode_EnvmapOld || mode == J3DTexMtxMode_EnvmapBasic) {
                Mtx viewMtx;
                MTXCopy(j3dSys.getViewMtx(), viewMtx);
                viewMtx[0][3] = 0.0f;
                viewMtx[1][3] = 0.0f;
                viewMtx[2][3] = 0.0f;
                mTexMtx[i]->setViewMtx(viewMtx);
            } else if (mode == J3DTexMtxMode_Projmap || mode == J3DTexMtxMode_ProjmapBasic) {
                mTexMtx[i]->setViewMtx(j3dDefaultMtx);
            } else if (mode == J3DTexMtxMode_ViewProjmap || mode == J3DTexMtxMode_ViewProjmapBasic) {
                mTexMtx[i]->setViewMtx(j3dSys.getViewMtx());
            } else if (mode == J3DTexMtxMode_EnvmapOldEffectMtx || mode == J3DTexMtxMode_EnvmapEffectMtx || mode == J3DTexMtxMode_Unknown5) {
                mTexMtx[i]->setViewMtx(j3dDefaultMtx);
            }

            mTexMtx[i]->calc();
        }
    }
}
