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