From 07f461da7ecc4504165bb0a208900d1c7041882b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 20 Sep 2016 14:57:46 +0000 Subject: [PATCH] Clip to boundaries when there are no suggested values for Prop_int. Revert r3986 as this commit fixes the problem in a different way. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3996 --- include/setup.h | 18 ++++++++++++---- src/dosbox.cpp | 2 +- src/misc/setup.cpp | 51 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/include/setup.h b/include/setup.h index 006cef67..7dc9f401 100644 --- a/include/setup.h +++ b/include/setup.h @@ -129,19 +129,26 @@ public: virtual bool SetValue(std::string const& str)=0; Value const& GetValue() const { return value;} Value const& Get_Default_Value() const { return default_value; } - //CheckValue returns true if value is in suggested_values; + //CheckValue returns true, if value is in suggested_values; //Type specific properties are encouraged to override this and check for type //specific features. virtual bool CheckValue(Value const& in, bool warn); - //Set interval value to in or default if in is invalid. force always sets the value. - bool SetVal(Value const& in, bool forced,bool warn=true) { - if(forced || CheckValue(in,warn)) {value = in; return true;} else { value = default_value; return false;}} +public: virtual ~Property(){ } virtual const std::vector& GetValues() const; Value::Etype Get_type(){return default_value.type;} Changeable::Value getChange() {return change;} protected: + //Set interval value to in or default if in is invalid. force always sets the value. + //Can be overriden to set a different value if invalid. + virtual bool SetVal(Value const& in, bool forced,bool warn=true) { + if(forced || CheckValue(in,warn)) { + value = in; return true; + } else { + value = default_value; return false; + } + } Value value; std::vector suggested_values; typedef std::vector::iterator iter; @@ -168,6 +175,9 @@ public: bool SetValue(std::string const& in); ~Prop_int(){ } virtual bool CheckValue(Value const& in, bool warn); + // Override SetVal, so it takes min,max in account when there are no suggested values + virtual bool SetVal(Value const& in, bool forced,bool warn=true); + private: Value min,max; }; diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 675e90da..1462fae3 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -370,7 +370,7 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&MEM_Init);//done secprop->AddInitFunction(&HARDWARE_Init);//done Pint = secprop->Add_int("memsize", Property::Changeable::WhenIdle,16); - Pint->SetMinMax(1,64); + Pint->SetMinMax(1,63); Pint->Set_help( "Amount of memory DOSBox has in megabytes.\n" " This value is best left at its default to avoid problems with some games,\n" diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index eea76a20..9ea232ba 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -227,7 +227,7 @@ bool Property::CheckValue(Value const& in, bool warn){ return true; } } - if(warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); + if (warn) LOG_MSG("\"%s\" is not a valid value for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); return false; } @@ -243,18 +243,51 @@ char const* Property::Get_help() { return MSG_Get(result.c_str()); } +bool Prop_int::SetVal(Value const& in, bool forced, bool warn) { + if (forced) { + value = in; + return true; + } else if (!suggested_values.empty()){ + if ( CheckValue(in,warn) ) { + value = in; + return true; + } else { + value = default_value; + return false; + } + } else { + //Handle ranges if specified + int mi = min; + int ma = max; + int va = static_cast(Value(in)); + + //No ranges + if (mi == -1 && ma == -1) { value = in; return true;} + //Inside range + if (va >= mi && va <= ma) { value = in; return true;} + + //Outside range, set it to the closest boundary + if (va > ma ) va = ma; else va = mi; + + if (warn) LOG_MSG("%s is outside the allowed range %s-%s for variable: %s.\nIt has been set to the closest boundary: %d.",in.ToString().c_str(),min.ToString().c_str(),max.ToString().c_str(),propname.c_str(),va); + + value = va; + return true; + } +} bool Prop_int::CheckValue(Value const& in, bool warn) { // if(!suggested_values.empty() && Property::CheckValue(in,warn)) return true; if(!suggested_values.empty()) return Property::CheckValue(in,warn); - + LOG_MSG("still used ?"); //No >= and <= in Value type and == is ambigious int mi = min; int ma = max; int va = static_cast(Value(in)); - if(mi == -1 && ma == -1) return true; + if (mi == -1 && ma == -1) return true; if (va >= mi && va <= ma) return true; - if(warn) LOG_MSG("%s lies outside the range %s-%s for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),min.ToString().c_str(),max.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); + + if (warn) LOG_MSG("%s lies outside the range %s-%s for variable: %s.\nIt might now be reset to the default value: %s",in.ToString().c_str(),min.ToString().c_str(),max.ToString().c_str(),propname.c_str(),default_value.ToString().c_str()); return false; } @@ -581,7 +614,6 @@ void trim(string& in) { if(loc != string::npos) in.erase(loc+1); } -//TODO double c_str bool Section_prop::HandleInputline(string const& gegevens){ string str1 = gegevens; string::size_type loc = str1.find('='); @@ -613,7 +645,6 @@ void Section_prop::PrintData(FILE* outfile) const { } } -//TODO geen noodzaak voor 2 keer c_str string Section_prop::GetPropValue(string const& _property) const{ for(const_it tel=properties.begin();tel!=properties.end();tel++){ if(!strcasecmp((*tel)->propname.c_str(),_property.c_str())){ @@ -642,16 +673,16 @@ bool Config::PrintConfig(char const * const configfilename) const { FILE* outfile=fopen(configfilename,"w+t"); if(outfile==NULL) return false; - /* Print start of configfile and add an return to improve readibility. */ + /* Print start of configfile and add a return to improve readibility. */ fprintf(outfile,MSG_Get("CONFIGFILE_INTRO"),VERSION); fprintf(outfile,"\n"); for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ /* Print out the Section header */ - Section_prop *sec = dynamic_cast(*tel); strcpy(temp,(*tel)->GetName()); lowcase(temp); fprintf(outfile,"[%s]\n",temp); + Section_prop *sec = dynamic_cast(*tel); if (sec) { Property *p; size_t i = 0, maxwidth = 0; @@ -719,7 +750,7 @@ Section_prop* Config::AddSection_prop(char const * const _name,void (*_initfunct } Section_prop::~Section_prop() { -//ExecuteDestroy should be here else the destroy functions use destroyed properties + //ExecuteDestroy should be here else the destroy functions use destroyed properties ExecuteDestroy(true); /* Delete properties themself (properties stores the pointer of a prop */ for(it prop = properties.begin(); prop != properties.end(); prop++) @@ -781,7 +812,7 @@ Section* Config::GetSection(int index){ } return NULL; } -//c_str() 2x + Section* Config::GetSection(string const& _sectionname) const{ for (const_it tel=sectionlist.begin(); tel!=sectionlist.end(); tel++){ if (!strcasecmp((*tel)->GetName(),_sectionname.c_str())) return (*tel);