Hi Plutonium, I added the original, not modified tod.cpp file as attachement to this post. Am 18.01.2013 11:38, schrieb Zhitao Li:
OK, Correct me if I am wrong, the second approach you described is those lines that has something to do with the "FFViperCompat.dll"? I first noticed that this dll's path is hard coded, and I don't have it, so there has to be something wrong with this, so I commented it out...
Yes!The FFViperCompat.dll was only a test by maself to proof fgetchar and fscanf work with FFViper.exe if it loads this DLL at Runtime dynamicly and NOT statically and this works! You can do all fgetchar / fscanf / ifstream stuff outside in a DLL. I named it FFViperCompat.dll to have a Wrapper Library for such type of compatibility Functions (like the Devs in the FreeBSD Operating System handles this sort of Problems).
I have another suggestion for this problem, why don't we use C++ style functions to read files? I took a brief look at the amount of work to be done going down this road, I have to say it is some amount of work, but it will make future work much easier, unless of course, it is written in C style and using some overload function was for specific reasons...
... This is what i tested forward and backward. All C++ ifsteam Operations are showing the same behavior as fgetchar and fscanf . The Code works outside in a TestDummy.exe but not inside FFViper.exe . And of cause i checked the preprocessor Settings. I removed all of them and putted them back. I tested it in and outside and everytime it is the same. Outside in a Test.exe it works, inside FFViper.exe it causes this strange behavior.
As i said. There is an Global override for all File IO Functions made by the former Microproose Devs because it looks like there was an Internal Compiler Error in the 90s and the Microproose Rrogrammers decided to do this sort of override wich redirect anything and
everything. I think this is the Problem. Peter
Thanks! Plutonium.*From:*freefalcon-developers-bounce@xxxxxxxxxxxxx [mailto:freefalcon-developers-bounce@xxxxxxxxxxxxx] *On Behalf Of *Peter Meyer*Sent:* Friday, January 18, 2013 3:30 AM *To:* freefalcon-developers@xxxxxxxxxxxxx*Subject:* [freefalcon-developers] Fwd: Re: Introduction of myself as new subscriber on the dev-listHi Plutonium, Hi all, I already got the code, and I was able to compile it with no problem.Thadts good to hear. I was not really sure it works without flaws on diffrent Computers expect of mine. This is a good sign!However, majority of the code in in C style, and it uses fopen() to open files, I am having some very weird problems with these C style functions, fopen is not working, no matter there is a file or not it returns a non-NULL pointer any way, and if I try to read the opened file with fscanf(), it gets nothing, I also tried to use fopen() to create new files, no file will be created, and check fopen() status with if(fopen(newFileAbsolutePath, "w") == NULL) {std::cout<<"open failed"<<std::endl;} it won't enter and print out anything, because the file point is not NULL, although there is no file created.Yes, you absolutly right. This is one of the Major Problems we having right now. I think there are a codeblock in the Resmgr Lib wich overrides all fopen,, scanf, fscanf, fgetchar and c++ ifstream calls to read files. The bug is described as Issue in the Bugtracker on GitHub. Awsome thadt you find this out by your self in such a short time, respect!In tod.cpp i tested out something. The fegetchar(), scanf() and ifstream Readfile Functions work outside from FFViper.exe but the same code makes the Problems you describing.After all testing i think we two choices to solve this Problem: 1)Finding the General overrides (resmgr Subproject in the FreeFalcon Solution) . i think this might be a critical Codeblock because it looks like any scanf and fegetchar and even ifstream acess uses it) - But of cause this would be the best Solution at all.2)I have created a little DLL wich is not statically linked (if you use it statically it shows the same behaviour wich suckz) but if you load it with Loadlib() as dynamic loading at Runtime, the fegetchar, scanf/fscanf and ifstream read functions works like expected. I will checkin my FFViper.dll Teststub Project so we can evaluatewich would be the best way to solve this issue.If iam wrong and you find something else whats causes the Problem, let me know, but for now i think this is the Situation.If anyone can give some idea, what's causing this problem, please help. I also created another x86 and x64 VS2010 project to test the fopen() function, it works fine in those test projects.Hahah, this was the same as i did myself - you welcome ;D Thanks! Greetings, Peter Plutonium*From:*freefalcon-developers-bounce@xxxxxxxxxxxxx <mailto:freefalcon-developers-bounce@xxxxxxxxxxxxx> [mailto:freefalcon-developers-bounce@xxxxxxxxxxxxx] *On Behalf Of *Mark Tigelaar*Sent:* Friday, January 18, 2013 2:56 AM*To:* freefalcon-developers@xxxxxxxxxxxxx <mailto:freefalcon-developers@xxxxxxxxxxxxx> *Subject:* [freefalcon-developers] Re: Introduction of myself as new subscriber on the dev-list------------------------------------------------------------------------ Date: Fri, 18 Jan 2013 10:45:01 +0100 From: pmvstrm@xxxxxxxx <mailto:pmvstrm@xxxxxxxx>To: freefalcon-developers@xxxxxxxxxxxxx <mailto:freefalcon-developers@xxxxxxxxxxxxx> Subject: [freefalcon-developers] Re: Introduction of myself as new subscriber on the dev-listHi Mark, and welcome on the developer list. You have done anything right. If you read this, just click reply thadts all. ps: Tell us a bit about your Ideads for FreeFalcon Greetings Peter. Am 18.01.2013 10:41, schrieb Mark Tigelaar: Hi all, After contacting Peter on possibilities for future work on the amazing FreeFalcon version of F4, he pointed me in the direction of the freelists.org where freefalcon-developers is the list for the dev-team. At least I hope I understood this correct. I did subscribe on the freelists.org but , probably because of having no rights to see anything, I found noone to get in touch with, or to introduce myself. So, I hope I can get this sorted with this email. Hope to hear from you guys soon (with instructions what the following steps are) High regards, Mark
/***************************************************************************\ Tod.cpp ? ? JAM 08Jan04 - Begin Major Rewrite. \***************************************************************************/ #include <stdio.h> #include <string.h> #include <math.h> #include <time.h> #include "grmath.h" #include "grinline.h" #include "PalBank.h" #include "TimeMgr.h" #include "RViewpnt.h" #include "RenderOW.h" #include "tod.h" #include "Falclib/include/openfile.h" #include "Falclib/include/PlayerOp.h" #include "Star.h" #include "RealWeather.h" #pragma warning (disable : 4127) CStar TheStar; // The one and only time manager CTimeOfDay TheTimeOfDay; extern float g_fLatitude; // JB 010804 extern SkyColorDataType* skycolor; // size of sun glare area = 22.5 deg static const int SUN_GLARE_SIZE = 1024; unsigned char CTimeOfDay::MoonPhaseMask[8*64]; unsigned char CTimeOfDay::CurrentMoonPhaseMask[8*64]; void CTimeOfDay::Setup( char *dataPath ) { char todfile[_MAX_PATH]; char starfile[_MAX_PATH]; FILE *in; ShiAssert( !IsReady() ); // Construct the input filename we need // if (skycolor) // sprintf( todfile, "%s\\tod\\%s", dataPath, skycolor[PlayerOptions.skycol-1].todname); sprintf( starfile, "%s\\star.dat", dataPath ); // if (!skycolor || !(in=fopen(todfile,"r"))) // Oops, the todfile is not there ? Use default one // { // sprintf( todfile, "%s\\tod\\tod.lst.default", dataPath); // if (!(in=fopen(todfile,"r"))) // Oops, the todfile is not there ? Use default one // sprintf( todfile, "%s\\tod.lst", dataPath); // else // fclose(in); // } // else // fclose(in); sprintf(todfile,"%s\\tod.lst",dataPath); in = FILE_Open (todfile, "r"); if (in == NULL) { //char string[256]; //sprintf( string, "TOD file open failed: %s", todfile ); //ShiError( string ); // We need to exit gracefully return; } TimeOfDayStruct temptod; TotalTimeOfDay = ReadTODFile (in, &temptod, 1); if (!TotalTimeOfDay) { fclose (in); char string[256]; sprintf( string, "No data obtained from TOD file: %s", todfile ); ShiError( string ); } TimeOfDay = new TimeOfDayStruct[TotalTimeOfDay]; if (!TimeOfDay) { fclose (in); ShiError( "Failed TOD memory allocation" ); } fseek (in, 0, 0); ISunYaw = IMoonYaw = 4096; ISunTilt = IMoonTilt = 0; HazeSunriseColor.r = 1.0f; HazeSunriseColor.g = 0.6f; HazeSunriseColor.b = 0.1f; HazeSunsetColor.r = 1.0f; HazeSunsetColor.g = 0.6f; HazeSunsetColor.b = 0.1f; Flag = 0; ReadTODFile (in, TimeOfDay-1); fclose (in); SetVar (TimeOfDay); //////////////// if (TheStar.Setup (starfile, 11.0f)) { // load all stars with magnitude less than 11 //ShiError ("Failed Loading Star"); // We nead to exit cleanly? } TheStarData = TheStar.GetStarData(); TheStar.SetHorizon ((float) degtorad(5), (float) degtorad(15)); // display stars with elevation > horizon // M.N. changed back from theater.map readout. It seems that the sun position is normalized to korean latitude, // so no need to change it at all... TheStar.SetLocation (g_fLatitude, 0.0f); // latitude, longitude /* struct tm *newtime; long ltime; time( <ime ); newtime = gmtime( <ime ); TheStar.SetDate (newtime -> tm_mday, newtime -> tm_mon + 1, newtime -> tm_year + 1900); */ int year = TheTimeManager.GetYearAD(); int extraday = TheTimeManager.GetDayOfYear(); int month = 1; int day = 0; TheStar.CalculateDate (&day, &month, &year, extraday); TheStar.SetDate (day, month, year); lastMoonTime = 0; MoonPhase = -1; //////////////////// int i, j; for (i=0; i < TotalTimeOfDay;i++) { j = i + 1; if (j >= TotalTimeOfDay) j = 0; if (!(TimeOfDay[j].Flag & GL_TIME_OF_DAY_USE_SUN)) TimeOfDay[i].Flag &= ~GL_TIME_OF_DAY_USE_SUN; if (!(TimeOfDay[j].Flag & GL_TIME_OF_DAY_USE_MOON)) TimeOfDay[i].Flag &= ~GL_TIME_OF_DAY_USE_MOON; int k = 0; if (TimeOfDay[i].StarIntensity > 0.0f) k = 1; else if (TimeOfDay[j].StarIntensity > 0.0f) k = 1; if (k) TimeOfDay[i].Flag |= GL_TIME_OF_DAY_USE_STAR; } // Default lighting conditions Ambient = .3f; Diffuse = .6f; Specular = .8f; // default glare angle is 22.5 deg SetSunGlareAngle (1024); // Start with NVGs off NVGmode = FALSE; // Initialize the lighting conditions and register for future time of day updates TimeUpdateCallback(this); TheTimeManager.RegisterTimeUpdateCB(TimeUpdateCallback,this); } void CTimeOfDay::Cleanup() { ShiAssert( IsReady() ); // Stop receiving time updates TheTimeManager.ReleaseTimeUpdateCB(TimeUpdateCallback,this); // Clean up and release the start position data TheStar.Cleanup (); // Clean up and release the time of data transition data delete[] TimeOfDay; TimeOfDay = NULL; } void CTimeOfDay::SetNVGmode(BOOL state) { NVGmode = state; /* Tcolor paletteEffect; int id; // Convert all the object texture palettes appropriatly paletteEffect.g = 1.0f; if (NVGmode) { paletteEffect.r = 0.0f; paletteEffect.b = 0.0f; } else { paletteEffect.r = 1.0f; paletteEffect.b = 1.0f; } for (id=0; ThePaletteBank.IsValidIndex( id ); id++) { ThePaletteBank.LightPalette( id, &paletteEffect ); } */ // Force a lighting refresh to reflect the changes TheTimeManager.Refresh(); } // Update the sky colors and sun/moon position based on the current time of day void CTimeOfDay::TimeUpdateCallback(void *self) { ((CTimeOfDay*)self)->UpdateSkyProperties(); } void CTimeOfDay::UpdateSkyProperties() { int i, c, n; TimeOfDayStruct *tod, *ntod; unsigned now; float t; // Convert from time since clock start to time since midnight now = TheTimeManager.GetTimeOfDay(); unsigned curtime = TheTimeManager.GetClockTime(); TheStar.SetUniversalTime( curtime ); if (curtime) { if (lastMoonTime == 0 || lastMoonTime > curtime || ((curtime - lastMoonTime) > 60*60*1000)) { lastMoonTime = curtime; MoonPhase = -1; MoonPhase = CalculateMoonPercent(); CreateMoonPhaseMask(MoonPhaseMask, MoonPhase); } } // Identify the Current time step in the TOD table for (i=0; i < TotalTimeOfDay;i++) { if (TimeOfDay[i].Time > now) break; } if (i == 0) c = TotalTimeOfDay - 1; else if (i >= TotalTimeOfDay) c = TotalTimeOfDay - 1; else c = i - 1; // Identify the Next time step in the TOD table n = c + 1; if (n >= TotalTimeOfDay) n = 0; // This should only happen if the table has less than two entries if (c == n) return; // Get pointers to the current and next TOD table entries tod = &(TimeOfDay[c]); ntod = &(TimeOfDay[n]); // No two table entries should have the same time stamp c = tod -> Time; n = ntod -> Time; ShiAssert( c != n ); // Calculate the time between the two table entries if (n < c) n += MSEC_PER_DAY; n -= c; // Calculate the time between now and the current table entry if (now < (DWORD)c) now += MSEC_PER_DAY; c = now - c; // Calculate the interpolation control variable "t" t = (float) c / (float) n; // Set all our variable from the first record SetVar(tod); // Add in deltas toward the second record m_SkyColor.r += t * (ntod -> SkyColor.r - m_SkyColor.r); m_SkyColor.g += t * (ntod -> SkyColor.g - m_SkyColor.g); m_SkyColor.b += t * (ntod -> SkyColor.b - m_SkyColor.b); m_HazeSkyColor.r += t * (ntod -> HazeSkyColor.r - m_HazeSkyColor.r); m_HazeSkyColor.g += t * (ntod -> HazeSkyColor.g - m_HazeSkyColor.g); m_HazeSkyColor.b += t * (ntod -> HazeSkyColor.b - m_HazeSkyColor.b); m_GroundColor.r += t * (ntod -> GroundColor.r - m_GroundColor.r); m_GroundColor.g += t * (ntod -> GroundColor.g - m_GroundColor.g); m_GroundColor.b += t * (ntod -> GroundColor.b - m_GroundColor.b); m_HazeGroundColor.r += t * (ntod -> HazeGroundColor.r - m_HazeGroundColor.r); m_HazeGroundColor.g += t * (ntod -> HazeGroundColor.g - m_HazeGroundColor.g); m_HazeGroundColor.b += t * (ntod -> HazeGroundColor.b - m_HazeGroundColor.b); m_TextureLighting.r += t * (ntod -> TextureLighting.r - m_TextureLighting.r); m_TextureLighting.g += t * (ntod -> TextureLighting.g - m_TextureLighting.g); m_TextureLighting.b += t * (ntod -> TextureLighting.b - m_TextureLighting.b); m_BadWeatherLighting.r += t * (ntod -> BadWeatherLighting.r - m_BadWeatherLighting.r); m_BadWeatherLighting.g += t * (ntod -> BadWeatherLighting.g - m_BadWeatherLighting.g); m_BadWeatherLighting.b += t * (ntod -> BadWeatherLighting.b - m_BadWeatherLighting.b); m_VisColor.r += t * (ntod -> VisColor.r - m_VisColor.r); m_VisColor.g += t * (ntod -> VisColor.g - m_VisColor.g); m_VisColor.b += t * (ntod -> VisColor.b - m_VisColor.b); Tcolor Color; Color = tod->RainColor; Color.r += t * (ntod -> RainColor.r - tod->RainColor.r); Color.g += t * (ntod -> RainColor.g - tod->RainColor.g); Color.b += t * (ntod -> RainColor.b - tod->RainColor.b); RainColor = MakeColor(&Color); Color = tod->SnowColor; Color.r += t * (ntod -> SnowColor.r - tod->SnowColor.r); Color.g += t * (ntod -> SnowColor.g - tod->SnowColor.g); Color.b += t * (ntod -> SnowColor.b - tod->SnowColor.b); SnowColor = MakeColor(&Color); LightningColor.r += t * (ntod -> LightningColor.r - tod->LightningColor.r); LightningColor.g += t * (ntod -> LightningColor.g - tod->LightningColor.g); LightningColor.b += t * (ntod -> LightningColor.b - tod->LightningColor.b); m_Ambient += t * (ntod -> Ambient - m_Ambient); m_Diffuse += t * (ntod -> Diffuse - m_Diffuse); m_Specular += t * (ntod -> Specular - m_Specular); m_MinVis += t * (ntod -> MinVis - m_MinVis); float ra, dec, az, alt; TheStar.GetSunRaDec (&ra, &dec); TheStar.ConvertPosition (ra, dec, &az, &alt); TheStar.SetSunPosition (az, alt); TheStar.ConvertCoord (ra, dec, &SunCoord.x, &SunCoord.y, &SunCoord.z); ISunYaw = FloatToInt32 (radtoangle(az)); ISunPitch = FloatToInt32 (radtoangle(alt)); TheStar.GetMoonRaDec (&ra, &dec); TheStar.ConvertPosition (ra, dec, &az, &alt); TheStar.SetMoonPosition (az, alt); TheStar.ConvertCoord (ra, dec, &MoonCoord.x, &MoonCoord.y, &MoonCoord.z); IMoonYaw = FloatToInt32 (radtoangle(az)); IMoonPitch = FloatToInt32 (radtoangle(alt)); if(ISunPitch < 256 || ISunPitch > (8192-256)) { // Adjust the light level for the moon // (original levels are assumed to have been for a full moon) // At new moon and/or moon rise/set, we darken by at most 1/2 // (at little more, actually, since the SIN can become negative just as the moon sets/rises) float t1 = (float) abs(NEW_MOON_PHASE - CalculateMoonPercent()); t1 = (t1 / NEW_MOON_PHASE) * (float)sin(alt);//angletorad(IMoonPitch)); t1 = (1.0f + t1)/2.0f; if (t1 < 0.45f) t1 = 0.45f; // limit the darkness level m_HazeGroundColor.r *= t1; m_HazeGroundColor.g *= t1; m_HazeGroundColor.b *= t1; m_TextureLighting.r *= t1; m_TextureLighting.g *= t1; m_TextureLighting.b *= t1; m_BadWeatherLighting.r *= t1; m_BadWeatherLighting.g *= t1; m_BadWeatherLighting.b *= t1; m_Ambient *= t1; m_Diffuse *= t1; m_Specular *= t1; } // Update the positions and effects of the celstial objects m_StarIntensity += t * (ntod -> StarIntensity - m_StarIntensity); TheStar.UpdateStar(); /* if(realWeather->weatherCondition > FAIR) { if(realWeather->weatherCondition == INCLEMENT) { BadWeatherLighting.r = max(BadWeatherLighting.r/1.5f,0.01f); BadWeatherLighting.g = max(BadWeatherLighting.g/1.5f,0.01f); BadWeatherLighting.b = max(BadWeatherLighting.b/1.5f,0.01f); } if(realWeather->InsideOvercast() || realWeather->UnderOvercast()) { if(realWeather->weatherCondition > POOR) Specular = 0.f; else Specular *= 0.2f; SkyColor.r = BadWeatherLighting.r/max((1.25f*scaleFactor),1.f); SkyColor.g = BadWeatherLighting.g/max((1.25f*scaleFactor),1.f); SkyColor.b = BadWeatherLighting.b/max((1.25f*scaleFactor),1.f); HazeSkyColor.r = BadWeatherLighting.r/max((1.25f*scaleFactor),1.f); HazeSkyColor.g = BadWeatherLighting.g/max((1.25f*scaleFactor),1.f); HazeSkyColor.b = BadWeatherLighting.b/max((1.25f*scaleFactor),1.f); HazeGroundColor.r = BadWeatherLighting.r/max((1.25f*scaleFactor),1.f); HazeGroundColor.g = BadWeatherLighting.g/max((1.25f*scaleFactor),1.f); HazeGroundColor.b = BadWeatherLighting.b/max((1.25f*scaleFactor),1.f); GroundColor.r = BadWeatherLighting.r/max((1.25f*scaleFactor),1.f); GroundColor.g = BadWeatherLighting.g/max((1.25f*scaleFactor),1.f); GroundColor.b = BadWeatherLighting.b/max((1.25f*scaleFactor),1.f); TextureLighting.r = BadWeatherLighting.r/max((1.25f*scaleFactor),1.f); TextureLighting.g = BadWeatherLighting.g/max((1.25f*scaleFactor),1.f); TextureLighting.b = BadWeatherLighting.b/max((1.25f*scaleFactor),1.f); } else { SkyColor.r = (SkyColor.r*(1.f - scaleFactor))+(BadWeatherLighting.r*scaleFactor); SkyColor.g = (SkyColor.g*(1.f - scaleFactor))+(BadWeatherLighting.g*scaleFactor); SkyColor.b = (SkyColor.b*(1.f - scaleFactor))+(BadWeatherLighting.b*scaleFactor); HazeSkyColor.r = min(BadWeatherLighting.r/max((1.25f*scaleFactor),.67f),.9f); HazeSkyColor.g = min(BadWeatherLighting.g/max((1.25f*scaleFactor),.67f),.9f); HazeSkyColor.b = min(BadWeatherLighting.b/max((1.25f*scaleFactor),.67f),.9f); HazeGroundColor.r = min(BadWeatherLighting.r/max((1.25f*scaleFactor),.67f),.9f); HazeGroundColor.g = min(BadWeatherLighting.g/max((1.25f*scaleFactor),.67f),.9f); HazeGroundColor.b = min(BadWeatherLighting.b/max((1.25f*scaleFactor),.67f),.9f); GroundColor.r = min(BadWeatherLighting.r/max((1.25f*scaleFactor),.67f),.9f); GroundColor.g = min(BadWeatherLighting.g/max((1.25f*scaleFactor),.67f),.9f); GroundColor.b = min(BadWeatherLighting.b/max((1.25f*scaleFactor),.67f),.9f); TextureLighting.r = min(BadWeatherLighting.r/max((1.25f*scaleFactor),.67f),.9f); TextureLighting.g = min(BadWeatherLighting.g/max((1.25f*scaleFactor),.67f),.9f); TextureLighting.b = min(BadWeatherLighting.b/max((1.25f*scaleFactor),.67f),.9f); } Diffuse /= max((2.f*scaleFactor),1.f); }*/ } // RED - Tihs function calculates Sky colors based on weather Conditions void CTimeOfDay::UpdateWeatherColors(DWORD weatherCondition) { // default values StarIntensity = m_StarIntensity; MinVis = m_MinVis; VisColor = m_VisColor; Ambient = m_Ambient; Specular = m_Specular; // Deafule values if nont under/inside an overcast layer if(weatherCondition <= FAIR){ SkyColor = m_SkyColor; HazeSkyColor = m_HazeSkyColor; GroundColor = m_GroundColor; HazeGroundColor = m_HazeGroundColor; TextureLighting = m_TextureLighting; BadWeatherLighting = m_BadWeatherLighting; Diffuse = m_Diffuse; } else { Diffuse = m_Diffuse / max((2.f*scaleFactor),1.f); // Bad weather stuff if(weatherCondition == INCLEMENT){ BadWeatherLighting.r = max(m_BadWeatherLighting.r/1.5f,0.01f); BadWeatherLighting.g = max(m_BadWeatherLighting.g/1.5f,0.01f); BadWeatherLighting.b = max(m_BadWeatherLighting.b/1.5f,0.01f); } else { BadWeatherLighting.r = m_BadWeatherLighting.r; BadWeatherLighting.g = m_BadWeatherLighting.g; BadWeatherLighting.b = m_BadWeatherLighting.b; } if(realWeather->InsideOvercast() || realWeather->UnderOvercast()){ if(realWeather->weatherCondition > POOR) Specular = 0.f; else Specular *= 0.2f; SkyColor.r = BadWeatherLighting.r/max((1.25f*scaleFactor),1.f); SkyColor.g = BadWeatherLighting.g/max((1.25f*scaleFactor),1.f); SkyColor.b = BadWeatherLighting.b/max((1.25f*scaleFactor),1.f); HazeSkyColor.r = BadWeatherLighting.r/max((1.25f*scaleFactor),1.f); HazeSkyColor.g = BadWeatherLighting.g/max((1.25f*scaleFactor),1.f); HazeSkyColor.b = BadWeatherLighting.b/max((1.25f*scaleFactor),1.f); HazeGroundColor.r = BadWeatherLighting.r/max((1.25f*scaleFactor),1.f); HazeGroundColor.g = BadWeatherLighting.g/max((1.25f*scaleFactor),1.f); HazeGroundColor.b = BadWeatherLighting.b/max((1.25f*scaleFactor),1.f); GroundColor.r = BadWeatherLighting.r/max((1.25f*scaleFactor),1.f); GroundColor.g = BadWeatherLighting.g/max((1.25f*scaleFactor),1.f); GroundColor.b = BadWeatherLighting.b/max((1.25f*scaleFactor),1.f); TextureLighting.r = BadWeatherLighting.r/max((1.25f*scaleFactor),1.f); TextureLighting.g = BadWeatherLighting.g/max((1.25f*scaleFactor),1.f); TextureLighting.b = BadWeatherLighting.b/max((1.25f*scaleFactor),1.f); } else { SkyColor.r = (m_SkyColor.r*(1.f - scaleFactor))+(BadWeatherLighting.r*scaleFactor); SkyColor.g = (m_SkyColor.g*(1.f - scaleFactor))+(BadWeatherLighting.g*scaleFactor); SkyColor.b = (m_SkyColor.b*(1.f - scaleFactor))+(BadWeatherLighting.b*scaleFactor); HazeSkyColor.r = min(BadWeatherLighting.r/max((1.25f*scaleFactor),.67f),.9f); HazeSkyColor.g = min(BadWeatherLighting.g/max((1.25f*scaleFactor),.67f),.9f); HazeSkyColor.b = min(BadWeatherLighting.b/max((1.25f*scaleFactor),.67f),.9f); HazeGroundColor.r = min(BadWeatherLighting.r/max((1.25f*scaleFactor),.67f),.9f); HazeGroundColor.g = min(BadWeatherLighting.g/max((1.25f*scaleFactor),.67f),.9f); HazeGroundColor.b = min(BadWeatherLighting.b/max((1.25f*scaleFactor),.67f),.9f); GroundColor.r = min(BadWeatherLighting.r/max((1.25f*scaleFactor),.67f),.9f); GroundColor.g = min(BadWeatherLighting.g/max((1.25f*scaleFactor),.67f),.9f); GroundColor.b = min(BadWeatherLighting.b/max((1.25f*scaleFactor),.67f),.9f); TextureLighting.r = min(BadWeatherLighting.r/max((1.25f*scaleFactor),.67f),.9f); TextureLighting.g = min(BadWeatherLighting.g/max((1.25f*scaleFactor),.67f),.9f); TextureLighting.b = min(BadWeatherLighting.b/max((1.25f*scaleFactor),.67f),.9f); } } } void CTimeOfDay::CalculateSunGroundPos (Tpoint *pos) { pos -> x = SunCoord.x; pos -> y = SunCoord.y; pos -> z = 0.0f; } // Return point on unit sphere at center of sun/moon void CTimeOfDay::CalculateSunMoonPos (Tpoint *pos, int ismoon) { if (ismoon) *pos = MoonCoord; else *pos = SunCoord; } // Return the unit vector TOWARD the light source // (Remember, X is north, Y is east, and Z is down) void CTimeOfDay::GetLightDirection( Tpoint *LightDirection ) { float sH, cH, sC, cC; ShiAssert( LightDirection ); // See if the sun is up if ( ThereIsASun() ) { glGetSinCos (&sH, &cH, ISunYaw); glGetSinCos (&sC, &cC, ISunPitch); } else if ( ThereIsAMoon() ) { glGetSinCos (&sH, &cH, IMoonYaw); glGetSinCos (&sC, &cC, IMoonPitch); } else { cC = 0.0f; sC = 1.0f; cH = 0.0F; sH = 0.0F; } LightDirection->x = cC * cH; LightDirection->y = cC * sH; LightDirection->z = -sC; } void CTimeOfDay::SetVar(TimeOfDayStruct *tod) { m_SkyColor = tod ->SkyColor; m_HazeSkyColor = tod ->HazeSkyColor; m_GroundColor = tod ->GroundColor; m_HazeGroundColor = tod ->HazeGroundColor; m_TextureLighting = tod ->TextureLighting; m_BadWeatherLighting = tod ->BadWeatherLighting; m_Ambient = tod ->Ambient; m_Diffuse = tod ->Diffuse; m_Specular = tod ->Specular; Flag = tod -> Flag; m_StarIntensity = tod -> StarIntensity; RainColor = MakeColor(&tod->RainColor); SnowColor = MakeColor(&tod->SnowColor); LightningColor = tod->LightningColor; m_MinVis = tod->MinVis; m_VisColor = tod->VisColor; } void CTimeOfDay::SetDefaultColor(Tcolor *col, Tcolor *defcol) { if (col->r ==-1) *col = *defcol; } int CTimeOfDay::ReadTODFile (FILE *in, TimeOfDayStruct *tod, int countflag) { float fvar; int total; char buffer[80]; total = 0; while (1) { fscanf (in, "%s", buffer); strupr (buffer); if (strcmp( buffer, "ZZZZ" ) == 0) { SetDefaultColor(&tod->RainColor, &tod->HazeGroundColor); SetDefaultColor(&tod->SnowColor, &tod->HazeGroundColor); SetDefaultColor(&tod->VisColor, &tod->HazeSkyColor); break; } else if (strcmp( buffer, "TIME" ) == 0) { DWORD ivar1, ivar2, ivar3; if (total != 0) { SetDefaultColor(&tod->RainColor, &tod->HazeGroundColor); SetDefaultColor(&tod->SnowColor, &tod->HazeGroundColor); SetDefaultColor(&tod->VisColor, &tod->HazeSkyColor); } total++; if (!countflag) tod++; fscanf (in, "%ld:%ld:%ld", &ivar1, &ivar2, &ivar3); ivar1 *= 3600000; ivar2 *= 60000; ivar3 *= 1000; tod -> Time = ivar1 + ivar2 + ivar3; tod -> Flag = 0; tod -> StarIntensity = 0.0f; tod->LightningColor.r = tod->LightningColor.g = 1; tod->LightningColor.b = 0; tod->RainColor.r = tod->RainColor.g = tod->RainColor.b = 1; tod->SnowColor.r = tod->SnowColor.g = tod->SnowColor.b = 1; tod->VisColor.r = tod->VisColor.g = tod->VisColor.b = -1; tod->MinVis = 0.1f; } else if (strcmp( buffer, "SUNTILT" ) == 0) { fscanf (in, "%f", &fvar); ISunTilt = glConvertFromDegree(fvar); } else if (strcmp (buffer, "MOONTILT") == 0) { fscanf (in, "%f", &fvar); IMoonTilt = glConvertFromDegree(fvar); } //---- ignore these ---- else if (strcmp( buffer, "SUNYAW" ) == 0) { fscanf (in, "%f", &fvar); } else if (strcmp (buffer, "MOONYAW") == 0) { fscanf (in, "%f", &fvar); } //---------------------- else if (strcmp (buffer, "HAZESUNSETCOLOR") == 0) { fscanf (in, "%f %f %f", &HazeSunsetColor.r, &HazeSunsetColor.g, &HazeSunsetColor.b); } else if (strcmp (buffer, "HAZESUNRISECOLOR") == 0) { fscanf (in, "%f %f %f", &HazeSunriseColor.r, &HazeSunriseColor.g, &HazeSunriseColor.b); } else if (strcmp (buffer, "SKYCOLOR") == 0) { fscanf (in, "%f %f %f", &tod -> SkyColor.r, &tod -> SkyColor.g, &tod -> SkyColor.b); } else if (strcmp (buffer, "HAZESKYCOLOR") == 0) { fscanf (in, "%f %f %f", &tod -> HazeSkyColor.r, &tod -> HazeSkyColor.g, &tod -> HazeSkyColor.b); } else if (strcmp (buffer, "GROUNDCOLOR") == 0) { fscanf (in, "%f %f %f", &tod -> GroundColor.r, &tod -> GroundColor.g, &tod -> GroundColor.b); } else if (strcmp (buffer, "HAZEGROUNDCOLOR") == 0) { fscanf (in, "%f %f %f", &tod -> HazeGroundColor.r, &tod -> HazeGroundColor.g, &tod -> HazeGroundColor.b); tod -> HazeGroundColor.r *= 0.7f; tod -> HazeGroundColor.g *= 0.7f; tod -> HazeGroundColor.b *= 0.7f; } else if (strcmp (buffer, "TEXTURELIGHTING") == 0) { fscanf (in, "%f %f %f", &tod -> TextureLighting.r, &tod -> TextureLighting.g, &tod -> TextureLighting.b); } else if (strcmp (buffer, "BADWEATHERLIGHTING") == 0) { fscanf (in, "%f %f %f", &tod -> BadWeatherLighting.r, &tod -> BadWeatherLighting.g, &tod -> BadWeatherLighting.b); } // else if (strcmp (buffer, "LIGHTNINGCOLOR") == 0) { // fscanf (in, "%f %f %f", &tod ->LightningColor.r, &tod ->LightningColor.g, &tod ->LightningColor.b); // } else if (strcmp (buffer, "AMBIENT") == 0) { fscanf (in, "%f", &tod -> Ambient); } else if (strcmp (buffer, "DIFFUSE") == 0) { fscanf (in, "%f", &tod -> Diffuse); } else if (strcmp (buffer, "SPECULAR") == 0) { fscanf (in, "%f", &tod ->Specular); } else if (strcmp (buffer, "SUNPITCH") == 0) { fscanf (in, "%f", &tod -> SunPitch); tod -> SunPitch = glConvertFromDegreef (tod -> SunPitch); tod -> Flag |= GL_TIME_OF_DAY_USE_SUN; } else if (strcmp (buffer, "MOONPITCH") == 0) { fscanf (in, "%f", &tod -> MoonPitch); tod -> MoonPitch = glConvertFromDegreef (tod -> MoonPitch); tod -> Flag |= GL_TIME_OF_DAY_USE_MOON; } else if (strcmp (buffer, "STAR") == 0) { tod -> StarIntensity = 1.0f; } // JPO additions else if (strcmp (buffer, "RAINCOLOR") == 0) { fscanf (in, "%f %f %f", &tod ->RainColor.r, &tod ->RainColor.g, &tod ->RainColor.b); } else if (strcmp (buffer, "SNOWCOLOR") == 0) { fscanf (in, "%f %f %f", &tod ->SnowColor.r, &tod ->SnowColor.g, &tod ->SnowColor.b); } else if (strcmp (buffer, "MINVISIBILITY") == 0) { fscanf (in, "%f", &tod->MinVis); } else if (strcmp (buffer, "VISCOLOR") == 0) { fscanf (in, "%f %f %f", &tod ->VisColor.r, &tod ->VisColor.g, &tod ->VisColor.b); } else { //MonoPrint("Ignoring TOD item %s\n", buffer); } } return total; } // angle must be between 0 and 90 void CTimeOfDay::SetSunGlareAngle (int angle) { SunGlareCosine = (float) glGetCosine (angle); SunGlareFactor = 1.0f / (1.0f - SunGlareCosine); } float CTimeOfDay::GetSunGlare (int yaw, int pitch) { // TODO: Instead of all this, just do a dot product with the light vector... int pitch1 = GetSunPitch(); int yaw1 = GetSunYaw(); float sin1, sin2, cos1, cos2, cos3; glGetSinCos (&sin1, &cos1, pitch); glGetSinCos (&sin2, &cos2, pitch1); cos3 = (float) glGetCosine (yaw - yaw1); float alpha = sin1 * sin2 + cos1 * cos2 * cos3; alpha -= SunGlareCosine; alpha *= SunGlareFactor; // just to make sure, clamp value if (alpha > 1.0f) alpha = 1.0f; else if (alpha < 0.0f) alpha = 0.0f; return alpha; } // return 1 if don't need to blend moon, else return moon blend value float CTimeOfDay::CalculateMoonBlend (float glare) { if (IMoonPitch < 0) return 1.0f; float alpha = 0.0f; if (ISunPitch >= 0) { int pitch = GetMoonPitch(); int yaw = GetMoonYaw(); int pitch1 = GetSunPitch(); int yaw1 = GetSunYaw(); float sin1, sin2, cos1, cos2, cos3; glGetSinCos (&sin1, &cos1, pitch); glGetSinCos (&sin2, &cos2, pitch1); cos3 = (float) glGetCosine (yaw - yaw1); alpha = sin1 * sin2 + cos1 * cos2 * cos3; alpha -= SunGlareCosine; alpha *= SunGlareFactor; if (alpha > 1.0f) alpha = 1.0f; else if (alpha < 0.0f) alpha = 0.0f; if (sin2 > 0.0f) { //sin2 *= 4.0f; alpha += sin2; } } if (glare < 0.0f) glare = 0.0f; else if (glare > 1.0f) glare = 1.0f; alpha = 1.0f - (alpha + glare); if (alpha < 0.0f) alpha = 0.0f; else if (alpha > 1.0f) alpha = 1.0f; return alpha; } int CTimeOfDay::CalculateMoonPercent(void) { if (MoonPhase == -1) MoonPhase = FloatToInt32(TheStar.GetMoonPhase() * MOON_PHASE_SIZE); return MoonPhase; } void CTimeOfDay::CreateMoonPhaseMask (unsigned char *image, int phase) { if (phase == NEW_MOON_PHASE) // new moon --> all moon dark memset ((void *) image, 0, 8*64); else { // part of moon dark int array[64]; int reverse = 0; int sizex = NEW_MOON_PHASE/2 - phase; if (phase > NEW_MOON_PHASE) { sizex += NEW_MOON_PHASE; reverse = 1; } int counter = 0; int flag = 1; int x = 0; int y = 32; int xpos = 32; float aa = (float) sizex * sizex; float bb = (float) 32 * 32; float d1 = bb - aa*32 + aa / 4.0f; while (aa * ((float) y - 0.5f) > bb * ((float) x + 1.0f)) { if (d1 < 0.0f) { d1 += bb * ((float) (x << 1) + 3.0f); x++; xpos++; } else { if (flag) { array[counter++] = xpos; flag = 0; } d1 += bb * ((float) (x << 1) + 3.0f) + aa * ((float) (-y << 1) + 2.0f); x++; xpos++; y--; array[counter++] = xpos; } } float x1 = (float) x + 0.5f; float y1 = (float) y - 1.0f; float d2 = bb * x1*x1 + aa * y1*y1 - aa*bb; while (y > 0) { if (d2 < 0.0f) { if (flag) { array[counter++] = xpos; flag = 0; } d2 += bb * ((float) (x << 1) + 2.0f) + aa * ((float) (-y << 1) + 3.0f); x++; xpos++; y--; } else { d2 += aa * ((float) (-y << 1) + 3.0f); y--; } array[counter++] = xpos; } int j; for (j=0; j < 32;j++) array[63-j] = array[j]; if (sizex < 0) { for (j=0; j < 64;j++) array[j] = 64 - array[j]; } int row, col, col1; int start, stop; unsigned char *dest = image; for (row=0; row < 64; row++) { if (reverse) { start = 0; stop = array[row]; } else { start = array[row]; stop = 64; } int col2 = 0; for (col=0; col < 8; col++) { unsigned char c = 0; for (col1=0; col1 < 8; col1++) { c <<= 1; if ((col2 < start) || (col2 >= stop)) c |= 1; col2++; } *dest++ = c; } } } } void CTimeOfDay::RotateMoonMask (int angle) { float sine, cosine; glGetSinCos (&sine, &cosine, -angle); int u1[3], v1[3]; float c32, s32; c32 = 65536.0f*32.0f * cosine; s32 = 65536.0f*32.0f * sine; u1[0] = (int) (-c32 + s32 + 65536.0f*32.0f); v1[0] = (int) (-s32 - c32 + 65536.0f*32.0f); u1[1] = (int) ( c32 + s32 + 65536.0f*32.0f); v1[1] = (int) ( s32 - c32 + 65536.0f*32.0f); u1[2] = (int) (-c32 - s32 + 65536.0f*32.0f); v1[2] = (int) (-s32 + c32 + 65536.0f*32.0f); int i, j, k; unsigned char *dest = CurrentMoonPhaseMask; int uu = u1[0]; int vv = v1[0]; int duu = (u1[1] - u1[0]) >> 6; int duv = (v1[1] - v1[0]) >> 6; int dvu = (u1[2] - u1[0]) >> 6; int dvv = (v1[2] - v1[0]) >> 6; for (i=0; i < 64; i++) { int uuu = uu; int vvv = vv; for (j=0; j < 8; j++) { unsigned char c1 = 0; for (k=0; k < 8; k++) { int tu = uuu >> 16; int tv = vvv >> 16; c1 <<= 1; uuu += duu; vvv += duv; if (tu >= 0 && tu < 64 && tv >= 0 && tv < 64) { int l = (tv << 3) + (tu >> 3); unsigned char c = (unsigned char)(1 << (7 - (tu & 7))); if (MoonPhaseMask[l] & c) c1 |= 1; } } *dest++ = c1; } uu += dvu; vv += dvv; } } void CTimeOfDay::CalculateMoonPhase () { int angle = 0; float dy = SunCoord.y - MoonCoord.y; if (dy > 1.0f) { dy -= 2.0f; angle = -4096; } else if (dy < -1.0f) { dy += 2.0f; angle = 4096; } if (dy < 0) angle -= 4096; else angle += 4096; float dz = SunCoord.z - MoonCoord.z; angle += FloatToInt32(radtoangle((float)atan2(dz, dy))); //MI moon phase fix #if 0 dy = MoonCoord.z; dz = MoonCoord.y; #else dy = -MoonCoord.y; dz = -MoonCoord.z; #endif int angle1 = FloatToInt32(radtoangle((float)atan2(dz, dy))); angle -= angle1; RotateMoonMask(angle); } void CTimeOfDay::CreateMoonPhase (unsigned char *src, unsigned char *dest) { int i, j, k; unsigned char *mask = CurrentMoonPhaseMask; for (i=0; i < 64; i++) { for (j=0; j < 8; j++) { unsigned char c = *mask++; for (k=0; k < 8; k++) { unsigned char c1 = *src++; #ifdef USE_TRANSPARENT_MOON if (c1 && !(c & 0x80)) c1 = 0; #else if (c1 && !(c & 0x80)) c1 += 48; #endif c <<= 1; *dest++ = c1; } } } } DWORD CTimeOfDay::MakeColor(Tcolor *col) { return (FloatToInt32(col->r * 255.9f) & 0xFF) | ((FloatToInt32(col->g * 255.9f) & 0xFF) << 8) | ((FloatToInt32(col->b * 255.9f) & 0xFF) << 16) | 0xff000000; }