DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 00020 #ifndef DOSBOX_SETUP_H 00021 #define DOSBOX_SETUP_H 00022 00023 #ifdef _MSC_VER 00024 //#pragma warning ( disable : 4786 ) 00025 //#pragma warning ( disable : 4290 ) 00026 #undef max 00027 #undef min 00028 #endif 00029 00030 00031 #ifndef CH_LIST 00032 #define CH_LIST 00033 #include <list> 00034 #endif 00035 00036 #ifndef CH_VECTOR 00037 #define CH_VECTOR 00038 #include <vector> 00039 #endif 00040 00041 #ifndef CH_STRING 00042 #define CH_STRING 00043 #include <string> 00044 #endif 00045 00046 #ifndef CH_CSTDIO 00047 #define CH_CSTDIO 00048 #include <stdio.h> 00049 #endif 00050 00051 00052 class Hex { 00053 private: 00054 int _hex; 00055 public: 00056 Hex(int in):_hex(in) { }; 00057 Hex():_hex(0) { }; 00058 bool operator==(Hex const& other) {return _hex == other._hex;} 00059 operator int () const { return _hex; } 00060 }; 00061 00062 class Value { 00063 /* 00064 * Multitype storage container that is aware of the currently stored type in it. 00065 * Value st = "hello"; 00066 * Value in = 1; 00067 * st = 12 //Exception 00068 * in = 12 //works 00069 */ 00070 private: 00071 Hex _hex; 00072 bool _bool = false; 00073 int _int = 0; 00074 std::string* _string = NULL; 00075 double _double = 0; 00076 public: 00077 class WrongType { }; // Conversion error class 00078 enum Etype { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE,V_CURRENT} type = V_NONE; 00079 00080 /* Constructors */ 00081 Value() { }; 00082 Value(Hex in) :_hex(in), type(V_HEX) { }; 00083 Value(int in) :_int(in), type(V_INT) { }; 00084 Value(bool in) :_bool(in), type(V_BOOL) { }; 00085 Value(double in) :_double(in), type(V_DOUBLE) { }; 00086 Value(std::string const& in) :_string(new std::string(in)),type(V_STRING) { }; 00087 Value(char const * const in) :_string(new std::string(in)),type(V_STRING) { }; 00088 Value(Value const& in) {plaincopy(in);} 00089 ~Value() { destroy();}; 00090 Value(std::string const& in, Etype _t) { SetValue(in, _t); } 00091 00092 /* Assigment operators */ 00093 Value& operator= (Hex in) { return copy(Value(in));} 00094 Value& operator= (int in) { return copy(Value(in));} 00095 Value& operator= (bool in) { return copy(Value(in));} 00096 Value& operator= (double in) { return copy(Value(in));} 00097 Value& operator= (std::string const& in) { return copy(Value(in));} 00098 Value& operator= (char const * const in) { return copy(Value(in));} 00099 Value& operator= (Value const& in) { return copy(Value(in));} 00100 00101 bool operator== (Value const & other); 00102 operator bool () const; 00103 operator Hex () const; 00104 operator int () const; 00105 operator double () const; 00106 operator char const* () const; 00107 bool SetValue(std::string const& in,Etype _type = V_CURRENT); 00108 std::string ToString() const; 00109 00110 private: 00111 void destroy(); 00112 Value& copy(Value const& in); 00113 void plaincopy(Value const& in); 00114 bool set_hex(std::string const& in); 00115 bool set_int(std::string const&in); 00116 bool set_bool(std::string const& in); 00117 void set_string(std::string const& in); 00118 bool set_double(std::string const& in); 00119 }; 00120 00121 class Property { 00122 public: 00123 struct Changeable { enum Value {Always, WhenIdle,OnlyAtStart};}; 00124 const std::string propname; 00125 00126 Property(std::string const& _propname, Changeable::Value when):propname(_propname),is_modified(false),change(when) { use_global_config_str=false; } 00127 void Set_values(const char * const * in); 00128 void Set_help(std::string const& in); 00129 char const* Get_help(); 00130 virtual bool SetValue(std::string const& str)=0; 00131 Value const& GetValue() const { return value;} 00132 Value const& Get_Default_Value() const { return default_value; } 00133 //CheckValue returns true, if value is in suggested_values; 00134 //Type specific properties are encouraged to override this and check for type 00135 //specific features. 00136 virtual bool CheckValue(Value const& in, bool warn); 00137 virtual ~Property(){ } 00138 virtual const std::vector<Value>& GetValues() const; 00139 Value::Etype Get_type(){return default_value.type;} 00140 Changeable::Value getChange() {return change;} 00141 bool modified() const { return is_modified; }; 00142 00143 protected: 00144 //Set interval value to in or default if in is invalid. force always sets the value. 00145 //Can be overriden to set a different value if invalid. 00146 virtual bool SetVal(Value const& in, bool forced,bool warn=true,bool init=false) { 00147 if(forced || CheckValue(in,warn)) { 00148 value = in; is_modified = !init; return true; 00149 } else { 00150 value = default_value; is_modified = false; return false; 00151 } 00152 } 00153 Value value; 00154 bool is_modified; 00155 std::vector<Value> suggested_values; 00156 typedef std::vector<Value>::iterator iter; 00157 Value default_value; 00158 const Changeable::Value change; 00159 bool use_global_config_str; 00160 std::string help_string; 00161 }; 00162 00163 class Prop_int:public Property { 00164 public: 00165 Prop_int(std::string const& _propname,Changeable::Value when, int _value) 00166 :Property(_propname,when), min (-1), max(-1) { 00167 default_value = value = _value; 00168 } 00169 Prop_int(std::string const& _propname,Changeable::Value when, int _min,int _max,int _value) 00170 :Property(_propname,when), min(_min), max(_max) { 00171 default_value = value = _value; 00172 } 00173 int getMin() { return min;} 00174 int getMax() { return max;} 00175 void SetMinMax(Value const& min,Value const& max) {this->min = min; this->max=max;} 00176 bool SetValue(std::string const& input); 00177 virtual ~Prop_int(){ } 00178 virtual bool CheckValue(Value const& in, bool warn); 00179 // Override SetVal, so it takes min,max in account when there are no suggested values 00180 virtual bool SetVal(Value const& in, bool forced,bool warn=true,bool init=false); 00181 00182 private: 00183 Value min,max; 00184 }; 00185 00186 class Prop_double:public Property { 00187 public: 00188 Prop_double(std::string const & _propname, Changeable::Value when, double _value) 00189 :Property(_propname,when), min(-1.0), max(-1.0) { 00190 default_value = value = _value; 00191 } 00192 Prop_double(std::string const & propname, Changeable::Value when, double _value, double _min, double _max) 00193 :Property(propname, when), min(_min), max(_max) 00194 { 00195 default_value = value = _value; 00196 } 00197 double getMin() const { return min; } 00198 double getMax() const { return max; } 00199 void SetMinMax(Value const& min, Value const& max) { this->min = min; this->max = max; } 00200 bool SetValue(std::string const& input); 00201 virtual ~Prop_double(){ } 00202 virtual bool CheckValue(Value const& in, bool warn); 00203 private: 00204 Value min, max; 00205 }; 00206 00207 class Prop_bool:public Property { 00208 public: 00209 Prop_bool(std::string const& _propname, Changeable::Value when, bool _value) 00210 :Property(_propname,when) { 00211 default_value = value = _value; 00212 } 00213 bool SetValue(std::string const& input); 00214 virtual ~Prop_bool(){ } 00215 }; 00216 00217 class Prop_string:public Property{ 00218 public: 00219 Prop_string(std::string const& _propname, Changeable::Value when, char const * const _value) 00220 :Property(_propname,when) { 00221 default_value = value = _value; 00222 } 00223 bool SetValue(std::string const& input); 00224 virtual bool CheckValue(Value const& in, bool warn); 00225 virtual ~Prop_string(){ } 00226 }; 00227 class Prop_path:public Prop_string{ 00228 public: 00229 std::string realpath; 00230 Prop_path(std::string const& _propname, Changeable::Value when, char const * const _value) 00231 :Prop_string(_propname,when,_value), realpath(_value) { 00232 default_value = value = _value; 00233 } 00234 bool SetValue(std::string const& input); 00235 virtual ~Prop_path(){ } 00236 }; 00237 00238 class Prop_hex:public Property { 00239 public: 00240 Prop_hex(std::string const& _propname, Changeable::Value when, Hex _value) 00241 :Property(_propname,when) { 00242 default_value = value = _value; 00243 } 00244 bool SetValue(std::string const& input); 00245 virtual ~Prop_hex(){ } 00246 }; 00247 00248 class Section; 00249 00250 typedef void (*SectionFunction)(Section*); 00251 00252 /* Wrapper class around startup and shutdown functions. the variable 00253 * canchange indicates it can be called on configuration changes */ 00254 struct Function_wrapper { 00255 SectionFunction function; 00256 bool canchange; 00257 std::string name; 00258 Function_wrapper(SectionFunction const _fun,bool _ch,const char *_name) { 00259 function=_fun; 00260 canchange=_ch; 00261 if (_name != NULL) name = _name; 00262 } 00263 }; 00264 00265 #define NO_SUCH_PROPERTY "PROP_NOT_EXIST" 00266 class Section { 00267 private: 00268 std::string sectionname; 00269 public: 00270 Section(std::string const& _sectionname):sectionname(_sectionname) { } 00271 00272 const char* GetName() const {return sectionname.c_str();} 00273 00274 virtual std::string GetPropValue(std::string const& _property) const =0; 00275 virtual bool HandleInputline(std::string const& _line)=0; 00276 virtual void PrintData(FILE* outfile,bool everything=false) = 0; 00277 virtual ~Section() { /*Children must call executedestroy ! */ } 00278 00279 std::list<SectionFunction> onpropchange; 00280 }; 00281 00282 /* list of functions to call (in list order) when DOSBox-X exits. 00283 * use AddExitFunction() to add your function. 00284 * NOTE: AddExitFunction() adds your function to the back of the list, 00285 * First-In-Last-Out order, so that exit callbacks added by init 00286 * code are called in the opposite order from initialization 00287 * (i.e. we want high-level stuff to cleanup first and low level 00288 * stuff like logging to cleanup last). */ 00289 extern std::list<Function_wrapper> exitfunctions; 00290 void AddExitFunction(SectionFunction func,const char *name,bool canchange=false); 00291 00292 /* for use with AddExitFunction and a name of a function. 00293 * this turns it into function pointer and function name. it turns one param into two. */ 00294 #define AddExitFunctionFuncPair(x) &x, #x 00295 00296 /* array of list of functions to call for various virtual machine events */ 00297 enum vm_event { 00298 VM_EVENT_POWERON=0, // emulation has started to power on hardware. it is safe to connect I/O, memory, IRQ resources, etc. to the bus. BIOS not initialized yet. 00299 VM_EVENT_RESET, // reset signal (at the hardware level), whether by the keyboard controller, reset button, etc. 00300 VM_EVENT_RESET_END, // reset signal switched off, permitting the system to begin booting. 00301 VM_EVENT_BIOS_INIT, // BIOS is going to reinitialize the system (after reset) 00302 VM_EVENT_BIOS_BOOT, // BIOS in the boot stage. usually leads to DOS kernel init or guest OS boot. 00303 00304 VM_EVENT_GUEST_OS_BOOT=5, // BIOS or DOS kernel (BOOT command) is running a guest OS. just after loading boot sector into memory but before executing it. 00305 VM_EVENT_DOS_BOOT, // emulation has decided to boot the built-in DOS kernel. just prior to starting the DOS kernel. 00306 VM_EVENT_DOS_INIT_KERNEL_READY, // DOS kernel init. Prior to CONFIG.SYS handling. 00307 VM_EVENT_DOS_INIT_CONFIG_SYS_DONE, // DOS kernel init. After CONFIG.SYS handling, all devices inited. 00308 VM_EVENT_DOS_INIT_SHELL_READY, // DOS kernel init. After COMMAND.COM initialization, before AUTOEXEC.BAT execution. 00309 00310 VM_EVENT_DOS_INIT_AUTOEXEC_BAT_DONE=10, // DOS kernel init. COMMAND.COM just finished AUTOEXEC.BAT. 00311 VM_EVENT_DOS_INIT_AT_PROMPT, // DOS kernel init complete. After this event, the user is immediately given the DOS prompt. 00312 VM_EVENT_DOS_EXIT_BEGIN, // DOS kernel is just starting to exit (user used BOOT command) 00313 VM_EVENT_DOS_EXIT_KERNEL, // DOS kernel has just finished exiting 00314 VM_EVENT_DOS_EXIT_REBOOT_BEGIN, // DOS kernel is just starting to exit (hard reset, outside of DOS's control) 00315 00316 VM_EVENT_DOS_EXIT_REBOOT_KERNEL=15, // DOS kernel has just finished exiting (hard reset) 00317 VM_EVENT_DOS_SURPRISE_REBOOT, // DOS kernel asked to boot, when apparently having never been shut down (jmp to FFFF:0000) 00318 00319 VM_EVENT_MAX 00320 }; 00321 00322 class VMDispatchState { 00323 public: 00324 VMDispatchState() : current_event(VM_EVENT_MAX), event_in_progress(false) { } 00325 void begin_event(enum vm_event event) { 00326 event_in_progress = true; 00327 current_event = event; 00328 } 00329 void end_event() { 00330 event_in_progress = false; 00331 } 00332 public: 00333 enum vm_event current_event; 00334 bool event_in_progress; 00335 }; 00336 00337 extern VMDispatchState vm_dispatch_state; 00338 00339 const char *GetVMEventName(enum vm_event event); 00340 00341 extern std::list<Function_wrapper> vm_event_functions[VM_EVENT_MAX]; 00342 void AddVMEventFunction(enum vm_event event,SectionFunction func,const char *name,bool canchange=false); 00343 void DispatchVMEvent(enum vm_event event); 00344 00345 /* for use with AddExitFunction and a name of a function. 00346 * this turns it into function pointer and function name. it turns one param into two. */ 00347 #define AddVMEventFunctionFuncPair(x) &x, #x 00348 00349 class Prop_multival; 00350 class Prop_multival_remain; 00351 class Section_prop:public Section { 00352 private: 00353 std::list<Property*> properties; 00354 typedef std::list<Property*>::iterator it; 00355 typedef std::list<Property*>::const_iterator const_it; 00356 00357 public: 00358 Section_prop(std::string const& _sectionname):Section(_sectionname){} 00359 Prop_int* Add_int(std::string const& _propname, Property::Changeable::Value when, int _value=0); 00360 Prop_string* Add_string(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL); 00361 Prop_path* Add_path(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL); 00362 Prop_bool* Add_bool(std::string const& _propname, Property::Changeable::Value when, bool _value=false); 00363 Prop_hex* Add_hex(std::string const& _propname, Property::Changeable::Value when, Hex _value=0); 00364 Prop_double* Add_double(std::string const& _propname, Property::Changeable::Value when, double _value=0.0); 00365 Prop_multival *Add_multi(std::string const& _propname, Property::Changeable::Value when,std::string const& sep); 00366 Prop_multival_remain *Add_multiremain(std::string const& _propname, Property::Changeable::Value when,std::string const& sep); 00367 00368 Property* Get_prop(int index); 00369 Property* Get_prop(std::string const& _propname); 00370 int Get_int(std::string const& _propname) const; 00371 const char* Get_string(std::string const& _propname) const; 00372 bool Get_bool(std::string const& _propname) const; 00373 Hex Get_hex(std::string const& _propname) const; 00374 double Get_double(std::string const& _propname) const; 00375 Prop_path* Get_path(std::string const& _propname) const; 00376 Prop_multival* Get_multival(std::string const& _propname) const; 00377 Prop_multival_remain* Get_multivalremain(std::string const& _propname) const; 00378 virtual bool HandleInputline(std::string const& gegevens); 00379 virtual void PrintData(FILE* outfile,bool everything=false); 00380 virtual std::string GetPropValue(std::string const& _property) const; 00381 virtual ~Section_prop(); 00382 std::string data; 00383 }; 00384 00385 class Prop_multival:public Property{ 00386 protected: 00387 Section_prop* section; 00388 std::string separator; 00389 void make_default_value(); 00390 public: 00391 Prop_multival(std::string const& _propname, Changeable::Value when,std::string const& sep):Property(_propname,when), section(new Section_prop("")),separator(sep) { 00392 default_value = value = ""; 00393 } 00394 Section_prop *GetSection() { return section; } 00395 const Section_prop *GetSection() const { return section; } 00396 virtual bool SetValue(std::string const& input,bool init); 00397 virtual bool SetValue(std::string const& input) { return SetValue(input,/*init*/false); }; 00398 virtual const std::vector<Value>& GetValues() const; 00399 virtual ~Prop_multival() { if (section != NULL) { delete section; } } 00400 }; //value bevat totale string. setvalue zet elk van de sub properties en checked die. 00401 00402 class Prop_multival_remain:public Prop_multival{ 00403 public: 00404 Prop_multival_remain(std::string const& _propname, Changeable::Value when,std::string const& sep):Prop_multival(_propname,when,sep){ } 00405 00406 virtual bool SetValue(std::string const& input,bool init); 00407 virtual bool SetValue(std::string const& input) { return SetValue(input,/*init*/false); }; 00408 }; 00409 00410 00411 class Section_line: public Section{ 00412 public: 00413 Section_line(std::string const& _sectionname):Section(_sectionname){} 00414 virtual ~Section_line() { }; 00415 virtual bool HandleInputline(std::string const& line); 00416 virtual void PrintData(FILE* outfile,bool everything=false); 00417 virtual std::string GetPropValue(std::string const& _property) const; 00418 std::string data; 00419 }; 00420 00421 class Module_base { 00422 /* Base for all hardware and software "devices" */ 00423 protected: 00424 Section* m_configuration; 00425 public: 00426 Module_base(Section* configuration){m_configuration=configuration;}; 00427 // Module_base(Section* configuration, SaveState* state) {}; 00428 virtual ~Module_base(){/*LOG_MSG("executed")*/;};//Destructors are required 00429 /* Returns true if succesful.*/ 00430 virtual bool Change_Config(Section* /*newconfig*/) {return false;} ; 00431 }; 00432 #endif