diff --git a/src/code/z_kankyo.c b/src/code/z_kankyo.c index 84b4558e77..e560f7eb52 100644 --- a/src/code/z_kankyo.c +++ b/src/code/z_kankyo.c @@ -12,13 +12,14 @@ typedef enum { } LightningBoltState; typedef struct { - /* 0x00 */ s32 mantissa; - /* 0x04 */ s32 exponent; -} ZBufValConversionEntry; // size = 0x8 + /* 0x00 */ s32 mantissaShift; // shift applied to the mantissa of the z buffer value + /* 0x04 */ s32 base; // 15.3 fixed-point base value for the exponent +} ZBufValConversionEntry; // size = 0x8 +// This table needs as many values as there are values for the 3-bit exponent ZBufValConversionEntry sZBufValConversionTable[1 << 3] = { - { 6, 0x00000 }, { 5, 0x20000 }, { 4, 0x30000 }, { 3, 0x38000 }, - { 2, 0x3C000 }, { 1, 0x3E000 }, { 0, 0x3F000 }, { 0, 0x3F800 }, + { 6, 0x0000 << 3 }, { 5, 0x4000 << 3 }, { 4, 0x6000 << 3 }, { 3, 0x7000 << 3 }, + { 2, 0x7800 << 3 }, { 1, 0x7C00 << 3 }, { 0, 0x7E00 << 3 }, { 0, 0x7F00 << 3 }, }; u8 gWeatherMode = WEATHER_MODE_CLEAR; // "E_wether_flg" @@ -225,9 +226,9 @@ u16 sSandstormScroll; * 4: dz value (unused) */ s32 Environment_ZBufValToFixedPoint(s32 zBufferVal) { - // base[exp] + mantissa << shift[exp] - s32 ret = (ZBUFVAL_MANTISSA(zBufferVal) << sZBufValConversionTable[ZBUFVAL_EXPONENT(zBufferVal)].mantissa) + - sZBufValConversionTable[ZBUFVAL_EXPONENT(zBufferVal)].exponent; + // base[exp] + (mantissa << shift[exp]) + s32 ret = (ZBUFVAL_MANTISSA(zBufferVal) << sZBufValConversionTable[ZBUFVAL_EXPONENT(zBufferVal)].mantissaShift) + + sZBufValConversionTable[ZBUFVAL_EXPONENT(zBufferVal)].base; return ret; } diff --git a/src/code/z_lights.c b/src/code/z_lights.c index b230100bce..f01c49df2a 100644 --- a/src/code/z_lights.c +++ b/src/code/z_lights.c @@ -339,11 +339,18 @@ void Lights_GlowCheck(PlayState* play) { wY = multDest.y * cappedInvWDest; if ((multDest.z > 1.0f) && (fabsf(wX) < 1.0f) && (fabsf(wY) < 1.0f)) { - wZ = (s32)((multDest.z * cappedInvWDest) * 16352.0f) + 16352; - zBuf = gZBuffer[(s32)((wY * -120.0f) + 120.0f)][(s32)((wX * 160.0f) + 160.0f)] * 4; + // Compute screen z value assuming the viewport scale and translation both have value G_MAXZ / 2 + // The multiplication by 32 follows from how the RSP microcode computes the screen z value. + wZ = (s32)((multDest.z * cappedInvWDest) * ((G_MAXZ / 2) * 32)) + ((G_MAXZ / 2) * 32); + // Obtain the z-buffer value for the screen pixel corresponding to the center of the glow. + zBuf = gZBuffer[(s32)((wY * -(SCREEN_HEIGHT / 2)) + (SCREEN_HEIGHT / 2))] + [(s32)((wX * (SCREEN_WIDTH / 2)) + (SCREEN_WIDTH / 2))] + << 2; if (1) {} if (1) {} + // Compare the computed screen z value to the integer part of the z-buffer value in fixed point. If + // it is less than the value from the z-buffer the depth test passes and the glow can draw. if (wZ < (Environment_ZBufValToFixedPoint(zBuf) >> 3)) { params->drawGlow = true; }