V0 80044DC0 Current Environment Data copied from EnvironmentData[x] as variables eg FarFog=EnvironmentData[EnvironmentID].FarFog 80044E10 EnvironmentData[] //start of list A1 800450f0 EnvironmentData[8] //Dam = FarFog = BlendMult = FarFog = BlendMult f18 v1(0) sp30= ScaledBlendMult = BlendMult / Visscale f12 v1(4) sp34= ScaledFarFog = FarFog / Visscale = FarIntensity f2 a0(0)= Float fFarIntensity = FarIntensity / 1000 = NearIntensity f16 a2(0)= Float fNearIntensity = NearIntensity / 1000 f14 sp(18)= DifInFog = ScaledFarFog - ScaledBlendMult = DifInFogNear = DifInFog * fNearIntensity at(4dc4)= NearFogDist = ScaledBlendMult + DifInFogNear = DifInFogFar = DifInFog * fFarIntensity at(4dc8)= FarFogDist = ScaledBlendMult + DifInFogFar sp(18)= DifInIntesity = fNearIntensity - fFarIntensity = 128 = 0.5 sp(20)= 128 / DifInIntensity = 0.5 - fFarIntensity = 256 = (0.5 - fFarIntensity) * 256 = 1 f10 sp(1c)= ((0.5 - fFarIntensity) * 256) / DifInIntensity = -(128 / DifInIntensity) = ScaledBlendMult + 1 = (-(128 / DifInIntensity)) * ScaledFarFog = ((-(128 / DifInIntensity)) * ScaledFarFog ) * (ScaledBlendMult + 1) f8= 255 = (((-(128 / DifInIntensity)) * ScaledFarFog ) * (ScaledBlendMult + 1)) / (DifInFog) v1(10)= ((((-(128 / DifInIntensity)) * ScaledFarFog ) * (ScaledBlendMult + 1)) / (DifInFog)) / 255 = ScaledFarFog + 1 = (ScaledFarFog + 1) * (128 / DifInIntensity) = ((ScaledFarFog + 1) * (128 / DifInIntensity)) / DifInFog f4= (((ScaledFarFog + 1) * (128 / DifInIntensity)) / DifInFog) + (((0.5 - fFarIntensity) * 256) / DifInIntensity) f6 v1(14)= ((((ScaledFarFog + 1) * (128 / DifInIntensity)) / DifInFog) + (((0.5 - fFarIntensity) * 256) / DifInIntensity)) / 255 EF288 7F0BA758 sets long enviroment data (A0) as current accepts: A0=p->enviroment data EF500 7F0BA9D0 sets short enviroment data (A0) as current accepts: A0=p->enviroment data EF58C 7F0BAA5C A0->SP+0; deleted function, used at 7F0B479C accepts: A0=p->start of portal list EF594 7F0BAA64 locates and copies matching enviroment values for Level EF7D8 7F0BACA8 switch to secondary sky for Level using F12 for blend multiplier sets long enviroment entry before return accepts: F12=multplier for blend value EFBA0 7F0BB070 sets sky color and material in display list A0; returns V0=p->DL accepts: A0=p->DL EFDC8 7F0BB298 clears geometry fog flag if clouds enabled; returns V0=p->DL accepts: A0=p->DL EFDF8 7F0BB2C8 EFEC8 7F0BB398 V0= p->near fog enviroment values [800825C4] 7F0BB3A4 if sky present converts fog values; returns V0=0-2 for whatever reason accepts: A0=p->???(+18=float), A1=p->fog color target # light fixtures //snippet of ultratypes.h typedef unsigned char u8; /* unsigned 8-bit */ typedef unsigned short u16; /* unsigned 16-bit */ typedef unsigned long u32; /* unsigned 32-bit */ typedef unsigned long long u64; /* unsigned 64-bit */ //snippet of Env Struct typedef struct objEnvironmentData { u32 LevelID; float BlendMult; float FarFog; //... etc } objEnvironmentData; typedef struct objEnvironmentData2 { u32 LevelID; u8 FogRed; //... etc } objEnvironmentData2; //LevelData Struct typedef struct objLevelData { u32 LevelID; ptr pBGfile; ptr pBGstan; float LevelScale; float VisibilityScale; float unknown; } objLevelData; === Since Dam is the cause of this thought process I thought Id just post it here, however, if anyone feels it would be better split off and moved to the visibility thread I will move it. View Matrix, RSP Bounds and Level/Visibility scale: With the realisation that level scale was literally "Scale everything by Level.fScale ======= u32 Count void GetEnvironment( u32 CurrentLevelID) { //usage // objEnvironment CurrentEnv = GetEnvironment(33, false); // // Set the RDP fog color. // gDPSetFogColor(gdl++, CurrentEnv.FogRed, CurrentEnv.FogGreen, CurrentEnv.FogBlue, 0xff); // objEnvironment CurrentEnv; NumPlayers = GetNumPlayers(); //7F0BAA74 jal(7f09a94) if (NumPlayers == 1) //7F0BAA88 logically opposit to ASM but equal end result { NumPlayers = 0; } // set default enviroment (7F0BAA94) float NearFog = 340282346638528860000000000000000000000; CurrentEnv.NearFog = NearFog; NearFog = 0; //7F0BAAB4 if (isMulti == 0) //7F0BAAB0 { currentLevelCutsceneID = currentLevelID + 900 //0x384 if (!EnvironmentData[0].LevelID) { //loop for each entry to find appropriate env (7F0BAB0C) int EnvironmentID=0; while( EnvironmentData[EnvironmentID].LevelID != currentLevelCutsceneID && EnvironmentData[EnvironmentID].LevelID <> 0 ) { EnvironmentID ++; } // objEnvironment EnvironmentData[8] = Dam } else { } } return id to 7F07AB5C // } //loop for each entry to find appropriate env (7F0BAB0C) int EnvironmentID=0; do { EnvironmentID ++; } while( EnvironmentData[EnvironmentID].LevelID != CurentLevelID && EnvironmentID <= EnvironmentData.count; ); // objEnvironment EnvironmentData[8] = Dam float FarFog; float ScaledBlendMult; float ScaledFarFog; float fFarIntensity; float fNearIntensity; //copy env values to variables CurrentEnv = EnvironmentData[EnvironmentID]; // locate and copy enviroment values(7F0BA758) NearFog = EnvironmentData[EnvironmentID].NearFog; FarFog = EnvironmentData[EnvironmentID].FarFog; ScaledBlendMult = EnvironmentData[EnvironmentID].BlendMult / LevelData[CurrentLevelID].VisibilityScale //24.58538 ScaledFarFog = FarFog / LevelData[CurrentLevelID].VisibilityScale //70755.710000000000000000 fFarIntensity = EnvironmentData[EnvironmentID].FarIntensity / 1000 //=0.995 fNearIntensity = EnvironmentData[EnvironmentID].NearIntensity / 1000 //=1 DifInFog = ScaledFarFog - ScaledBlendMult //=70731.13 DifInFogNear = DifInFog * fNearIntensity //=70731.13 DifInFogFar = DifInFog * fFarIntensity //=70377.47 NearFogDist = ScaledBlendMult + DifInFogNear //=70755.71 FarFogDist = ScaledBlendMult + DifInFogFar //=70402.05 DifInIntesity = fNearIntensity - fFarIntensity somethingx = ((((-(128 / DifInIntensity)) * ScaledFarFog ) * (ScaledBlendMult + 1)) / (DifInFog)) / 255 // ((((-(128/0.005))*8192)*(20+1))/8172)/255 = 2641.7436871958768823241484552705 very odd, but its what GE gets too somethingy = ((((ScaledFarFog + 1) * (128 / DifInIntensity)) / DifInFog) + (((0.5 - fFarIntensity) * 256) / DifInIntensity)) / 255 // (((8193*(128/0.004))/8172)+(((0.5-1)*256)/0.004))/255 = 0.32247847744090293973683452823126 //copy remaining data 2 //7F0BAC84:JAL 7F0BA9D0 CurrentEnv = EnvironmentData2[EnvironmentID]; } //we are not finished, these values must be a prelude to something else //some time later 7f0bb470 -2569.467 / 1280 = -2.007396 + 1.040242 = -0.9671537 return to 7F021CD0 if r0 = v0 goto 7f022248 //false store v0(2) ==========snippet from GBI for "Standard Demo Fog" ======= /* * FOG macros * fm = z multiplier * fo = z offset * FOG FORMULA: alpha(fog) = (eyespace z) * fm + fo CLAMPED 0 to 255 * note: (eyespace z) ranges -1 to 1 * * Alternate method of setting fog: * min, max: range 0 to 1000: 0=nearplane, 1000=farplane * min is where fog begins (usually less than max and often 0) * max is where fog is thickest (usually 1000) * */ #define gSPFogFactor(pkt, fm, fo) \ gMoveWd(pkt, G_MW_FOG, G_MWO_FOG, \ (_SHIFTL(fm,16,16) | _SHIFTL(fo,0,16))) #define gsSPFogFactor(fm, fo) \ gsMoveWd(G_MW_FOG, G_MWO_FOG, \ (_SHIFTL(fm,16,16) | _SHIFTL(fo,0,16))) #define gSPFogPosition(pkt, min, max) \ gMoveWd(pkt, G_MW_FOG, G_MWO_FOG, \ (_SHIFTL((128000/((max)-(min))),16,16) | \ _SHIFTL(((500-(min))*256/((max)-(min))),0,16))) #define gsSPFogPosition(min, max) \ gsMoveWd(G_MW_FOG, G_MWO_FOG, \ (_SHIFTL((128000/((max)-(min))),16,16) | \ _SHIFTL(((500-(min))*256/((max)-(min))),0,16)))