// Ryzom - MMORPG Framework
// 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 .
#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 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 = strlwr (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; iGeneralDlg;
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; iDisplayDetailsDlg;
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; iName, *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; iName=="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::value_type (*cwnd, (const char*)text));
/* else if (!stlText.empty() && GetInt ("TestConfig") )
HwndMap.insert (std::map::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::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)
}
}