#include "internal.h" static inline u32 calc_diff(u32 a, u32 b, int pos) { float fa = ((a>>pos)&0xFF)/255.0f; float fb = ((b>>pos)&0xFF)/255.0f; float x = fb-fa; u32 diff = 0; if (x < 0) { diff = 0x80; x = -x; } diff |= (u32)(x*0x7F); return diff< 1.0f) x = 1.0f; return ((u32)x*255)<color[i] = data[i]; if (i > 0) lut->diff[i-1] = color_diff(data[i-1], data[i]); } } void C3D_GasAttn(float value) { C3D_Context* ctx = C3Di_GetContext(); if (!(ctx->flags & C3DiF_Active)) return; ctx->flags |= C3DiF_Gas; ctx->gasAttn = f32tof16(value); } void C3D_GasAccMax(float value) { C3D_Context* ctx = C3Di_GetContext(); if (!(ctx->flags & C3DiF_Active)) return; ctx->flags |= C3DiF_Gas; ctx->gasAccMax = f32tof16(1.0f / value); } void C3D_GasDeltaZ(float value) { C3D_Context* ctx = C3Di_GetContext(); if (!(ctx->flags & C3DiF_Active)) return; ctx->flags |= C3DiF_Gas; ctx->gasDeltaZ = (u32)(value*0x100) & 0xFFFFFF; ctx->gasDeltaZ |= 2<<24; } void C3D_GasLightPlanar(float min, float max, float attn) { C3D_Context* ctx = C3Di_GetContext(); if (!(ctx->flags & C3DiF_Active)) return; ctx->flags |= C3DiF_Gas; ctx->gasLightXY = conv_u8(min,0) | conv_u8(max,8) | conv_u8(attn,16); } void C3D_GasLightView(float min, float max, float attn) { C3D_Context* ctx = C3Di_GetContext(); if (!(ctx->flags & C3DiF_Active)) return; ctx->flags |= C3DiF_Gas; ctx->gasLightZ = conv_u8(min,0) | conv_u8(max,8) | conv_u8(attn,16); } void C3D_GasLightDirection(float dotp) { C3D_Context* ctx = C3Di_GetContext(); if (!(ctx->flags & C3DiF_Active)) return; ctx->flags |= C3DiF_Gas; ctx->gasLightZColor &= ~0xFF; ctx->gasLightZColor |= conv_u8(dotp,0); } void C3D_GasLutInput(GPU_GASLUTINPUT input) { C3D_Context* ctx = C3Di_GetContext(); if (!(ctx->flags & C3DiF_Active)) return; ctx->flags |= C3DiF_Gas; ctx->gasLightZColor &= ~0x100; ctx->gasLightZColor |= (input&1)<<8; } void C3D_GasLutBind(C3D_GasLut* lut) { C3D_Context* ctx = C3Di_GetContext(); if (!(ctx->flags & C3DiF_Active)) return; if (lut) { ctx->flags |= C3DiF_GasLut; ctx->gasLut = lut; } else ctx->flags &= ~C3DiF_GasLut; } void C3Di_GasUpdate(C3D_Context* ctx) { //__builtin_printf("updgasstate %08lX\n", ctx->flags); //for(;;); if (ctx->flags & C3DiF_Gas) { ctx->flags &= ~C3DiF_Gas; GPUCMD_AddWrite(GPUREG_GAS_ATTENUATION, ctx->gasAttn); //GPUCMD_AddWrite(GPUREG_GAS_ACCMAX, ctx->gasAccMax); GPUCMD_AddWrite(GPUREG_GAS_LIGHT_XY, ctx->gasLightXY); GPUCMD_AddWrite(GPUREG_GAS_LIGHT_Z, ctx->gasLightZ); GPUCMD_AddWrite(GPUREG_GAS_LIGHT_Z_COLOR, ctx->gasLightZColor); GPUCMD_AddWrite(GPUREG_GAS_DELTAZ_DEPTH, ctx->gasDeltaZ); } if (ctx->flags & C3DiF_GasLut) { ctx->flags &= ~C3DiF_GasLut; if (ctx->gasLut) { GPUCMD_AddWrite(GPUREG_GAS_LUT_INDEX, 0); GPUCMD_AddWrites(GPUREG_GAS_LUT_DATA, (u32*)ctx->gasLut, 16); } } }