Day night cycle: Difference between revisions

From wowdev
Jump to navigation Jump to search
(Initial addition of CalcColors)
(→‎Logic: Cleanup)
Line 102: Line 102:
  <nowiki>
  <nowiki>
int DayNight::CDayNightObjectInt::CalcColors(DayNight::CDayNightObjectInt *this, int time, DayNight::CurrentLight *currentLight, LightParamsRec *lightParamsRec) {
int DayNight::CDayNightObjectInt::CalcColors(DayNight::CDayNightObjectInt *this, int time, DayNight::CurrentLight *currentLight, LightParamsRec *lightParamsRec) {
  int result; // eax@1
  LightDataRec *v5; // esi@2
  int v6; // eax@3
  LightDataRec *v7; // ebx@7
  float tfactor1; // xmm1_4@7
  float v9; // xmm1_4@8
  float v10; // xmm3_4@9
  float v11; // xmm0_4@11
  uint32_t v12; // eax@13
  uint32_t v13; // eax@13
  LightDataRec *v14; // ecx@20
  LightDataRec *v15; // ecx@21
  int t1; // eax@22
  int t2; // edx@23
  _DWORD *v18; // edx@24
  int v19; // eax@24
  int v20; // edx@30
  int v21; // eax@30
  float v22; // ST2C_4@32
  uint32_t v23; // eax@32
  float v24; // xmm0_4@33
  float v25; // xmm2_4@34
  float v26; // xmm2_4@35
  float v27; // xmm0_4@36
  float v28; // xmm0_4@37
  int tdiff; // edx@50
  float tfactor2; // [sp+2Ch] [bp-6Ch]@7
  int timea; // [sp+A4h] [bp+Ch]@50


   result = 0;
   // Not shown: obtain the appropriate DBC entries for the start and end
  float tstart = time - t1;
  float tdiff = t2 - t1;
  float tdist = tstart / tdiff;


   if ( lightParamsRec )
   // Interpolate color values 0-17 from LightData.dbc
   {
  currentLight->m_directColor    = DayNight::LerpColor(tdist, start->m_directColor,    end->m_directColor);
     v5 = (LightDataRec *)DayNight::FindFirstLightData(lightParamsRec);
  currentLight->m_ambientColor    = DayNight::LerpColor(tdist, start->m_ambientColor,    end->m_ambientColor);
     if ( v5 )
  currentLight->m_skyTopColor    = DayNight::LerpColor(tdist, start->m_skyTopColor,    end->m_skyTopColor);
     {
  currentLight->m_skyMiddleColor  = DayNight::LerpColor(tdist, start->m_skyMiddleColor,  end->m_skyMiddleColor);
      v6 = g_lightDataDB[1];
  currentLight->m_skyBand1Color  = DayNight::LerpColor(tdist, start->m_skyBand1Color,  end->m_skyBand1Color);
     }
  currentLight->m_skyBand2Color  = DayNight::LerpColor(tdist, start->m_skyBand2Color,  end->m_skyBand2Color);
   currentLight->m_skySmogColor    = DayNight::LerpColor(tdist, start->m_skySmogColor,    end->m_skySmogColor);
  currentLight->m_skyFogColor    = DayNight::LerpColor(tdist, start->m_skyFogColor,     end->m_skyFogColor);
  currentLight->m_shadowOpacity  = DayNight::LerpColor(tdist, start->m_shadowOpacity,  end->m_shadowOpacity);
  currentLight->m_sunColor        = DayNight::LerpColor(tdist, start->m_sunColor,        end->m_sunColor);
  currentLight->m_cloudSunColor  = DayNight::LerpColor(tdist, start->m_cloudSunColor,  end->m_cloudSunColor);
  currentLight->m_cloudLayer1AmbientColor = DayNight::LerpColor(tdist, start->m_cloudLayer1AmbientColor, end->m_cloudLayer1AmbientColor);
  currentLight->m_cloudEmissiveColor      = DayNight::LerpColor(tdist, start->m_cloudEmissiveColor,      end->m_cloudEmissiveColor);
  currentLight->m_cloudLayer2AmbientColor = DayNight::LerpColor(tdist, start->m_cloudLayer2AmbientColor, end->m_cloudLayer2AmbientColor);
  currentLight->m_oceanCloseColor = DayNight::LerpColor(tdist, start->m_oceanCloseColor, end->m_oceanCloseColor);
  currentLight->m_oceanFarColor  = DayNight::LerpColor(tdist, start->m_oceanFarColor,  end->m_oceanFarColor);
  currentLight->m_riverCloseColor = DayNight::LerpColor(tdist, start->m_riverCloseColor, end->m_riverCloseColor);
  currentLight->m_riverFarColor  = DayNight::LerpColor(tdist, start->m_riverFarColor,  end->m_riverFarColor);
 
  // Handle cloud density
  currentLight->m_cloudDensity = start->m_cloudDensity + ((end->m_cloudDensity - start->m_cloudDensity) * tdist);
 
  // Copy light params (these values are not interpolated)
  currentLight->m_highlightSky      = lightParamsRec->m_highlightSky;
  currentLight->m_glow              = lightParamsRec->m_glow;
  currentLight->m_waterShallowAlpha = lightParamsRec->m_waterShallowAlpha;
  currentLight->m_waterDeepAlpha    = lightParamsRec->m_waterDeepAlpha;
  currentLight->m_oceanShallowAlpha = lightParamsRec->m_oceanShallowAlpha;
  currentLight->m_oceanDeepAlpha    = lightParamsRec->m_oceanDeepAlpha;
 
  // Light params flag 0x01 set to off (unk?)
  if (!(lightParamsRec->m_flags & 1))
    currentLight->float7C = 0.0;
  } else {
     currentLight->float7C = 1.0;
  }
 
  // Light params flag 0x02 set to on (unk?)
  currentLight->dword80 = (lightParamsRec->m_flags >> 1) & 1;
 
  currentLight->dword90 = 1.0;
  currentLight->dwordA8 = 1.0;
  currentLight->m_lightSkyboxID = lightParamsRec->m_lightSkyboxID;
  currentLight->m_cloudTypeID = lightParamsRec->m_cloudTypeID;
 
  // Handle fog
  currentLight->m_fogEnd = (start->m_fogEnd + ((end->m_fogEnd - start->m_fogEnd) * tdist)) / 36.0;
  currentLight->m_fogEnd = min(10.0f, currentLight->m_fogEnd);
 
  currentLight->m_fogScalar = start->m_fogScalar + ((end->m_fogScalar - start->m_fogScalar) * tdist);
  currentLight->m_fogScalar = clamp(currentLight->m_fogScalar, -1.0, 1.0);
 
  currentLight->m_fogRate = 1.0;
 
  // Fog not enabled? (unk)
  if (a1->m_info.unk_0 != 1)
     return 1;
 
  if (currentLight->m_fogEnd >= 27.777779) {
    v25 = this->m_info.m_cameraFarClip;
 
     if ( v25 < 700.0 )
      v26 = v25 - 200.0;
     else
     else
    {
       v26 = 500.0;
       v6 = g_lightDataDB[1];
 
      if ( v6 < 0 )
    v27 = currentLight->m_fogEnd - (float)(currentLight->m_fogScalar * v24);
      {
 
        SErrDisplayError(
     if ( v27 <= v26 )
          (void *)0x85100000,
       v28 = (float)((float)(1.0f - (float)(v27 / v26)) * 5.5) + 1.5;
          (int)"/Users/patchman/buildserver/wow-b/work/WoW-code/trunk/WoW/Source/Mac/../DB/WowClientDB.h",
          (void *)0x89,
          "m_numRecords >= 0",
          0,
          1,
          0,
          286331153);
        v6 = g_lightDataDB[1];
      }
      if ( v6 > 0 )
        v5 = (LightDataRec *)g_lightDataDB[5];
    }
     if ( v6 < 0 )
    {
      SErrDisplayError(
        (void *)0x85100000,
        (int)"/Users/patchman/buildserver/wow-b/work/WoW-code/trunk/WoW/Source/Mac/../DB/WowClientDB.h",
        (void *)0x7E,
        "m_numRecords >= 0",
        0,
        1,
        0,
        286331153);
       v6 = g_lightDataDB[1];
    }
    if ( (unsigned int)v5 >= g_lightDataDB[5] + 96 * v6
      || (v7 = (LightDataRec *)((char *)v5 + 96), v5 == (LightDataRec *)-96)
      || v5[1].m_ID != lightParamsRec->m_ID )
    {
      v7 = v5;
      tfactor2 = 0.0;
      tfactor1 = 0.0;
    }
     else
     else
    {
       v28 = 1.5;
       v14 = (LightDataRec *)((char *)v5 + 96);
 
      if ( v5 == v7 )
     currentLight->m_fogRate = v28;
      {
     currentLight->m_fogEnd = this->m_info.m_cameraFarClip;
LABEL_30:
        v20 = v7->m_time;
        v21 = time + 2880;
        if ( time >= v20 )
          v21 = time;
        v22 = (float)(v21 - v20);
        v23 = v5->m_time + 2880 - v20;
        tfactor1 = v22 / (float)(signed int)v23;
        tfactor2 = v22 / (float)(signed int)v23;
        v7 = v5;
        v5 = v14;
      }
      else
      {
        v15 = v5;
        while ( 1 )
        {
          t1 = v15->m_time;
          if ( time >= t1 )
          {
            t2 = v7->m_time;
            if ( time < t2 )
              break;
          }
          v18 = g_lightDataDB;
          v19 = g_lightDataDB[1];
          if ( v19 < 0 )
          {
            SErrDisplayError(
              (void *)0x85100000,
              (int)"/Users/patchman/buildserver/wow-b/work/WoW-code/trunk/WoW/Source/Mac/../DB/WowClientDB.h",
              (void *)0x7E,
              "m_numRecords >= 0",
              0,
              1,
              0,
              286331153);
            v19 = g_lightDataDB[1];
            v18 = g_lightDataDB;
          }
          if ( v18[5] + 96 * v19 <= (unsigned int)v7
            || v7 == (LightDataRec *)-96
            || v7[1].m_ID != lightParamsRec->m_ID
            || (v15 = v7, (LightDataRec *)&v7->m_fogDensity == v5) )
          {
            v14 = v7;
            goto LABEL_30;
          }
          v7 = (LightDataRec *)((char *)v7 + 96);
        }
        timea = time - t1;
        tdiff = t2 - t1;
        tfactor1 = (float)timea / (float)tdiff;
        tfactor2 = (float)timea / (float)tdiff;
        v5 = v15;
      }
    }
    // Interpolate color values 0-17 from LightData.dbc
    currentLight->m_directColor = DayNight::LerpColor(tfactor1, v5->m_directColor, v7->m_directColor);
    currentLight->m_ambientColor = DayNight::LerpColor(tfactor2, v5->m_ambientColor, v7->m_ambientColor);
    currentLight->m_skyTopColor = DayNight::LerpColor(tfactor2, v5->m_skyTopColor, v7->m_skyTopColor);
    currentLight->m_skyMiddleColor = DayNight::LerpColor(tfactor2, v5->m_skyMiddleColor, v7->m_skyMiddleColor);
    currentLight->m_skyBand1Color = DayNight::LerpColor(tfactor2, v5->m_skyBand1Color, v7->m_skyBand1Color);
    currentLight->m_skyBand2Color = DayNight::LerpColor(tfactor2, v5->m_skyBand2Color, v7->m_skyBand2Color);
    currentLight->m_skySmogColor = DayNight::LerpColor(tfactor2, v5->m_skySmogColor, v7->m_skySmogColor);
    currentLight->m_skyFogColor = DayNight::LerpColor(tfactor2, v5->m_skyFogColor, v7->m_skyFogColor);
    currentLight->m_shadowOpacity = DayNight::LerpColor(tfactor2, v5->m_shadowOpacity, v7->m_shadowOpacity);
    currentLight->m_sunColor = DayNight::LerpColor(tfactor2, v5->m_sunColor, v7->m_sunColor);
    currentLight->m_cloudSunColor = DayNight::LerpColor(tfactor2, v5->m_cloudSunColor, v7->m_cloudSunColor);
    currentLight->m_cloudLayer1AmbientColor = DayNight::LerpColor(
                                                tfactor2,
                                                v5->m_cloudLayer1AmbientColor,
                                                v7->m_cloudLayer1AmbientColor);
    currentLight->m_cloudEmissiveColor = DayNight::LerpColor(
                                          tfactor2,
                                          v5->m_cloudEmissiveColor,
                                          v7->m_cloudEmissiveColor);
    currentLight->m_cloudLayer2AmbientColor = DayNight::LerpColor(
                                                tfactor2,
                                                v5->m_cloudLayer2AmbientColor,
                                                v7->m_cloudLayer2AmbientColor);
    currentLight->m_oceanCloseColor = DayNight::LerpColor(tfactor2, v5->m_oceanCloseColor, v7->m_oceanCloseColor);
    currentLight->m_oceanFarColor = DayNight::LerpColor(tfactor2, v5->m_oceanFarColor, v7->m_oceanFarColor);
    currentLight->m_riverCloseColor = DayNight::LerpColor(tfactor2, v5->m_riverCloseColor, v7->m_riverCloseColor);
    currentLight->m_riverFarColor = DayNight::LerpColor(tfactor2, v5->m_riverFarColor, v7->m_riverFarColor);
    currentLight->m_fogEnd = (float)(v5->m_fogEnd + (float)((float)(v7->m_fogEnd - v5->m_fogEnd) * tfactor2))
                          * 0.027777778;
    v9 = (float)((float)(v7->m_fogScalar - v5->m_fogScalar) * tfactor2) + v5->m_fogScalar;
    currentLight->m_fogScalar = v9;
    if ( v9 < -1.0 )
    {
      LODWORD(currentLight->m_fogScalar) = -1082130432;// if fogScaler is < -1.0, set fogScaler to -1.0 and v10 to 1.0
      v10 = 1.0;
    }
    else
     {
      v10 = 1.0;
      if ( v9 > 1.0 )
        LODWORD(currentLight->m_fogScalar) = 1065353216;
    }
    LODWORD(currentLight->m_fogRate) = 1065353216;
    currentLight->m_cloudDensity = v5->m_cloudDensity
                                + (float)((float)(v7->m_cloudDensity - v5->m_cloudDensity) * tfactor2);
    currentLight->m_highlightSky = (float)(signed int)lightParamsRec->m_highlightSky;
    currentLight->m_glow = lightParamsRec->m_glow;
    currentLight->m_waterShallowAlpha = lightParamsRec->m_waterShallowAlpha;
    currentLight->m_waterDeepAlpha = lightParamsRec->m_waterDeepAlpha;
    currentLight->m_oceanShallowAlpha = lightParamsRec->m_oceanShallowAlpha;
    currentLight->m_oceanDeepAlpha = lightParamsRec->m_oceanDeepAlpha;
    v11 = v10;
    if ( !(lightParamsRec->m_flags & 1) )      // flag 1 set to off
      v11 = 0.0;
    currentLight->float7C = v11;
    currentLight->dword80 = (lightParamsRec->m_flags >> 1) & 1;// flag 2 set to on
    v12 = lightParamsRec->m_lightSkyboxID;
    currentLight->dword90 = 1065353216;
    currentLight->m_lightSkyboxID = v12;
    v13 = lightParamsRec->m_cloudTypeID;
    currentLight->dwordA8 = 1065353216;
    currentLight->m_cloudTypeID = v13;
    if ( currentLight->m_fogEnd < 10.0 )
      LODWORD(currentLight->m_fogEnd) = 1092616192;// force fog end to 10.0 if below 10.0
    if ( a1->m_info.unk_0 != 1 )                // fog enabled?
      goto LABEL_53;
     v24 = currentLight->m_fogEnd;
    if ( v24 >= 27.777779 )
    {
      v25 = this->m_info.m_cameraFarClip;
      if ( v25 < 700.0 )
        v26 = v25 - 200.0;
      else
        v26 = 500.0;
      v27 = v24 - (float)(currentLight->m_fogScalar * v24);
      if ( v27 <= v26 )
        v28 = (float)((float)(v10 - (float)(v27 / v26)) * 5.5) + 1.5;
      else
        v28 = 1.5;
      currentLight->m_fogRate = v28;
      currentLight->m_fogEnd = this->m_info.m_cameraFarClip;
    }
    if ( currentLight->m_fogScalar >= 0.0 )
    {
LABEL_53:
      result = 1;
    }
    else
    {
      LODWORD(currentLight->m_fogScalar) = 0;
      result = 1;
    }
   }
   }
   return result;
 
  currentLight->m_fogScalar = min(0.0f, currentLight->m_fogScalar);
 
   return 1;
}
}
</nowiki>
</nowiki>

