// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/> // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "stdafx.h" #include "cfg_file.h" #include "client_config.h" #include "client_configDlg.h" #include "display_dlg.h" using namespace std; using namespace NLMISC; CConfigFile ConfigFile; // Translation windows map std::map<HWND, std::string> HwndMap; // *************************************************************************** string GetString (const char *var) { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr (var); // Available ? if (variable) { return variable->asString (); } else { theApp.error ("Can't find the variable "+(ucstring)var+" in "CONFIG_FILE_NAME); return ""; } } // *************************************************************************** sint GetInt (const char *var) { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr (var); // Available ? if (variable) { return variable->asInt (); } else { theApp.error ("Can't find the variable "+(ucstring)var+" in "CONFIG_FILE_NAME); return -1; } } // *************************************************************************** float GetFloat (const char *var) { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr (var); // Available ? if (variable) { return variable->asFloat (); } else { theApp.error ("Can't find the variable "+(ucstring)var+" in "CONFIG_FILE_NAME); return -1; } } // *************************************************************************** bool GetBool (const char *var) { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr (var); // Available ? if (variable) { string _bool = toLower (variable->asString ()); if (_bool == "true") return true; if (_bool == "false") return false; theApp.error ("The variable "+(ucstring)var+" is not a boolean "CONFIG_FILE_NAME); return false; } else { theApp.error ("Can't find the variable "+(ucstring)var+" in "CONFIG_FILE_NAME); return false; } } // *************************************************************************** void SetString (const char *var, const char *value) { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr (var); // Available ? if (variable) { if (variable->Type == CConfigFile::CVar::T_STRING) { if (variable->asString () != value) variable->setAsString (value); } else { theApp.error ("The variable "+(ucstring)var+" is not a string "CONFIG_FILE_NAME); } } else { theApp.error ("Can't find the variable "+(ucstring)var+" in "CONFIG_FILE_NAME); } } // *************************************************************************** void SetBool (const char *var, bool value) { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr (var); // Available ? if (variable) { if (variable->Type == CConfigFile::CVar::T_STRING) { const char *valueToSet = value?"true":"false"; if (variable->asString () != valueToSet) variable->setAsString (valueToSet); } else { theApp.error ("The variable "+(ucstring)var+" is not a string "CONFIG_FILE_NAME); } } else { theApp.error ("Can't find the variable "+(ucstring)var+" in "CONFIG_FILE_NAME); } } // *************************************************************************** void SetInt (const char *var, sint value) { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr (var); // Available ? if (variable) { if (variable->Type == CConfigFile::CVar::T_INT) { if (variable->asInt () != value) variable->setAsInt (value); } else { theApp.error ("The variable "+(ucstring)var+" is not an integer "CONFIG_FILE_NAME); } } else { theApp.error ("Can't find the variable "+(ucstring)var+" in "CONFIG_FILE_NAME); } } // *************************************************************************** void SetFloat (const char *var, float value) { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr (var); // Available ? if (variable) { if (variable->Type == CConfigFile::CVar::T_REAL) { if (fabs (variable->asFloat () - value) > 0.000001f) variable->setAsFloat (value); } else { theApp.error ("The variable "+(ucstring)var+" is not a float "CONFIG_FILE_NAME); } } else { theApp.error ("Can't find the variable "+(ucstring)var+" in "CONFIG_FILE_NAME); } } // *************************************************************************** void SetToConfigFile () { // Get the window pointer CClient_configDlg *dlg = (CClient_configDlg*)theApp.m_pMainWnd; dlg->UpdateData (TRUE); // *** General dialog // Get the dialog CGeneralDlg &general = dlg->GeneralDlg; SetInt ("SaveConfig", (int)general.SaveConfig); SetString ("LanguageCode", (general.Language==2)?"de":(general.Language==1)?"fr":"en"); if (general.Sleep) SetInt ("ProcessPriority", -1); else SetInt ("ProcessPriority", 0); // *** Display dialog // Get the dialog CDisplayDlg &display = dlg->DisplayDlg; SetInt ("PositionX", display.PositionX); SetInt ("PositionY", display.PositionY); SetInt ("FullScreen", !display.Windowed); switch(display.DriverChoiceMode) { case CDisplayDlg::DrvChooseDirect3D: SetString("Driver3D", "Direct3D"); break; case CDisplayDlg::DrvChooseOpenGL: SetString("Driver3D", "OpenGL"); break; case CDisplayDlg::DrvChooseAuto: SetString("Driver3D", "Auto"); break; } if (display.Windowed) { SetInt ("Width", display.Width); SetInt ("Height", display.Height); SetInt ("Depth", 32); } else { // Mode valid ? if (display.DriverChoiceMode != CDisplayDlg::DrvChooseUnknwown) { const CVideoMode &videoMode = VideoModes[display.getActualDriver()][display.Mode]; SetInt ("Width", videoMode.Width); SetInt ("Height", videoMode.Height); SetInt ("Depth", 32); SetInt ("Frequency", videoMode.Frequency); } } // *** Display details dialog // Get the dialog CDisplayDetailsDlg &displayDetails = dlg->DisplayDetailsDlg; SetInt ("HDEntityTexture", displayDetails.TextureQualityInt==2); SetInt ("DivideTextureSizeBy2", displayDetails.TextureQualityInt==0); SetFloat ("LandscapeThreshold", QualityToLandscapeThreshold[displayDetails.LandscapeQualityInt]); SetFloat ("Vision", QualityToZFar[displayDetails.LandscapeQualityInt]); SetFloat ("LandscapeTileNear", QualityToLandscapeTileNear[displayDetails.LandscapeQualityInt]); SetInt ("SkinNbMaxPoly", QualityToSkinNbMaxPoly[displayDetails.CharacterQualityInt]); SetInt ("NbMaxSkeletonNotCLod", QualityToNbMaxSkeletonNotCLod[displayDetails.CharacterQualityInt]); SetInt ("FxNbMaxPoly", QualityToFxNbMaxPoly[displayDetails.FXQualityInt]); // *** Display details dialog // Get the dialog CDisplayAdvancedDlg &displayAdvanced = dlg->DisplayAdvancedDlg; SetInt ("ForceDXTC", !displayAdvanced.DisableDXTC); SetInt ("DisableVtxProgram", (int)displayAdvanced.DisableVertexProgram); SetInt ("DisableVtxAGP", (int)displayAdvanced.DisableAGPVertices); SetInt ("DisableTextureShdr", (int)displayAdvanced.DisableTextureShaders); // *** Sound dialog // Get the dialog CSoundDlg &sound = dlg->SoundDlg; SetInt ("SoundOn", (int)sound.SoundOn); SetInt ("UseEax", sound.EAX ? true : false); SetInt ("MaxTrack", sound.getAsNumSoundBuffer()); SetStringDriverSound(sound.FMod ? "FMod" : "Auto"); SetInt ("SoundForceSoftwareBuffer", sound.ForceSoundSoft? true : false); } // *************************************************************************** uint getFullscreenMode (uint driver, const CVideoMode &mode) { // Look for the valid mode ? uint i; for (i=0; i<VideoModes[driver].size (); i++) { // Good one ? if (mode == VideoModes[driver][i]) { // This mode return i; } } return 0xffffffff; } // *************************************************************************** void GetFromConfigFile () { // Get the window pointer CClient_configDlg *dlg = (CClient_configDlg*)theApp.m_pMainWnd; // Get the dialogs CGeneralDlg &general = dlg->GeneralDlg; general.UpdateData (); // *** General dialog general.SaveConfig = GetInt ("SaveConfig"); string lang = GetString ("LanguageCode"); (lang == "de")?general.Language=2:(lang == "fr")?general.Language=1:general.Language=0; int sleep = GetInt ("ProcessPriority"); if (sleep != -1) { general.Sleep = 0; } else { general.Sleep = -1; } general.UpdateData (FALSE); // *** Display dialog CDisplayDlg &display = dlg->DisplayDlg; display.UpdateData (); display.Windowed = !GetInt ("FullScreen"); display.Width = GetInt ("Width"); display.Height = GetInt ("Height"); display.PositionX = GetInt ("PositionX"); display.PositionY = GetInt ("PositionY"); std::string driverMode = GetString("Driver3D"); if (nlstricmp(driverMode, "Auto") == 0 || nlstricmp(driverMode, "0") == 0) display.DriverChoiceMode = CDisplayDlg::DrvChooseAuto; else if (nlstricmp(driverMode, "OpenGL") == 0 || nlstricmp(driverMode, "1") == 0) display.DriverChoiceMode = CDisplayDlg::DrvChooseOpenGL; else if (nlstricmp(driverMode, "Direct3D") == 0 || nlstricmp(driverMode, "2") == 0) display.DriverChoiceMode = CDisplayDlg::DrvChooseDirect3D; else display.DriverChoiceMode = CDisplayDlg::DrvChooseAuto; display.Mode = -1; // The video mode CVideoMode mode; mode.Width = display.Width; mode.Height = display.Height; mode.ColorDepth = 32; mode.Frequency = GetInt ("Frequency"); // Look for the valid mode ? uint i; CDisplayDlg::TDriver actualDriver = display.getActualDriver(); for (i=0; i<VideoModes[actualDriver].size (); i++) { // Good one ? if (mode == VideoModes[actualDriver][i]) { // This mode display.Mode = i; break; } } // If not found, look for default resolution mode.Width = 1024; mode.Height = 768; mode.ColorDepth = 32; mode.Frequency = 60; display.updateState (); display.UpdateData (FALSE); // *** Display details dialog CDisplayDetailsDlg &displayDetails = dlg->DisplayDetailsDlg; int hdTextureInstalled = GetInt ("HDTextureInstalled"); displayDetails.UpdateData (); displayDetails.MaxTextureQuality= hdTextureInstalled?2:1; // NB: if the player changes its client.cfg, mixing HDEntityTexture=1 and DivideTextureSizeBy2=1, it will // result to a low quality! if(GetInt ("DivideTextureSizeBy2")) displayDetails.TextureQualityInt = 0; else if(GetInt ("HDEntityTexture") && hdTextureInstalled) displayDetails.TextureQualityInt = 2; else displayDetails.TextureQualityInt = 1; displayDetails.LandscapeQualityInt = GetQuality (QualityToLandscapeThreshold, GetFloat ("LandscapeThreshold")); displayDetails.FXQualityInt = GetQuality (QualityToFxNbMaxPoly, GetInt ("FxNbMaxPoly")); // minimize quality according to NbMaxSkeletonNotCLod and SkinNbMaxPoly displayDetails.CharacterQualityInt = GetQuality (QualityToSkinNbMaxPoly, GetInt ("SkinNbMaxPoly")); displayDetails.CharacterQualityInt = min(displayDetails.CharacterQualityInt, GetQuality (QualityToNbMaxSkeletonNotCLod, GetInt ("NbMaxSkeletonNotCLod"))); displayDetails.updateState (); displayDetails.UpdateData (FALSE); // *** Display advanced dialog CDisplayAdvancedDlg &displayAdvanced = dlg->DisplayAdvancedDlg; displayAdvanced.UpdateData (); displayAdvanced.DisableDXTC = !GetInt ("ForceDXTC"); displayAdvanced.DisableVertexProgram = GetInt ("DisableVtxProgram") ? TRUE : FALSE; displayAdvanced.DisableAGPVertices = GetInt ("DisableVtxAGP") ? TRUE : FALSE; displayAdvanced.DisableTextureShaders = GetInt ("DisableTextureShdr") ? TRUE : FALSE; displayAdvanced.UpdateData (FALSE); // *** Sound dialog // Get the dialog CSoundDlg &sound = dlg->SoundDlg; sound.UpdateData (); sound.SoundOn = GetInt ("SoundOn"); sound.EAX = GetInt ("UseEax") ? TRUE : FALSE; sound.FMod = GetStringDriverSound()=="FMod" ? TRUE : FALSE; sound.ForceSoundSoft = GetInt ("SoundForceSoftwareBuffer") ? TRUE : FALSE; sound.setAsNumSoundBuffer( GetInt ("MaxTrack") ); sound.updateState (); sound.UpdateData (FALSE); } // *************************************************************************** bool LoadConfigFile () { // Read the file try { ConfigFile.load (CONFIG_FILE_NAME); } catch (Exception &e) { theApp.error ("Error reading the file "CONFIG_FILE_NAME" : "+string (e.what ())); return false; } return true; } // *************************************************************************** bool SaveConfigFile () { // Read the file try { ConfigFile.save (); } catch (Exception &e) { theApp.error (CI18N::get ("uiConfigErrorWritingTheFile")+" "CONFIG_FILE_NAME" : "+string (e.what ())); return false; } return true; } // *************************************************************************** void InvalidateConfig () { theApp.Modified = true; // Get the window pointer CClient_configDlg *dlg = (CClient_configDlg*)theApp.m_pMainWnd; dlg->ApplyCtrl.EnableWindow (TRUE); // Set the title setWindowText(*dlg, (WCHAR*)(CI18N::get ("uiConfigTitle") + " *").c_str()); } // *************************************************************************** void ResetConfigFile () { // Clear the config file ConfigFile.clear (); ConfigFile.reparse (/*CONFIG_DEFAULT_FILE_NAME*/); CConfigFile::CVar var; var.Type = CConfigFile::CVar::T_STRING; var.setAsString (CONFIG_DEFAULT_FILE_NAME); CConfigFile::CVar *newVar = ConfigFile.insertVar ("RootConfigFilename", var); } // *************************************************************************** void MergeConfigFile (CConfigFile &configFile) { // For each variable in the new config file uint count = configFile.getNumVar (); uint i; for (i=0; i<count; i++) { // Get the variable CConfigFile::CVar *src = configFile.getVar (i); // Get the destination variable CConfigFile::CVar *dest = ConfigFile.insertVar (src->Name, *src); if ((src->Type == CConfigFile::CVar::T_INT) && (dest->Type == CConfigFile::CVar::T_INT) || (src->Type == CConfigFile::CVar::T_REAL) && (dest->Type == CConfigFile::CVar::T_INT) || (src->Type == CConfigFile::CVar::T_INT) && (dest->Type == CConfigFile::CVar::T_REAL) || (src->Type == CConfigFile::CVar::T_REAL) && (dest->Type == CConfigFile::CVar::T_REAL) || (src->Type == CConfigFile::CVar::T_STRING) && (dest->Type == CConfigFile::CVar::T_STRING)) { // Get the method for the merge TMergeMethod merge = GetMergeMethod (src->Name.c_str ()); if (src->Type == CConfigFile::CVar::T_INT) { if (dest->Root) { SetInt (src->Name.c_str (), src->asInt()); } else { if (merge == PreferInferior) SetInt (src->Name.c_str (), min (src->asInt(), dest->asInt())); else if (merge == PreferSuperior) SetInt (src->Name.c_str (), max (src->asInt(), dest->asInt())); else if (merge == PreferTrue) SetInt (src->Name.c_str (), (int)((src->asInt()!=0)||(dest->asInt()!=0))); else if (merge == PreferFalse) SetInt (src->Name.c_str (), (int)((src->asInt()!=0)&&(dest->asInt()!=0))); } } else if (src->Type == CConfigFile::CVar::T_REAL) { if (dest->Root) { SetFloat (src->Name.c_str (), src->asFloat()); } else { if (merge == PreferInferior) SetFloat (src->Name.c_str (), min (src->asFloat(), dest->asFloat())); else if (merge == PreferSuperior) SetFloat (src->Name.c_str (), max (src->asFloat(), dest->asFloat())); else if (merge == PreferTrue) SetFloat (src->Name.c_str (), (float)((src->asFloat()!=0.f)||(dest->asFloat()!=0.f))); else if (merge == PreferFalse) SetFloat (src->Name.c_str (), (float)((src->asFloat()!=0.f)&&(dest->asFloat()!=0.f))); } } else if (src->Type == CConfigFile::CVar::T_STRING) { if (dest->Root) { SetString (src->Name.c_str (), src->asString().c_str ()); } else { if (merge == PreferTrue) SetBool (src->Name.c_str (), (src->asString()!="false")||(dest->asString()!="true")); else if (merge == PreferFalse) SetBool (src->Name.c_str (), (src->asString()!="false")&&(dest->asString()!="true")); else SetString (src->Name.c_str (), src->asString().c_str ()); } } } } } // *************************************************************************** void ResetConfigFileToDefault () { // For each variable not ROOT in the current config file uint count = ConfigFile.getNumVar (); uint i; for (i=0; i<count; i++) { // Get the destination variable CConfigFile::CVar *dest = ConfigFile.getVar (i); // Temp: avoid changing this variable (debug: binded to the actual texture set installed) if(dest->Name=="HDTextureInstalled") continue; // Get the variable from default config file CConfigFile::CVar *src = ConfigFileDefault.getVarPtr (dest->Name); // if default exist and cur not already default if ( src && !dest->Root && ((src->Type == CConfigFile::CVar::T_INT) && (dest->Type == CConfigFile::CVar::T_INT) || (src->Type == CConfigFile::CVar::T_REAL) && (dest->Type == CConfigFile::CVar::T_INT) || (src->Type == CConfigFile::CVar::T_INT) && (dest->Type == CConfigFile::CVar::T_REAL) || (src->Type == CConfigFile::CVar::T_REAL) && (dest->Type == CConfigFile::CVar::T_REAL) || (src->Type == CConfigFile::CVar::T_STRING) && (dest->Type == CConfigFile::CVar::T_STRING))) { if (src->Type == CConfigFile::CVar::T_INT) { SetInt (src->Name.c_str (), src->asInt()); } else if (src->Type == CConfigFile::CVar::T_REAL) { SetFloat (src->Name.c_str (), src->asFloat()); } else if (src->Type == CConfigFile::CVar::T_STRING) { SetString (src->Name.c_str (), src->asString().c_str()); } } } } // *************************************************************************** void backupWindowHandleRec (CWnd *cwnd) { if (!cwnd) cwnd = theApp.m_pMainWnd; CString text; cwnd->GetWindowText (text); string stlText = (const char*)text; // Add an entry for this window if ((stlText.size()>2) && (stlText[0] == 'u') && (stlText[1] == 'i')) HwndMap.insert (std::map<HWND, std::string>::value_type (*cwnd, (const char*)text)); /* else if (!stlText.empty() && GetInt ("TestConfig") ) HwndMap.insert (std::map<HWND, std::string>::value_type (*cwnd, (const char*)"toto")); */ // Go for the children CWnd* child = cwnd->GetWindow(GW_CHILD); while (child) { backupWindowHandleRec (child); child = child->GetWindow(GW_HWNDNEXT); } } // *************************************************************************** void localizeWindowsRec (CWnd *cwnd, bool useMap) { if (!cwnd) cwnd = theApp.m_pMainWnd; if (useMap) { std::map<HWND, std::string>::iterator ite = HwndMap.find (*cwnd); if (ite != HwndMap.end()) { ucstring ucName = CI18N::get (ite->second); setWindowText(ite->first, (WCHAR*)ucName.c_str()); } } else { CString name; cwnd->GetWindowText (name); ucstring ucName = CI18N::get ((const char*)name); setWindowText(*cwnd, (WCHAR*)ucName.c_str()); } // Go for the children CWnd* child = cwnd->GetWindow(GW_CHILD); while (child) { localizeWindowsRec (child, useMap); child = child->GetWindow(GW_HWNDNEXT); } } // *************************************************************************** std::string GetStringDriverSound() { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr ("DriverSound"); // Available ? if (variable) return variable->asString (); // else force FMod else return "FMod"; } // *************************************************************************** sint GetIntForceLanguage() { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr ("ForceLanguage"); // Available ? if (variable) return variable->asInt (); // else force "NO" else return 0; } // *************************************************************************** sint GetIntTestConfig() { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr ("TestConfig"); // Available ? if (variable) return variable->asInt (); // else force NO else return 0; } // *************************************************************************** void SetStringDriverSound(const char *value) { // Get the variable pointer CConfigFile::CVar *variable = ConfigFile.getVarPtr ("DriverSound"); // Available ? if (variable) { if (variable->Type == CConfigFile::CVar::T_STRING) { if (variable->asString () != value) variable->setAsString (value); } else { theApp.error (ucstring("The variable DriverSound is not a string "CONFIG_FILE_NAME)); } } else { // no op (FMod should be forced) } }