diff --git a/include/c3d/texenv.h b/include/c3d/texenv.h index 5fa0f53..2b2f4bd 100644 --- a/include/c3d/texenv.h +++ b/include/c3d/texenv.h @@ -7,7 +7,7 @@ typedef struct u16 opRgb, opAlpha; u16 funcRgb, funcAlpha; u32 color; - u32 unknown; + u16 scaleRgb, scaleAlpha; } C3D_TexEnv; enum @@ -22,6 +22,9 @@ void TexEnv_Init(C3D_TexEnv* env); C3D_TexEnv* C3D_GetTexEnv(int id); void C3D_SetTexEnv(int id, C3D_TexEnv* env); +void C3D_TexEnvBufUpdate(int mode, int mask); +void C3D_TexEnvBufColor(u32 color); + static inline void C3D_TexEnvSrc(C3D_TexEnv* env, int mode, int s1, int s2, int s3) { int param = GPU_TEVSOURCES(s1, s2, s3); @@ -52,3 +55,11 @@ static inline void C3D_TexEnvColor(C3D_TexEnv* env, u32 color) { env->color = color; } + +static inline void C3D_TexEnvScale(C3D_TexEnv* env, int mode, int param) +{ + if (mode & C3D_RGB) + env->scaleRgb = param; + if (mode & C3D_Alpha) + env->scaleAlpha = param; +} diff --git a/source/base.c b/source/base.c index a7bcd1a..3aa700f 100644 --- a/source/base.c +++ b/source/base.c @@ -49,7 +49,7 @@ static void C3Di_AptEventHook(int hookType, void* param) { ctx->flags |= C3DiF_AttrInfo | C3DiF_BufInfo | C3DiF_Effect | C3DiF_RenderBuf | C3DiF_Viewport | C3DiF_Scissor | C3DiF_Program - | C3DiF_TexAll | C3DiF_TexEnvAll; + | C3DiF_TexAll | C3DiF_TexEnvBuf | C3DiF_TexEnvAll; break; } } @@ -69,7 +69,7 @@ bool C3D_Init(size_t cmdBufSize) GPUCMD_SetBuffer(ctx->cmdBuf, ctx->cmdBufSize, 0); - ctx->flags = C3DiF_Active | C3DiF_TexEnvAll | C3DiF_Effect | C3DiF_TexAll; + ctx->flags = C3DiF_Active | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_Effect | C3DiF_TexAll; // TODO: replace with direct struct access C3D_DepthMap(-1.0f, 0.0f); @@ -81,6 +81,9 @@ bool C3D_Init(size_t cmdBufSize) C3D_AlphaTest(false, GPU_ALWAYS, 0x00); C3D_AlphaBlend(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); + ctx->texEnvBuf = 0; + ctx->texEnvBufClr = 0xFFFFFFFF; + for (i = 0; i < 3; i ++) ctx->tex[i] = NULL; @@ -189,6 +192,13 @@ void C3Di_UpdateContext(void) GPUCMD_AddWrite(GPUREG_TEXUNIT_ENABLE, 0x00011000|units); // enables texture units } + if (ctx->flags & C3DiF_TexEnvBuf) + { + ctx->flags &= ~C3DiF_TexEnvBuf; + GPUCMD_AddMaskedWrite(GPUREG_TEXENV_UPDATE_BUFFER, 0x2, ctx->texEnvBuf); + GPUCMD_AddWrite(GPUREG_TEXENV_BUFFER_COLOR, ctx->texEnvBufClr); + } + if (ctx->flags & C3DiF_TexEnvAll) { for (i = 0; i < 6; i ++) diff --git a/source/context.h b/source/context.h index 93ca0e7..323d53c 100644 --- a/source/context.h +++ b/source/context.h @@ -36,6 +36,8 @@ typedef struct C3D_Tex* tex[3]; C3D_TexEnv texEnv[6]; + u32 texEnvBuf, texEnvBufClr; + C3D_RenderBuf* rb; u32 viewport[5]; u32 scissor[3]; @@ -53,6 +55,7 @@ enum C3DiF_Viewport = BIT(6), C3DiF_Scissor = BIT(7), C3DiF_Program = BIT(8), + C3DiF_TexEnvBuf = BIT(9), #define C3DiF_Tex(n) BIT(23+(n)) C3DiF_TexAll = 7 << 23, diff --git a/source/texenv.c b/source/texenv.c index 1004680..d897d7a 100644 --- a/source/texenv.c +++ b/source/texenv.c @@ -11,7 +11,8 @@ void TexEnv_Init(C3D_TexEnv* env) env->funcRgb = GPU_REPLACE; env->funcAlpha = env->funcRgb; env->color = 0xFFFFFFFF; - env->unknown = 0; + env->scaleRgb = GPU_TEVSCALE_1; + env->scaleAlpha = GPU_TEVSCALE_1; } C3D_TexEnv* C3D_GetTexEnv(int id) @@ -41,3 +42,40 @@ void C3Di_TexEnvBind(int id, C3D_TexEnv* env) if (id >= 4) id += 2; GPUCMD_AddIncrementalWrites(GPUREG_TEXENV0_SOURCE + id*8, (u32*)env, sizeof(C3D_TexEnv)/sizeof(u32)); } + +void C3D_TexEnvBufUpdate(int mode, int mask) +{ + C3D_Context* ctx = C3Di_GetContext(); + + if (!(ctx->flags & C3DiF_Active)) + return; + + u32 val = ctx->texEnvBuf; + mask &= 0xF; + + if (mode & C3D_RGB) + { + val &= ~(0xF << 8); + val |= mask << 8; + } + + if (mode & C3D_Alpha) + { + val &= ~(0xF << 12); + val |= mask << 12; + } + + ctx->texEnvBuf = val; + ctx->flags |= C3DiF_TexEnvBuf; +} + +void C3D_TexEnvBufColor(u32 color) +{ + C3D_Context* ctx = C3Di_GetContext(); + + if (!(ctx->flags & C3DiF_Active)) + return; + + ctx->texEnvBufClr = color; + ctx->flags |= C3DiF_TexEnvBuf; +}