Revision as of 05:54, 20 September 2016

Summary

WIP

CGameTime

CGameTime contains the logic and values necessary to determine things like: time of day progression, adjustments necessary to transform local time in to server time, etc.

CGameTime::GameTimeGetDayProgression

The GameTimeGetDayProgression function in CGameTime is frequently used in the various DayNight calculations. This function calculates the minutes since midnight in server time, and divides by the total number of minutes in a day.

The return value is a floating point that ranges from 0.0 to 1.0, measuring the distance the current server time is from midnight. 0.0 represents the time just after midnight, 0.5 represents midday, and 1.0 represents the time just before midnight.

DayNight

DayNight::InterpTable

Given a table and an interpolation factor, this function returns a value linearly interpolated out of the table. The function is commonly called in various DayNight value / color update functions.

Return values are always floating points.

Tables

Tables that are fed into DayNight::InterpTable include:

  • DayNight::s_sidnTable
  • DayNight::DNSky::s_darkTable
  • DayNight::DNSky::s_fadeTable
  • DayNight::DNStars::s_fadeTable
  • DayNight::DNClouds::s_bumpFadeTable
  • DayNight::CDayNightObjectInt::SetDirection(void)::phiTable
  • DayNight::CDayNightObjectInt::SetDirection(void)::thetaTable

