tp/libs/dolphin/gx/GXTev.c

387 lines
10 KiB
C

#include "dolphin/gx/GXTev.h"
#include "dolphin/gx.h"
/* ############################################################################################## */
/* 803D27C0-803D27D4 02F8E0 0014+00 1/1 0/0 0/0 .data TEVCOpTableST0 */
static u32 TEVCOpTableST0[] = {
0xC008F8AF, // modulate
0xC008A89F, // decal
0xC008AC8F, // blend
0xC008FFF8, // replace
0xC008FFFA, // passclr
};
/* 803D27D4-803D27E8 02F8F4 0014+00 0/0 0/0 0/0 .data TEVCOpTableST1 */
static u32 TEVCOpTableST1[] = {
0xC008F80F, // modulate
0xC008089F, // decal
0xC0080C8F, // blend
0xC008FFF8, // replace
0xC008FFF0, // passclr
};
/* 803D27E8-803D27FC 02F908 0014+00 0/0 0/0 0/0 .data TEVAOpTableST0 */
static u32 TEVAOpTableST0[] = {
0xC108F2F0, // modulate
0xC108FFD0, // decal
0xC108F2F0, // blend
0xC108FFC0, // replace
0xC108FFD0, // passclr
};
/* 803D27FC-803D2810 02F91C 0014+00 0/0 0/0 0/0 .data TEVAOpTableST1 */
static u32 TEVAOpTableST1[] = {
0xC108F070, // modulate
0xC108FF80, // decal
0xC108F070, // blend
0xC108FFC0, // replace
0xC108FF80, // passclr
};
/* 8035F198-8035F224 359AD8 008C+00 0/0 15/15 1/1 .text GXSetTevOp */
void GXSetTevOp(GXTevStageID stage, GXTevMode mode) {
u32* color;
u32* alpha;
u32 tevReg;
if (stage == GX_TEVSTAGE0) {
color = &TEVCOpTableST0[mode];
alpha = &TEVAOpTableST0[mode];
} else {
color = &TEVCOpTableST1[mode];
alpha = &TEVAOpTableST1[mode];
}
tevReg = __GXData->tevc[stage];
tevReg = (*color & ~0xFF000000) | (tevReg & 0xFF000000);
GX_WRITE_U8(0x61);
GX_WRITE_U32(tevReg);
__GXData->tevc[stage] = tevReg;
tevReg = __GXData->teva[stage];
tevReg = (*alpha & ~0xFF00000F) | (tevReg & 0xFF00000F);
GX_WRITE_U8(0x61);
GX_WRITE_U32(tevReg);
__GXData->teva[stage] = tevReg;
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F224-8035F268 359B64 0044+00 0/0 49/49 5/5 .text GXSetTevColorIn */
void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c,
GXTevColorArg d) {
u32 tevReg;
tevReg = __GXData->tevc[stage];
FAST_FLAG_SET(tevReg, a, 12, 4);
FAST_FLAG_SET(tevReg, b, 8, 4);
FAST_FLAG_SET(tevReg, c, 4, 4);
FAST_FLAG_SET(tevReg, d, 0, 4);
GX_WRITE_U8(0x61);
GX_WRITE_U32(tevReg);
__GXData->tevc[stage] = tevReg;
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F268-8035F2AC 359BA8 0044+00 0/0 49/49 6/6 .text GXSetTevAlphaIn */
void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c,
GXTevAlphaArg d) {
u32 tevReg;
tevReg = __GXData->teva[stage];
FAST_FLAG_SET(tevReg, a, 13, 3);
FAST_FLAG_SET(tevReg, b, 10, 3);
FAST_FLAG_SET(tevReg, c, 7, 3);
FAST_FLAG_SET(tevReg, d, 4, 3);
GX_WRITE_U8(0x61);
GX_WRITE_U32(tevReg);
__GXData->teva[stage] = tevReg;
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F2AC-8035F314 359BEC 0068+00 0/0 50/50 5/5 .text GXSetTevColorOp */
void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale,
GXBool doClamp, GXTevRegID outReg) {
u32 tevReg;
tevReg = __GXData->tevc[stage];
FAST_FLAG_SET(tevReg, op & 1, 18, 1);
if (op <= 1) {
FAST_FLAG_SET(tevReg, scale, 20, 2);
FAST_FLAG_SET(tevReg, bias, 16, 2);
} else {
FAST_FLAG_SET(tevReg, (op >> 1) & 3, 20, 2);
FAST_FLAG_SET(tevReg, 3, 16, 2);
}
FAST_FLAG_SET(tevReg, doClamp, 19, 1);
FAST_FLAG_SET(tevReg, outReg, 22, 2);
GX_WRITE_U8(0x61);
GX_WRITE_U32(tevReg);
__GXData->tevc[stage] = tevReg;
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F314-8035F37C 359C54 0068+00 0/0 50/50 5/5 .text GXSetTevAlphaOp */
void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale,
GXBool doClamp, GXTevRegID outReg) {
u32 tevReg;
tevReg = __GXData->teva[stage];
FAST_FLAG_SET(tevReg, op & 1, 18, 1);
if (op <= 1) {
FAST_FLAG_SET(tevReg, scale, 20, 2);
FAST_FLAG_SET(tevReg, bias, 16, 2);
} else {
FAST_FLAG_SET(tevReg, (op >> 1) & 3, 20, 2);
FAST_FLAG_SET(tevReg, 3, 16, 2);
}
FAST_FLAG_SET(tevReg, doClamp, 19, 1);
FAST_FLAG_SET(tevReg, outReg, 22, 2);
GX_WRITE_U8(0x61);
GX_WRITE_U32(tevReg);
__GXData->teva[stage] = tevReg;
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F37C-8035F3DC 359CBC 0060+00 0/0 54/54 4/4 .text GXSetTevColor */
void GXSetTevColor(GXTevRegID reg, GXColor color) {
u32 col = *(u32*)&color;
u32 ra = (0xE0 + reg * 2) << 24;
u32 bg = (0xE1 + reg * 2) << 24;
GX_SET_REG(ra, col >> 24, 24, 31);
GX_SET_REG(bg, col >> 8, 24, 31);
GX_SET_REG(bg, col >> 16, 12, 19);
GX_SET_REG(ra, col & 0xFF, 12, 19);
GX_BP_LOAD_REG(ra);
GX_BP_LOAD_REG(bg);
GX_BP_LOAD_REG(bg);
GX_BP_LOAD_REG(bg);
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F3DC-8035F440 359D1C 0064+00 0/0 8/8 2/2 .text GXSetTevColorS10 */
void GXSetTevColorS10(GXTevRegID reg, GXColorS10 color) {
u32 col = *(u32*)&color;
u32 col1 = ((u32*)&color)[1];
u32 ra = (0xE0 + reg * 2) << 24;
u32 bg = (0xE1 + reg * 2) << 24;
GX_SET_REG(ra, col >> 16, 21, 31);
GX_SET_REG(bg, col1 >> 16, 21, 31);
GX_SET_REG(bg, col & 0x7FF, 9, 19);
GX_SET_REG(ra, col1 & 0x7FF, 9, 19);
GX_BP_LOAD_REG(ra);
GX_BP_LOAD_REG(bg);
GX_BP_LOAD_REG(bg);
GX_BP_LOAD_REG(bg);
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F440-8035F4A4 359D80 0064+00 0/0 8/8 4/4 .text GXSetTevKColor */
void GXSetTevKColor(GXTevKColorID id, GXColor color) {
u32 col = *(u32*)&color;
u32 ra;
u32 bg;
ra = (0xE0 + id * 2) << 24;
GX_SET_REG(ra, col >> 24, 24, 31);
GX_SET_REG(ra, col & 0xFF, 12, 19);
GX_SET_REG(ra, 8, 8, 11);
bg = (0xE1 + id * 2) << 24;
GX_SET_REG(bg, col >> 8, 24, 31);
GX_SET_REG(bg, col >> 16, 12, 19);
GX_SET_REG(bg, 8, 8, 11);
GX_BP_LOAD_REG(ra);
GX_BP_LOAD_REG(bg);
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F4A4-8035F500 359DE4 005C+00 0/0 9/9 4/4 .text GXSetTevKColorSel */
void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel) {
u32* reg;
reg = &__GXData->tevKsel[stage >> 1];
if (stage & 1) {
GX_SET_REG(*reg, sel, 13, 17);
} else {
GX_SET_REG(*reg, sel, 23, 27);
}
GX_BP_LOAD_REG(*reg);
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F500-8035F55C 359E40 005C+00 0/0 9/9 4/4 .text GXSetTevKAlphaSel */
void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel) {
u32* reg;
reg = &__GXData->tevKsel[stage >> 1];
if (stage & 1) {
GX_SET_REG(*reg, sel, 8, 12);
} else {
GX_SET_REG(*reg, sel, 18, 22);
}
GX_BP_LOAD_REG(*reg);
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F55C-8035F5A4 359E9C 0048+00 0/0 10/10 5/5 .text GXSetTevSwapMode */
void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel rasSel, GXTevSwapSel texSel) {
u32* reg = &__GXData->teva[stage];
GX_SET_REG(*reg, rasSel, 30, 31);
GX_SET_REG(*reg, texSel, 28, 29);
GX_BP_LOAD_REG(*reg);
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F5A4-8035F624 359EE4 0080+00 0/0 17/17 2/2 .text GXSetTevSwapModeTable */
void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColor red, GXTevColor green, GXTevColor blue,
GXTevColor alpha) {
u32* reg;
reg = &__GXData->tevKsel[table << 1];
GX_SET_REG(*reg, red, 30, 31);
GX_SET_REG(*reg, green, 28, 29);
GX_BP_LOAD_REG(*reg);
reg = &__GXData->tevKsel[(table << 1) + 1];
GX_SET_REG(*reg, blue, 30, 31);
GX_SET_REG(*reg, alpha, 28, 29);
GX_BP_LOAD_REG(*reg);
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F624-8035F668 359F64 0044+00 0/0 43/43 5/5 .text GXSetAlphaCompare */
void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) {
u32 reg = 0xF3000000;
GX_SET_REG(reg, ref0, 24, 31);
GX_SET_REG(reg, ref1, 16, 23);
GX_SET_REG(reg, comp0, 13, 15);
GX_SET_REG(reg, comp1, 10, 12);
GX_SET_REG(reg, op, 8, 9);
GX_BP_LOAD_REG(reg);
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F668-8035F6F4 359FA8 008C+00 0/0 3/3 0/0 .text GXSetZTexture */
void GXSetZTexture(GXZTexOp op, GXTexFmt format, u32 bias) {
u32 val1;
u32 val2;
u32 val3;
val1 = 0;
GX_SET_REG(val1, bias, 8, 31);
GX_SET_REG(val1, 0xF4, 0, 7);
val2 = 0;
switch (format) {
case GX_TF_Z8:
val3 = 0;
break;
case GX_TF_Z16:
val3 = 1;
break;
case GX_TF_Z24X8:
val3 = 2;
break;
default:
val3 = 2;
break;
}
GX_SET_REG(val2, val3, 30, 31);
GX_SET_REG(val2, op, 28, 29);
GX_SET_REG(val2, 0xF5, 0, 7);
GX_BP_LOAD_REG(val1);
GX_BP_LOAD_REG(val2);
__GXData->bpSentNot = GX_FALSE;
}
/* 8035F6F4-8035F890 35A034 019C+00 0/0 65/65 6/6 .text GXSetTevOrder */
void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color) {
static int c2r[] = {0, 1, 0, 1, 0, 1, 7, 5, 6};
u32* reg;
u32 tempMap;
u32 tempCoord;
reg = &__GXData->tref[stage / 2];
__GXData->texmapId[stage] = map;
tempMap = map & ~0x100;
tempMap = (tempMap >= GX_MAX_TEXMAP) ? GX_TEXMAP0 : tempMap;
if (coord >= GX_MAXCOORD) {
tempCoord = GX_TEXCOORD0;
__GXData->tevTcEnab = __GXData->tevTcEnab & ~(1 << stage);
} else {
tempCoord = coord;
__GXData->tevTcEnab = __GXData->tevTcEnab | (1 << stage);
}
if (stage & 1) {
GX_SET_REG(*reg, tempMap, 17, 19);
GX_SET_REG(*reg, tempCoord, 14, 16);
GX_SET_REG(*reg, (color == GX_COLOR_NULL ? 7 : c2r[color]), 10, 12);
GX_SET_REG(*reg, ((map != GX_TEXMAP_NULL) && !(map & 0x100)), 13, 13);
} else {
GX_SET_REG(*reg, tempMap, 29, 31);
GX_SET_REG(*reg, tempCoord, 26, 28);
GX_SET_REG(*reg, (color == GX_COLOR_NULL ? 7 : c2r[color]), 22, 24);
GX_SET_REG(*reg, ((map != GX_TEXMAP_NULL) && !(map & 0x100)), 25, 25);
}
GX_BP_LOAD_REG(*reg);
__GXData->bpSentNot = GX_FALSE;
__GXData->dirtyState |= 1;
}
/* 8035F890-8035F8B8 35A1D0 0028+00 0/0 63/63 6/6 .text GXSetNumTevStages */
void GXSetNumTevStages(u8 count) {
GX_SET_REG(__GXData->genMode, count - 1, 18, 21);
__GXData->dirtyState |= 0x4;
}