marioparty4/src/dolphin/gx/GXPixel.c
2024-12-31 02:21:59 +01:00

290 lines
7.7 KiB
C

#include <dolphin/gx.h>
#include <dolphin/os.h>
#include <math.h>
#include <dolphin/gx/GXPriv.h>
void GXSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color)
{
u32 fogclr;
u32 fog0;
u32 fog1;
u32 fog2;
u32 fog3;
f32 A;
f32 B;
f32 B_mant;
f32 C;
f32 a;
f32 c;
u32 B_expn;
u32 b_m;
u32 b_s;
u32 a_hex;
u32 c_hex;
CHECK_GXBEGIN(0x8A, "GXSetFog");
ASSERTMSGLINE(0x8C, farz >= 0.0f, "GXSetFog: The farz should be positive value");
ASSERTMSGLINE(0x8D, farz >= nearz, "GXSetFog: The farz should be larger than nearz");
if (farz == nearz || endz == startz) {
A = 0.0f;
B = 0.5f;
C = 0.0f;
}
else {
A = (farz * nearz) / ((farz - nearz) * (endz - startz));
B = farz / (farz - nearz);
C = startz / (endz - startz);
}
B_mant = B;
B_expn = 0;
while (B_mant > 1.0) {
B_mant *= 0.5f;
B_expn++;
}
while (B_mant > 0.0f && B_mant < 0.5) {
B_mant *= 2.0f;
B_expn--;
}
a = A / (f32)(1 << (B_expn + 1));
b_m = 8.388638e6f * B_mant;
b_s = B_expn + 1;
c = C;
fog1 = 0;
SET_REG_FIELD(0x94, fog1, 24, 0, b_m);
SET_REG_FIELD(0x95, fog1, 8, 24, 0xEF);
fog2 = 0;
SET_REG_FIELD(0x98, fog2, 5, 0, b_s);
SET_REG_FIELD(0x99, fog2, 8, 24, 0xF0);
a_hex = *(u32 *)&a;
c_hex = *(u32 *)&c;
fog0 = 0;
SET_REG_FIELD(0xA0, fog0, 11, 0, (a_hex >> 12) & 0x7FF);
SET_REG_FIELD(0xA1, fog0, 8, 11, (a_hex >> 23) & 0xFF);
SET_REG_FIELD(0xA2, fog0, 1, 19, (a_hex >> 31));
SET_REG_FIELD(0xA3, fog0, 8, 24, 0xEE);
fog3 = 0;
SET_REG_FIELD(0xA6, fog3, 11, 0, (c_hex >> 12) & 0x7FF);
SET_REG_FIELD(0xA7, fog3, 8, 11, (c_hex >> 23) & 0xFF);
SET_REG_FIELD(0xA8, fog3, 1, 19, (c_hex >> 31));
SET_REG_FIELD(0xA9, fog3, 1, 20, 0);
SET_REG_FIELD(0xAA, fog3, 3, 21, type);
SET_REG_FIELD(0xAB, fog3, 8, 24, 0xF1);
fogclr = 0;
SET_REG_FIELD(0xAE, fogclr, 8, 0, color.b);
SET_REG_FIELD(0xAF, fogclr, 8, 8, color.g);
SET_REG_FIELD(0xB0, fogclr, 8, 16, color.r);
SET_REG_FIELD(0xB1, fogclr, 8, 24, 0xF2);
GX_WRITE_RAS_REG(fog0);
GX_WRITE_RAS_REG(fog1);
GX_WRITE_RAS_REG(fog2);
GX_WRITE_RAS_REG(fog3);
GX_WRITE_RAS_REG(fogclr);
gx->bpSentNot = 0;
}
void GXSetFogColor(GXColor color)
{
unsigned long rgba;
unsigned long fogclr = 0xF2000000;
rgba = *(u32 *)&color;
SET_REG_FIELD(0xFA, fogclr, 24, 0, rgba >> 8);
GX_WRITE_RAS_REG(fogclr);
gx->bpSentNot = 0;
}
void GXInitFogAdjTable(GXFogAdjTable *table, u16 width, const f32 projmtx[4][4])
{
f32 xi;
f32 iw;
f32 rangeVal;
f32 nearZ;
f32 sideX;
u32 i;
CHECK_GXBEGIN(0x113, "GXInitFogAdjTable");
ASSERTMSGLINE(0x114, table != NULL, "GXInitFogAdjTable: table pointer is null");
ASSERTMSGLINE(0x115, width <= 640, "GXInitFogAdjTable: invalid width value");
if (0.0 == projmtx[3][3]) {
nearZ = projmtx[2][3] / (projmtx[2][2] - 1.0f);
sideX = nearZ / projmtx[0][0];
}
else {
sideX = 1.0f / projmtx[0][0];
nearZ = 1.73205f * sideX;
}
iw = 2.0f / width;
for (i = 0; i < 10; i++) {
xi = (i + 1) << 5;
xi *= iw;
xi *= sideX;
rangeVal = sqrtf(1.0f + ((xi * xi) / (nearZ * nearZ)));
table->r[i] = (u32)(256.0f * rangeVal) & 0xFFF;
}
}
void GXSetFogRangeAdj(GXBool enable, u16 center, const GXFogAdjTable *table)
{
u32 i;
u32 range_adj;
u32 range_c;
CHECK_GXBEGIN(0x14B, "GXSetFogRangeAdj");
if (enable) {
ASSERTMSGLINE(0x14E, table != NULL, "GXSetFogRangeAdj: table pointer is null");
for (i = 0; i < 10; i += 2) {
range_adj = 0;
SET_REG_FIELD(0x152, range_adj, 12, 0, table->r[i]);
SET_REG_FIELD(0x153, range_adj, 12, 12, table->r[i + 1]);
SET_REG_FIELD(0x154, range_adj, 8, 24, (i >> 1) + 0xE9);
GX_WRITE_RAS_REG(range_adj);
}
}
range_c = 0;
SET_REG_FIELD(0x15A, range_c, 10, 0, center + 342);
SET_REG_FIELD(0x15B, range_c, 1, 10, enable);
SET_REG_FIELD(0x15C, range_c, 8, 24, 0xE8);
GX_WRITE_RAS_REG(range_c);
gx->bpSentNot = 0;
}
void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op)
{
CHECK_GXBEGIN(0x177, "GXSetBlendMode");
SET_REG_FIELD(0x135, gx->cmode0, 1, 0, (type == GX_BM_BLEND || type == GX_BM_SUBTRACT));
SET_REG_FIELD(0x136, gx->cmode0, 1, 11, (type == GX_BM_SUBTRACT));
SET_REG_FIELD(0x138, gx->cmode0, 1, 1, (type == GX_BM_LOGIC));
SET_REG_FIELD(0x139, gx->cmode0, 4, 12, op);
SET_REG_FIELD(0x13A, gx->cmode0, 3, 8, src_factor);
SET_REG_FIELD(0x13B, gx->cmode0, 3, 5, dst_factor);
SET_REG_FIELD(0x13C, gx->cmode0, 8, 24, 0x41);
GX_WRITE_RAS_REG(gx->cmode0);
gx->bpSentNot = 0;
}
void GXSetColorUpdate(GXBool update_enable)
{
CHECK_GXBEGIN(0x1A3, "GXSetColorUpdate");
SET_REG_FIELD(0x150, gx->cmode0, 1, 3, update_enable);
GX_WRITE_RAS_REG(gx->cmode0);
gx->bpSentNot = 0;
}
void GXSetAlphaUpdate(GXBool update_enable)
{
CHECK_GXBEGIN(0x1B0, "GXSetAlphaUpdate");
SET_REG_FIELD(0x159, gx->cmode0, 1, 4, update_enable);
GX_WRITE_RAS_REG(gx->cmode0);
gx->bpSentNot = 0;
}
void GXSetZMode(GXBool compare_enable, GXCompare func, GXBool update_enable)
{
CHECK_GXBEGIN(0x1CB, "GXSetZMode");
SET_REG_FIELD(0x171, gx->zmode, 1, 0, compare_enable);
SET_REG_FIELD(0x172, gx->zmode, 3, 1, func);
SET_REG_FIELD(0x173, gx->zmode, 1, 4, update_enable);
GX_WRITE_RAS_REG(gx->zmode);
gx->bpSentNot = 0;
}
void GXSetZCompLoc(GXBool before_tex)
{
CHECK_GXBEGIN(0x1DA, "GXSetZCompLoc");
SET_REG_FIELD(0x1DB, gx->peCtrl, 1, 6, before_tex);
GX_WRITE_RAS_REG(gx->peCtrl);
gx->bpSentNot = 0;
}
void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt)
{
u32 oldPeCtrl;
u8 aa;
static u32 p2f[8] = { 0, 1, 2, 3, 4, 4, 4, 5 };
CHECK_GXBEGIN(0x1FF, "GXSetPixelFmt");
oldPeCtrl = gx->peCtrl;
ASSERTMSGLINE(0x203, pix_fmt >= 0 && pix_fmt <= 7, "Invalid Pixel format");
SET_REG_FIELD(0x205, gx->peCtrl, 3, 0, p2f[pix_fmt]);
SET_REG_FIELD(0x206, gx->peCtrl, 3, 3, z_fmt);
if (oldPeCtrl != gx->peCtrl) {
GX_WRITE_RAS_REG(gx->peCtrl);
if (pix_fmt == GX_PF_RGB565_Z16)
aa = 1;
else
aa = 0;
SET_REG_FIELD(0x20F, gx->genMode, 1, 9, aa);
gx->dirtyState |= 4;
}
if (p2f[pix_fmt] == 4) {
SET_REG_FIELD(0x216, gx->cmode1, 2, 9, (pix_fmt - 4) & 0x3);
SET_REG_FIELD(0x216, gx->cmode1, 8, 24, 0x42);
GX_WRITE_RAS_REG(gx->cmode1);
}
gx->bpSentNot = 0;
}
void GXSetDither(GXBool dither)
{
CHECK_GXBEGIN(0x22C, "GXSetDither");
SET_REG_FIELD(0x1CE, gx->cmode0, 1, 2, dither);
GX_WRITE_RAS_REG(gx->cmode0);
gx->bpSentNot = 0;
}
void GXSetDstAlpha(GXBool enable, u8 alpha)
{
CHECK_GXBEGIN(0x245, "GXSetDstAlpha");
SET_REG_FIELD(0x1E2, gx->cmode1, 8, 0, alpha);
SET_REG_FIELD(0x1E3, gx->cmode1, 1, 8, enable);
GX_WRITE_RAS_REG(gx->cmode1);
gx->bpSentNot = 0;
}
void GXSetFieldMask(GXBool odd_mask, GXBool even_mask)
{
u32 reg;
CHECK_GXBEGIN(0x260, "GXSetFieldMask");
reg = 0;
SET_REG_FIELD(0x262, reg, 1, 0, even_mask);
SET_REG_FIELD(0x263, reg, 1, 1, odd_mask);
SET_REG_FIELD(0x263, reg, 8, 24, 0x44);
GX_WRITE_RAS_REG(reg);
gx->bpSentNot = 0;
}
void GXSetFieldMode(GXBool field_mode, GXBool half_aspect_ratio)
{
u32 reg;
CHECK_GXBEGIN(0x27D, "GXSetFieldMode");
SET_REG_FIELD(0x281, gx->lpSize, 1, 22, half_aspect_ratio);
GX_WRITE_RAS_REG(gx->lpSize);
__GXFlushTextureState();
reg = field_mode | 0x68000000;
GX_WRITE_RAS_REG(reg);
__GXFlushTextureState();
}