Tables are structured:

struct {
  float distance_along_interpolation;
  float value_at_distance;
};

For example,

DayNight::DNStars::s_fadeTable = { {0.1250, 1.0}
                                 , {0.1875, 0.0}
                                 , {0.9375, 0.0}
                                 , {1.0000, 1.0}
                                 }

Logic

Logic WIP

DayNight::DarkenColor

Adjusts a given RGB value's brightness by a given floating point multiplier. Converts RGB to HSV, applies the multiplier to the V component, converts the adjusted HSV value back to RGB, and returns it.

Called from the various SetColors functions within DayNight.

DayNight::CDayNightObjectInt::CalcFogRate

Given a fog start distance and a fog end distance, this function uses a simple formula to calculate a fog rate. The formula makes use of a fog far clip, defined as: fogFarClip = (cameraFarClip > 700.0f) ? cameraFarClip - 200.f : 500.0f.

Note that the fog start distance fed to this function is typically computed by this formula: fogStart = fogEnd * fogScalar.

Also note that (at least from MoP+) calculating fog start from the various light DBC values uses a somewhat different formula than: fogStart = fogEnd * fogScalar.

Logic

float DayNight::CDayNightObjectInt::CalcFogRate(DayNight::CDayNightObjectInt *this, float fogStart, float fogEnd) {

  float fogRange = fogEnd - fogStart;

  float fogFarClip;

  if (this.info.cameraFarClip < 700.f) {
    fogFarClip = this.info.cameraFarClip - 200.0f;
  } else {
    fogFarClip = 500.f;
  }

  float fogRate;

  if (fogRange <= fogFarClip) {
    fogRate = ((1.0f - (fogRange / fogFarClip)) * 5.5f) + 1.5f;
  } else {
    fogRate = 1.5f;
  }

  return fogRate;

}

