diff --git a/include/setup.h b/include/setup.h index 5c406e04..cc27f4df 100644 --- a/include/setup.h +++ b/include/setup.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.h,v 1.29 2008-01-19 11:02:29 qbix79 Exp $ */ +/* $Id: setup.h,v 1.30 2008-01-26 15:50:19 qbix79 Exp $ */ #ifndef DOSBOX_SETUP_H #define DOSBOX_SETUP_H @@ -37,74 +37,142 @@ #include #endif +#ifndef CH_VECTOR +#define CH_VECTOR +#include +#endif + #ifndef CH_STRING #define CH_STRING #include #endif -union Value{ +class Hex { +private: + int _hex; +public: + Hex(int in):_hex(in) { }; + Hex():_hex(0) { }; + bool operator==(Hex const& other) {return _hex == other._hex;} +}; + +class Value { +public: //for the time being. Added a n to _hex to keep compilable during the work + Hex _hexn; int _hex; bool _bool; int _int; std::string* _string; - float _float; + double _double; +public: + class WrongType { }; // Conversion error class + enum { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE} type; + + /* Constructors */ + Value() :type(V_NONE) { }; + Value(Hex in) :type(V_HEX), _hexn(in) { }; + Value(int in) :type(V_INT), _int(in) { }; + Value(bool in) :type(V_BOOL), _bool(in) { }; + Value(double in) :type(V_DOUBLE), _double(in) { }; + Value(std::string const& in) :type(V_STRING), _string(new std::string(in)) { }; + Value(char const * const in) :type(V_STRING), _string(new std::string(in)) { }; + Value(Value const& in) {plaincopy(in);} + ~Value() { destroy();}; + + /* Assigment operators */ + Value& operator= (Hex in) throw(WrongType) { return copy(Value(in));} + Value& operator= (int in) throw(WrongType) { return copy(Value(in));} + Value& operator= (bool in) throw(WrongType) { return copy(Value(in));} + Value& operator= (double in) throw(WrongType) { return copy(Value(in));} + Value& operator= (std::string const& in) throw(WrongType) { return copy(Value(in));} + Value& operator= (char const * const in) throw(WrongType) { return copy(Value(in));} + Value& operator= (Value const& in) throw(WrongType) { return copy(Value(in));} + + bool operator== (Value const & other); + operator bool () throw(WrongType); + operator Hex () throw(WrongType); + operator int () throw(WrongType); + operator double () throw(WrongType); + operator char const* () throw(WrongType); + +private: + void destroy(); + Value& copy(Value const& in) throw(WrongType); + void plaincopy(Value const& in); + }; class Property { public: + struct Changable { enum Value {Always, WhenIdle,OnlyAtStart};}; Property(char const * const _propname):propname(_propname) { } virtual void SetValue(char* input)=0; virtual void GetValuestring(char* str) const=0; Value GetValue() const { return value;} virtual ~Property(){ } std::string propname; + //CheckValue returns true (and sets value to in) 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. + void SetVal(Value const& in, bool forced) {if(forced || CheckValue(in,false)) value = in; else value = default_value;} +protected: Value value; + std::vector suggested_values; + typedef std::vector::iterator iter; + Value default_value; + /*const*/ Changable::Value change; }; class Prop_int:public Property { public: Prop_int(char const * const _propname, int _value):Property(_propname) { - value._int=_value; + default_value = value = _value; + min = max = -1; } + void SetMinMax(Value const& min,Value const& max) {this->min = min; this->max=max;} void SetValue(char* input); - void GetValuestring(char* str) const; + void GetValuestring(char* str) const; ~Prop_int(){ } + virtual bool CheckValue(Value const& in, bool warn); +private: + Value min,max; }; -class Prop_float:public Property { +class Prop_double:public Property { public: - Prop_float(char const * const _propname, float _value):Property(_propname){ - value._float=_value; + Prop_double(char const * const _propname, float _value):Property(_propname){ + default_value = value = _value; } void SetValue(char* input); void GetValuestring(char* str) const; - ~Prop_float(){ } + ~Prop_double(){ } }; class Prop_bool:public Property { public: Prop_bool(char const * const _propname, bool _value):Property(_propname) { - value._bool=_value; + default_value = value = _value; } void SetValue(char* input); - void GetValuestring(char* str) const; + void GetValuestring(char* str) const; ~Prop_bool(){ } }; class Prop_string:public Property{ public: Prop_string(char const * const _propname, char const * const _value):Property(_propname) { - value._string=new std::string(_value); - } - ~Prop_string(){ - delete value._string; + default_value = value = _value; } void SetValue(char* input); - void GetValuestring(char* str) const; + void GetValuestring(char* str) const; + ~Prop_string(){ } + }; class Prop_hex:public Property { public: Prop_hex(char const * const _propname, int _value):Property(_propname) { - value._hex=_value; + default_value = value._hex = _value; } void SetValue(char* input); ~Prop_hex(){ } @@ -150,18 +218,18 @@ private: typedef std::list::const_iterator const_it; public: Section_prop(char const * const _sectionname):Section(_sectionname){} - void Add_int(char const * const _propname, int _value=0); - void Add_string(char const * const _propname, char const * const _value=NULL); - void Add_bool(char const * const _propname, bool _value=false); - void Add_hex(char const * const _propname, int _value=0); - void Add_float(char const * const _propname, float _value=0.0); + Prop_int& Add_int(char const * const _propname, int _value=0); + Prop_string& Add_string(char const * const _propname, char const * const _value=NULL); + Prop_bool& Add_bool(char const * const _propname, bool _value=false); + Prop_hex& Add_hex(char const * const _propname, int _value=0); + void Add_double(char const * const _propname, double _value=0.0); Property* Get_prop(int index); int Get_int(char const * const _propname) const; const char* Get_string(char const * const _propname) const; bool Get_bool(char const * const _propname) const; int Get_hex(char const * const _propname) const; - float Get_float(char const * const _propname) const; + double Get_double(char const * const _propname) const; void HandleInputline(char *gegevens); void PrintData(FILE* outfile) const; virtual char const * GetPropValue(char const * const _property) const; diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp index 59b40233..6a1a900c 100644 --- a/src/gui/sdl_gui.cpp +++ b/src/gui/sdl_gui.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_gui.cpp,v 1.3 2007-11-06 20:25:36 qbix79 Exp $ */ +/* $Id: sdl_gui.cpp,v 1.4 2008-01-26 15:50:19 qbix79 Exp $ */ #include "SDL.h" #include "../libs/gui_tk/gui_tk.h" @@ -317,13 +317,13 @@ public: PropertyEditor(parent, x, y, section, prop) { new GUI::Label(this, 0, 5, prop->propname); input = new GUI::Input(this, 130, 0, 50); - input->setText(stringify(prop->GetValue()._float)); + input->setText(stringify((double)prop->GetValue())); } bool prepare(std::string &buffer) { - float val; + double val; convert(input->getText(), val, false); - if (val == prop->GetValue()._float) return false; + if (val == (double)prop->GetValue()) return false; buffer.append(stringify(val)); return true; } @@ -403,7 +403,7 @@ public: while ((prop = section->Get_prop(i))) { Prop_bool *pbool = dynamic_cast(prop); Prop_int *pint = dynamic_cast(prop); - Prop_float *pfloat = dynamic_cast(prop); + Prop_double *pdouble = dynamic_cast(prop); Prop_hex *phex = dynamic_cast(prop); Prop_string *pstring = dynamic_cast(prop); @@ -411,7 +411,7 @@ public: if (pbool) p = new PropertyEditorBool(this, 5+250*(i/6), 40+(i%6)*30, section, prop); else if (phex) p = new PropertyEditorHex(this, 5+250*(i/6), 40+(i%6)*30, section, prop); else if (pint) p = new PropertyEditorInt(this, 5+250*(i/6), 40+(i%6)*30, section, prop); - else if (pfloat) p = new PropertyEditorFloat(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else if (pdouble) p = new PropertyEditorFloat(this, 5+250*(i/6), 40+(i%6)*30, section, prop); else if (pstring) p = new PropertyEditorString(this, 5+250*(i/6), 40+(i%6)*30, section, prop); else { i++; continue; } b->addActionHandler(p); diff --git a/src/misc/setup.cpp b/src/misc/setup.cpp index 842cbdfc..9506bd7e 100644 --- a/src/misc/setup.cpp +++ b/src/misc/setup.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: setup.cpp,v 1.41 2007-10-21 08:43:24 qbix79 Exp $ */ +/* $Id: setup.cpp,v 1.42 2008-01-26 15:50:19 qbix79 Exp $ */ #include "dosbox.h" #include "cross.h" @@ -30,19 +30,115 @@ using namespace std; -void Prop_float::SetValue(char* input){ +void Value::destroy() { + if (type == V_STRING) delete _string; +} + +Value& Value::copy(Value const& in) throw(WrongType) { + if (this != &in) { //Selfassigment! + if(type != V_NONE && type != in.type) throw WrongType(); + destroy(); + plaincopy(in); + } + return *this; +} + +void Value::plaincopy(Value const& in) { + type = in.type; + _int = in._int; + _double = in._double; + _bool = in._bool; + _hex = in._hex; + if(type == V_STRING) _string = new string(*in._string); +} + +Value::operator bool () throw(WrongType) { + if(type != V_BOOL) throw WrongType(); + return _bool; +} + +Value::operator Hex () throw(WrongType) { + if(type != V_HEX) throw WrongType(); + return _hexn; +} + +Value::operator int () throw(WrongType) { + if(type != V_INT) throw WrongType(); + return _int; +} + +Value::operator double () throw(WrongType) { + if(type != V_DOUBLE) throw WrongType(); + return _double; +} + +Value::operator char const* () throw(WrongType) { + if(type != V_STRING) throw WrongType(); + return _string->c_str(); +} + +bool Value::operator==(Value const& other) { + if(this == &other) return true; + if(type != other.type) return false; + switch(type){ + case V_BOOL: + if(_bool == other._bool) return true; + break; + case V_INT: + if(_int == other._int) return true; + break; + case V_HEX: + if(_hexn == other._hexn) return true; + break; + case V_DOUBLE: + if(_double == other._double) return true; + break; + case V_STRING: + if((*_string) == (*other._string)) return true; + break; + default: + E_Exit("comparing stuff that doesn't make sense"); + break; + } + return false; +} + +bool Property::CheckValue(Value const& in, bool warn){ + if(suggested_values.empty()) return false; + for(iter it = suggested_values.begin();it != suggested_values.end();it++) { + if ( (*it) == in) { //Match! + return true; + } + } + if(warn) LOG_MSG("Value not in suggested values"); + return false; +} + +bool Prop_int::CheckValue(Value const& in, bool warn) { + if(Property::CheckValue(in,warn)) return true; + //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 (va >= mi && va <= ma) return true; + if(warn) LOG_MSG("Value not included in range"); + return false; +} + +void Prop_double::SetValue(char* input){ input=trim(input); - value._float= static_cast(atof(input)); + value = static_cast(atof(input)); } void Prop_int::SetValue(char* input){ input=trim(input); - value._int= atoi(input); + value = atoi(input); } void Prop_string::SetValue(char* input){ input=trim(input); - value._string->assign(input); + value=input; } void Prop_bool::SetValue(char* input){ @@ -71,42 +167,46 @@ void Prop_bool::GetValuestring(char* str) const{ sprintf(str,"%s",value._bool?"true":"false"); } -void Prop_float::GetValuestring(char* str) const { - sprintf(str,"%1.2f",value._float); +void Prop_double::GetValuestring(char* str) const { + sprintf(str,"%1.2f",value._double); } void Prop_hex::GetValuestring(char* str) const { sprintf(str,"%X",value._hex); } -void Section_prop::Add_float(char const * const _propname, float _value) { - Property* test=new Prop_float(_propname,_value); +void Section_prop::Add_double(char const * const _propname, double _value) { + Property* test=new Prop_double(_propname,_value); properties.push_back(test); } -void Section_prop::Add_int(const char* _propname, int _value) { - Property* test=new Prop_int(_propname,_value); +Prop_int& Section_prop::Add_int(const char* _propname, int _value) { + Prop_int* test=new Prop_int(_propname,_value); properties.push_back(test); + return *test; } -void Section_prop::Add_string(char const * const _propname, char const * const _value) { - Property* test=new Prop_string(_propname,_value); +Prop_string& Section_prop::Add_string(char const * const _propname, char const * const _value) { + Prop_string* test=new Prop_string(_propname,_value); properties.push_back(test); + return *test; } -void Section_prop::Add_bool(char const * const _propname, bool _value) { - Property* test=new Prop_bool(_propname,_value); +Prop_bool& Section_prop::Add_bool(char const * const _propname, bool _value) { + Prop_bool* test=new Prop_bool(_propname,_value); properties.push_back(test); + return *test; } -void Section_prop::Add_hex(const char* _propname, int _value) { - Property* test=new Prop_hex(_propname,_value); +Prop_hex& Section_prop::Add_hex(const char* _propname, int _value) { + Prop_hex* test=new Prop_hex(_propname,_value); properties.push_back(test); + return *test; } int Section_prop::Get_int(char const * const _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return ((*tel)->GetValue())._int; + return ((*tel)->GetValue()); } } return 0; @@ -115,15 +215,15 @@ int Section_prop::Get_int(char const * const _propname) const { bool Section_prop::Get_bool(char const * const _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return ((*tel)->GetValue())._bool; + return ((*tel)->GetValue()); } } return false; } -float Section_prop::Get_float(char const * const _propname) const { +double Section_prop::Get_double(char const * const _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return ((*tel)->GetValue())._float; + return ((*tel)->GetValue()); } } return false; @@ -139,7 +239,7 @@ Property* Section_prop::Get_prop(int index){ const char* Section_prop::Get_string(char const * const _propname) const { for(const_it tel=properties.begin();tel!=properties.end();tel++){ if((*tel)->propname==_propname){ - return ((*tel)->GetValue())._string->c_str(); + return ((*tel)->GetValue()); } } return "";