/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "SeriousSam/StdH.h" #include "SeriousSam/VarList.h" CListHead _lhVarSettings; static CTString _strFile; static INDEX _ctLines; static CTString GetNonEmptyLine_t(CTStream &strm) { FOREVER { if(strm.AtEOF()) { ThrowF_t(TRANS("Unexpected end of file")); } CTString str; _ctLines++; strm.GetLine_t(str); str.TrimSpacesLeft(); if (str.RemovePrefix("//")) { // skip comments continue; } if (str!="") { str.TrimSpacesRight(); return str; } } } void TranslateLine(CTString &str) { str.TrimSpacesLeft(); if (str.RemovePrefix("TTRS")) { str.TrimSpacesLeft(); str = TranslateConst(str, 0); } str.TrimSpacesLeft(); } static void FixupFileName_t(CTString &strFnm) { strFnm.TrimSpacesLeft(); strFnm.TrimSpacesRight(); if (!strFnm.RemovePrefix(CTString("TF") +"NM ")) { // must not directly have ids in code ThrowF_t(TRANS("Expected %s%s before filename"), "TF", "NM"); } } void CheckPVS_t(CVarSetting *pvs) { if (pvs==NULL) { ThrowF_t("Gadget expected"); } } void ParseCFG_t(CTStream &strm) { CVarSetting *pvs = NULL; // repeat FOREVER { // read one line CTString strLine = GetNonEmptyLine_t(strm); if (strLine.RemovePrefix("MenuEnd")) { return; } else if (strLine.RemovePrefix("Gadget:")) { pvs = new CVarSetting; _lhVarSettings.AddTail(pvs->vs_lnNode); TranslateLine(strLine); strLine.TrimSpacesLeft(); pvs->vs_strName = strLine; } else if (strLine.RemovePrefix("Type:")) { CheckPVS_t(pvs); strLine.TrimSpacesLeft(); strLine.TrimSpacesRight(); if (strLine=="Toggle") { pvs->vs_bSeparator = FALSE; } else if (strLine=="Separator") { pvs->vs_bSeparator = TRUE; } } else if (strLine.RemovePrefix("Schedule:")) { CheckPVS_t(pvs); FixupFileName_t(strLine); pvs->vs_strSchedule = strLine; } else if (strLine.RemovePrefix("Tip:")) { CheckPVS_t(pvs); TranslateLine(strLine); strLine.TrimSpacesLeft(); strLine.TrimSpacesRight(); pvs->vs_strTip = strLine; } else if (strLine.RemovePrefix("Var:")) { CheckPVS_t(pvs); strLine.TrimSpacesLeft(); strLine.TrimSpacesRight(); pvs->vs_strVar = strLine; } else if (strLine.RemovePrefix("Filter:")) { CheckPVS_t(pvs); strLine.TrimSpacesLeft(); strLine.TrimSpacesRight(); pvs->vs_strFilter = strLine; } else if (strLine.RemovePrefix("Slider:")) { CheckPVS_t(pvs); strLine.TrimSpacesLeft(); strLine.TrimSpacesRight(); if (strLine=="Fill") { pvs->vs_iSlider = 1; } else if (strLine=="Ratio") { pvs->vs_iSlider = 2; } else { pvs->vs_iSlider = 0; } } else if (strLine.RemovePrefix("InGame:")) { CheckPVS_t(pvs); strLine.TrimSpacesLeft(); strLine.TrimSpacesRight(); if( strLine=="No") { pvs->vs_bCanChangeInGame = FALSE; } else { ASSERT( strLine=="Yes"); pvs->vs_bCanChangeInGame = TRUE; } } else if (strLine.RemovePrefix("String:")) { CheckPVS_t(pvs); TranslateLine(strLine); strLine.TrimSpacesLeft(); strLine.TrimSpacesRight(); pvs->vs_astrTexts.Push() = strLine; } else if (strLine.RemovePrefix("Value:")) { CheckPVS_t(pvs); strLine.TrimSpacesLeft(); strLine.TrimSpacesRight(); pvs->vs_astrValues.Push() = strLine; } else { ThrowF_t(TRANS("unknown keyword")); } } } void LoadVarSettings(const CTFileName &fnmCfg) { FlushVarSettings(FALSE); try { CTFileStream strm; strm.Open_t(fnmCfg); _ctLines = 0; _strFile = fnmCfg; ParseCFG_t(strm); } catch (char* strError) { CPrintF("%s (%d) : %s\n", (const char*)_strFile, _ctLines, strError); } FOREACHINLIST(CVarSetting, vs_lnNode, _lhVarSettings, itvs) { CVarSetting &vs = *itvs; if (!vs.Validate() || vs.vs_bSeparator) { continue; } INDEX ctValues = vs.vs_ctValues; CTString strValue = _pShell->GetValue(vs.vs_strVar); vs.vs_bCustom = TRUE; vs.vs_iOrgValue = vs.vs_iValue = -1; for(INDEX iValue=0; iValue astrScheduled; if (bApply) { FOREACHINLIST(CVarSetting, vs_lnNode, _lhVarSettings, itvs) { CVarSetting &vs = *itvs; if (vs.vs_iValue!=vs.vs_iOrgValue) { CTString strCmd; _pShell->SetValue(vs.vs_strVar, vs.vs_astrValues[vs.vs_iValue]); if (vs.vs_strSchedule!="") { BOOL bSheduled = FALSE; for(INDEX i=0; iExecute(strCmd); } } CVarSetting::CVarSetting() { Clear(); } void CVarSetting::Clear() { vs_iOrgValue = 0; vs_iValue = 0; vs_ctValues = 0; vs_bSeparator = FALSE; vs_bCanChangeInGame = TRUE; vs_iSlider = 0; vs_strName.Clear(); vs_strTip.Clear(); vs_strVar.Clear(); vs_strFilter.Clear(); vs_strSchedule.Clear(); vs_bCustom = FALSE; } BOOL CVarSetting::Validate(void) { if (vs_bSeparator) { return TRUE; } vs_ctValues = Min(vs_astrValues.Count(), vs_astrTexts.Count()); if (vs_ctValues<=0) { ASSERT(FALSE); return FALSE; } if (!vs_bCustom) { vs_iValue = Clamp(vs_iValue, 0, vs_ctValues-1); } return TRUE; }