DayNight::CDayNightObjectInt::CalcColors

This function handles lerping / copying area light colors and parameters. Area lights are the lights defined by Light.dbc (and associated DBCs).

Logic

int DayNight::CDayNightObjectInt::CalcColors(DayNight::CDayNightObjectInt *this, int time, DayNight::CurrentLight *currentLight, LightParamsRec *lightParamsRec) {

  // Not shown: obtain the appropriate DBC entries for the start and end
  float tstart = time - t1;
  float tdiff = t2 - t1;
  float tdist = tstart / tdiff;

  // Interpolate color values 0-17 from LightData.dbc
  currentLight->m_directColor     = DayNight::LerpColor(tdist, start->m_directColor,     end->m_directColor);
  currentLight->m_ambientColor    = DayNight::LerpColor(tdist, start->m_ambientColor,    end->m_ambientColor);
  currentLight->m_skyTopColor     = DayNight::LerpColor(tdist, start->m_skyTopColor,     end->m_skyTopColor);
  currentLight->m_skyMiddleColor  = DayNight::LerpColor(tdist, start->m_skyMiddleColor,  end->m_skyMiddleColor);
  currentLight->m_skyBand1Color   = DayNight::LerpColor(tdist, start->m_skyBand1Color,   end->m_skyBand1Color);
  currentLight->m_skyBand2Color   = DayNight::LerpColor(tdist, start->m_skyBand2Color,   end->m_skyBand2Color);
  currentLight->m_skySmogColor    = DayNight::LerpColor(tdist, start->m_skySmogColor,    end->m_skySmogColor);
  currentLight->m_skyFogColor     = DayNight::LerpColor(tdist, start->m_skyFogColor,     end->m_skyFogColor);
  currentLight->m_shadowOpacity   = DayNight::LerpColor(tdist, start->m_shadowOpacity,   end->m_shadowOpacity);
  currentLight->m_sunColor        = DayNight::LerpColor(tdist, start->m_sunColor,        end->m_sunColor);
  currentLight->m_cloudSunColor   = DayNight::LerpColor(tdist, start->m_cloudSunColor,   end->m_cloudSunColor);
  currentLight->m_cloudLayer1AmbientColor = DayNight::LerpColor(tdist, start->m_cloudLayer1AmbientColor, end->m_cloudLayer1AmbientColor);
  currentLight->m_cloudEmissiveColor      = DayNight::LerpColor(tdist, start->m_cloudEmissiveColor,      end->m_cloudEmissiveColor);
  currentLight->m_cloudLayer2AmbientColor = DayNight::LerpColor(tdist, start->m_cloudLayer2AmbientColor, end->m_cloudLayer2AmbientColor);
  currentLight->m_oceanCloseColor = DayNight::LerpColor(tdist, start->m_oceanCloseColor, end->m_oceanCloseColor);
  currentLight->m_oceanFarColor   = DayNight::LerpColor(tdist, start->m_oceanFarColor,   end->m_oceanFarColor);
  currentLight->m_riverCloseColor = DayNight::LerpColor(tdist, start->m_riverCloseColor, end->m_riverCloseColor);
  currentLight->m_riverFarColor   = DayNight::LerpColor(tdist, start->m_riverFarColor,   end->m_riverFarColor);

  // Handle cloud density
  currentLight->m_cloudDensity = start->m_cloudDensity + ((end->m_cloudDensity - start->m_cloudDensity) * tdist);

  // Copy light params (these values are not interpolated)
  currentLight->m_highlightSky      = lightParamsRec->m_highlightSky;
  currentLight->m_glow              = lightParamsRec->m_glow;
  currentLight->m_waterShallowAlpha = lightParamsRec->m_waterShallowAlpha;
  currentLight->m_waterDeepAlpha    = lightParamsRec->m_waterDeepAlpha;
  currentLight->m_oceanShallowAlpha = lightParamsRec->m_oceanShallowAlpha;
  currentLight->m_oceanDeepAlpha    = lightParamsRec->m_oceanDeepAlpha;

  // Light params flag 0x01 set to off (unk?)
  if (!(lightParamsRec->m_flags & 1))
    currentLight->float7C = 0.0;
  } else {
    currentLight->float7C = 1.0;
  }

  // Light params flag 0x02 set to on (unk?)
  currentLight->dword80 = (lightParamsRec->m_flags >> 1) & 1;

  currentLight->dword90 = 1.0;
  currentLight->dwordA8 = 1.0;
  currentLight->m_lightSkyboxID = lightParamsRec->m_lightSkyboxID;
  currentLight->m_cloudTypeID = lightParamsRec->m_cloudTypeID;

  // Handle fog
  currentLight->m_fogEnd = (start->m_fogEnd + ((end->m_fogEnd - start->m_fogEnd) * tdist)) / 36.0;
  currentLight->m_fogEnd = min(10.0f, currentLight->m_fogEnd);

  currentLight->m_fogScalar = start->m_fogScalar + ((end->m_fogScalar - start->m_fogScalar) * tdist);
  currentLight->m_fogScalar = clamp(currentLight->m_fogScalar, -1.0, 1.0);

  currentLight->m_fogRate = 1.0;

  // Fog not enabled? (unk)
  if (a1->m_info.unk_0 != 1)
    return 1;

  if (currentLight->m_fogEnd >= 27.777779) {
    v25 = this->m_info.m_cameraFarClip;

    if ( v25 < 700.0 )
      v26 = v25 - 200.0;
    else
      v26 = 500.0;

    v27 = currentLight->m_fogEnd - (float)(currentLight->m_fogScalar * v24);

    if ( v27 <= v26 )
      v28 = (float)((float)(1.0f - (float)(v27 / v26)) * 5.5) + 1.5;
    else
      v28 = 1.5;

    currentLight->m_fogRate = v28;
    currentLight->m_fogEnd = this->m_info.m_cameraFarClip;
  }

  currentLight->m_fogScalar = min(0.0f, currentLight->m_fogScalar);

  return 1;
}

CShaderEffect

CShaderEffect::SetFogParams

The given fog params and fog color set up to be passed to the GPU when this function is called. Values typically or always originate from DayNight.

Logic

void CShaderEffect::SetFogParams(float fogStart, float fogEnd, float fogRate, const CArgb *fogColor, float a5) {
  if (CShaderEffect::s_enableShaders) {
    CShaderEffect::s_fogColorAlphaRef = fogColor / 255.0f;

    float fogRange = fogEnd - fogStart;


    // s_fogMul is set to 1.0 in CShaderEffect::InitShaderSystem, and does not appear to be modified elsewhere
    float fogMul = CShaderEffect::s_fogMul;

    CShaderEffect::s_fogParams.x = -(1.0f / fogRange) * fogMul;
    CShaderEffect::s_fogParams.y = (1.0f / fogRange) * fogEnd;
    CShaderEffect::s_fogParams.z = fogRate;

    // w is unknown; often forcibly set to 0.0; possibly something to do with intersecting m_liquidPlane in CM2SceneRender::SetupLighting
    CShaderEffect::s_fogParams.w = a5;
  }
}