src/settings.cpp

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <fstream>
00003 #include <sstream>
00004 #include <iomanip>
00005 #include <cmath>
00006 #include "cardinfo.h"
00007 #include "settings.h"
00008 #include "controls.h"
00009 #include "globals.h"
00010 #include "binreloc.h"
00011 
00012 using namespace std;
00013 
00014 #define NUM_FILES_CHK 7
00015 #define NUM_SUBDIRS_CHK 5
00016 
00017 extern bool verbose_output;
00018 
00019 inline bool gt_rect (SDL_Rect r1, SDL_Rect r2) { return ((r1.w*r1.h) < (r2.w*r2.h)); }
00020 inline bool eq_rect (SDL_Rect r1, SDL_Rect r2) { return ((r1.w == r2.w) && (r1.h == r2.h)); }
00021 
00022 SETTINGS::SETTINGS()
00023 {
00024         // Enable/disable spewing debug output
00025         spew = verbose_output;
00026 
00027         // Get user's home directory
00028         FindHomeDir();
00029 
00030         // Figure out where the settings are to be
00031         settings_directory = SETTINGS_DIR;
00032 
00033 #ifndef _WIN32
00034         settings_path = home_directory + settings_directory;
00035 #else
00036         if(home_directory == "data/")
00037         {
00038                 settings_path = home_directory + "settings";
00039         }
00040         else
00041         {
00042                 settings_path = home_directory + settings_directory;    
00043         }
00044 #endif
00045 
00046 #ifndef _WIN32
00047         data_directory = DATA_DIR;
00048 #else
00049         data_directory = "data";
00050 #endif
00051 
00052 /*
00053         cout << "**********Home dir: " << home_directory << endl;
00054         cout << "**********Settings dir: " << settings_directory << endl;
00055         cout << "**********Data dir: " << data_directory << endl;
00056 */
00057 #ifdef ENABLE_BINRELOC
00058         BrInitError br_err;
00059         int br_ret = br_init( &br_err );
00060         if( !br_ret )
00061         {
00062                 switch( br_err )
00063                 {
00064                 case BR_INIT_ERROR_NOMEM:
00065                         cout << "BinReloc: Can't allocate memory." << endl;
00066                         break;
00067                 case BR_INIT_ERROR_OPEN_MAPS:
00068                         cout << "BinReloc: Unable to open /proc/self/maps; see errno for details.." << endl;
00069                         break;
00070                 case BR_INIT_ERROR_READ_MAPS:
00071                         cout << "BinReloc: Unable to read from /proc/self/maps; see errno for details." << endl;
00072                         break;
00073                 case BR_INIT_ERROR_INVALID_MAPS:
00074                         cout << "BinReloc: The file format of /proc/self/maps is invalid; kernel bug?" << endl;
00075                         break;
00076                 case BR_INIT_ERROR_DISABLED:
00077                         cout << "BinReloc: BinReloc is disabled." << endl;
00078                         break;
00079                 default:
00080                         cout << "BinReloc: Unknown error." << endl;
00081                         break;
00082                 }
00083                 cout << "BinReloc failed, using hardcoded paths." << endl;
00084         }
00085         else
00086         {
00087                 cout << "BinReloc successfully initialized." << endl;
00088                 cout << "Executable path: " << br_find_exe( "/usr/share/games/vdrift/bin" ) << endl;
00089                 cout << "Data dir: " << br_find_prefix( "/usr/share/games/vdrift" );
00090                 cout << "/data" << endl;
00091                 data_directory = br_find_prefix( "/usr/share/games/vdrift" );
00092                 #ifdef ENABLE_NLS
00093                 cout << "Localedir: " << br_find_locale_dir( "/usr/share/locale" ) << endl;
00094                 locale_directory = br_find_locale_dir( "/usr/share/locale" );
00095                 #endif
00096                 data_directory += "/data";
00097         }
00098 #else
00099      #ifdef ENABLE_NLS
00100         locale_directory = LOCALEDIR;
00101         #endif
00102 #endif
00103 
00104         // Read saved settings
00105         configfile.Load((settings_path + "/VDrift.config").c_str());
00106         ParseSettings(configfile);
00107 
00108         string dconfig_filename = "";
00109         bool found_file = false;
00110         int chance = 0;
00111 
00112         do
00113         {
00114                 dconfig_filename = data_directory + "/settings/VDrift.config";
00115 
00116                 if( !FileExists( dconfig_filename.c_str() ) )
00117                 {
00118                 
00119                         cout << dconfig_filename;
00120                         cout << " not found.";
00121                         switch( chance )
00122                         {
00123                         case 0:
00124 #ifdef ENABLE_BINRELOC
00125                                 data_directory = br_find_exe_dir( "/usr/share/games/vdrift/bin" );
00126                                 data_directory += "/data";
00127 #else
00128                                 data_directory = "./data";
00129 #endif
00130                                 break;
00131                         case 1:
00132 #ifdef ENABLE_BINRELOC
00133                                 data_directory = br_find_prefix( "/usr/share/games/vdrift" );
00134                                 data_directory += "/data";
00135 #else
00136                                 data_directory = "../data";
00137 #endif
00138                                 break;
00139                         default:
00140                         case 2:
00141                                 cout << " Can't find data in directory with executable, or in parent dir. Giving up." << endl;
00142                                 exit(1);
00143                                 break;
00144                         }
00145                         cout << " Attempting to load data from " << data_directory << endl;
00146                         chance++;
00147                 }
00148                 else
00149                 {
00150                         found_file = true;
00151                 }
00152         }
00153         while( found_file = false );
00154 
00155         default_configfile.Load( ( data_directory + "/settings/VDrift.config" ).c_str() );
00156         options_configfile.Load( ( data_directory + "/settings/options.config" ).c_str() );
00157 
00158         Init();
00159 
00160         configfile.Load((settings_path + "/VDrift.config").c_str());
00161         ParseSettings(configfile);
00162 
00163         cout << "Version of game: " << VERSION << endl;
00164 /*
00165         if(!DirExists(data_directory))
00166         {
00167                 cout << endl;
00168                 cout << "WARNING!! Could not find the VDrift data directory. This is currently set to:" << endl;
00169                 cout << data_directory << endl;;
00170                 cout << "You may change this by editing " + settings_path + "/VDrift.config or by running vdrift thus:" << endl;
00171                 cout << "vdrift -datadir /path/to/vdrift/data" << endl;
00172                 cout << "Continuing to run, probably won't work..." << endl << endl;
00173         }
00174 */
00175 }
00176 
00177 SETTINGS::~SETTINGS()
00178 {
00179         // save the config file
00180         configfile.Write(true);
00181         configfile.Clear();
00182         default_configfile.Clear();
00183         car_parts.Clear();
00184         parts_list.clear();
00185         float_options.clear();
00186         int_options.clear();
00187         bool_options.clear();
00188         string_options.clear();
00189 }
00190 
00191 void SETTINGS::Init()
00192 {
00193         //bool write_defaults = false;
00194         spew = verbose_output;
00195         vector<string> files;
00196         files.push_back( "controls" );
00197         files.push_back( "VDrift.config" );
00198         /*
00199         files.push_back( "carsettings/CS" );
00200         files.push_back( "carsettings/XS" );
00201         files.push_back( "carsettings/GT" );
00202         files.push_back( "carsettings/XSR" );
00203         files.push_back( "carsettings/XM" );
00204         */
00205         vector<string> subdirs;
00206         subdirs.push_back( "replays/" );
00207         subdirs.push_back( "screenshots/" );
00208         subdirs.push_back( "logs/" );
00209         //subdirs.push_back( "carsettings/" );
00210         subdirs.push_back( "userdata/" );
00211  
00212         // Check for settings dir and create if non-existant (I think that a directory cannot be opened as a file)
00213         if(!FileExists(settings_path + "/VDrift.config"))
00214         {
00215                 // Whine
00216                 cout << "Can't find the settings directory at \"" + settings_path + "\". Making a new one..." << endl;
00217                 // Make it
00218                 CreateDir(settings_path);
00219 
00220                 // Copy file
00221                 default_configfile.Write( true, settings_path + "/VDrift.config" );
00222         }
00223 
00224         // Check for subdirs
00225         for( unsigned int i = 0; i < subdirs.size(); i++ )
00226         {
00227                 CreateDir(settings_path + "/" + subdirs[i]);
00228         }
00229 
00230         // Check for files
00231         for( unsigned int i = 0; i < files.size(); i++ )
00232         {
00233                 if( !FileExists( settings_path + "/" + files[i] ) )
00234                 {
00235                         cout << "Missing " + settings_path + "/" + files[i] + " file, copying." << endl;
00236                         utility.FileCopy( data_directory + "/settings/" + files[i], settings_path + "/" + files[i] );
00237                 }
00238                 else
00239                 {
00240                         cout << "Found config file " + settings_path + "/" + files[i] + "." << endl;
00241                 }
00242         }
00243 /*
00244         if( !FileExists( settings_path + "/controls" ) )
00245         {
00246                 keyman.Load();
00247                 gamecontrols.LoadControls( data_directory + "/settings/controls" );
00248                 gamecontrols.WriteControlFile( settings_path + "/controls" );
00249         }
00250 */
00251         files.clear();
00252         subdirs.clear();
00253 
00254 }
00255 
00256 void SETTINGS::ParseOptionFile()
00257 {
00258         spew = verbose_output;
00259         // fill in the options lists
00260         int num_options = 0;
00261         options_configfile.GetParam( ".num_options", num_options );
00262         for( int i = 0; i < num_options; i++ )
00263         {
00264                 ostringstream option_id;
00265                 option_id << "option-" << setfill( '0' ) << setw( 2 ) << i;
00266                 string opt_id = option_id.str();
00267                 string cat, name, title, desc, type;
00268                 
00269                 if( !options_configfile.GetParam( opt_id + ".cat", cat ) )
00270                 {
00271                         cout << "Error: " << opt_id << " is missing its category." << endl;
00272                         cat = "";
00273                 }
00274 
00275                 if( !options_configfile.GetParam( opt_id + ".name", name ) )
00276                 {
00277                         cout << "Error: " << opt_id << " is missing its name." << endl;
00278                         name = "";
00279                 }
00280 
00281                 if( !options_configfile.GetParam( opt_id + ".title", title ) )
00282                 {
00283                         cout << "Error: " << opt_id << " is missing its title." << endl;
00284                         cat = "";
00285                 }
00286 
00287                 if( !options_configfile.GetParam( opt_id + ".desc", desc ) )
00288                 {
00289                         cout << "Error: " << opt_id << " is missing its description." << endl;
00290                         cat = "";
00291                 }
00292 
00293                 if( !options_configfile.GetParam( opt_id + ".type", type ) )
00294                 {
00295                         cout << "Error: " << opt_id << " is missing its type." << endl;
00296                         cat = "";
00297                 }
00298 
00299                 if( type == "int" )
00300                 {
00301                         OPTION<int> opt;
00302                         string val_type = "";
00303                         int default_val = 0;
00304 
00305                         opt.SetCat( cat );
00306                         opt.SetName( name );
00307                         opt.SetTitle( title );
00308                         opt.SetDesc( desc );
00309 
00310                         if( !options_configfile.GetParam( opt_id + ".default", default_val ) )
00311                         {
00312                                 cout << "Error: " << opt_id << " is missing its default value." << endl;
00313                         }
00314                         opt.SetDefaultValue( default_val );
00315 
00316                         if( !options_configfile.GetParam( opt_id + ".values", val_type ) )
00317                         {
00318                                 cout << "Error: " << opt_id << " is missing its values type." << endl;
00319                         }
00320 
00321                         if( val_type == "list" )
00322                         {
00323                                 int num_vals = 0;
00324                                 vector<string> opts;
00325                                 vector<int> vals;
00326                                 if( !options_configfile.GetParam( opt_id + ".num_vals", num_vals ) )
00327                                 {
00328                                         cout << "Error: " << opt_id << " is missing its values list number." << endl;
00329                                 }
00330                                 for( int j = 0; j < num_vals; j++ )
00331                                 {
00332                                         string opt = "";
00333                                         int val = 0;
00334                                         ostringstream value_id_num;
00335                                         value_id_num << setfill( '0' ) << setw( 2 ) << j;
00336                                         string v_id = opt_id + ".val" + value_id_num.str();
00337                                         string o_id = opt_id + ".opt" + value_id_num.str();
00338 
00339                                         if( !options_configfile.GetParam( v_id, val ) )
00340                                         {
00341                                                 cout << "Error: " << v_id << " is missing." << endl;
00342                                         }
00343                                         if( !options_configfile.GetParam( o_id, opt ) )
00344                                         {
00345                                                 cout << "Error: " << o_id << " is missing." << endl;
00346                                         }
00347                                         opts.push_back( opt );
00348                                         vals.push_back( val );
00349                                 }
00350                                 opt.SetValueList( vals );
00351                                 opt.SetOptionList( opts );
00352                         }
00353                         else if( val_type == "car_paints" )
00354                         {
00355                         /*
00356                                 list<string> carlist;
00357                                 string folderpath = data_directory + "/cars";
00358                                 utility.GetFolderIndex(folderpath, carlist);
00359                                 for( list<string>::iterator i = carlist.begin(); i != carlist.end(); ++i )
00360                                 {
00361                                         // create a list of paints for each car...
00362                                         string car_about_filename = data_directory + "/cars/" + *i + "/about.txt";
00363                                         if( utility.FileExists( car_about_filename ) )
00364                                         {
00365                                                 ifstream car_about_file;
00366                                                 car_about_file.open( car_about_filename.c_str() );
00367                                                 string car_name = utility.sGetLine( car_about_file );
00368                                                 vals.push_back( *i );
00369                                                 opts.push_back( car_name );
00370                                         }
00371                                 }
00372                         */
00373                         }
00374                         else if( val_type == "resolution_widths" )
00375                         {
00376                                 /*
00377                                  * this option is processed later in ParseDynamicOptions()
00378                                  */
00379                                 vector<string> opts;
00380                                 vector<int> vals;
00381                                 opts.push_back( "" );
00382                                 vals.push_back( 0 );
00383                                 opt.SetValueList( vals );
00384                                 opt.SetOptionList( opts );
00385                         }
00386                         else if( val_type == "resolution_heights" )
00387                         {
00388                                 /*
00389                                  * this option is processed later in ParseDynamicOptions()
00390                                  */
00391                                 vector<string> opts;
00392                                 vector<int> vals;
00393                                 opts.push_back( "" );
00394                                 vals.push_back( 0 );
00395                                 opt.SetValueList( vals );
00396                                 opt.SetOptionList( opts );
00397                         }
00398                         else if( val_type == "joy_indeces" )
00399                         {
00400                                 /*
00401                                  * this option is processed later in ParseDynamicOptions()
00402                                  */
00403                                 vector<string> opts;
00404                                 vector<int> vals;
00405                                 opts.push_back( "X" );
00406                                 vals.push_back( 0 );
00407                                 opt.SetValueList( vals );
00408                                 opt.SetOptionList( opts );
00409                         }
00410                         else if( val_type == "anisotropy" )
00411                         {
00412                                 /*
00413                                  * this option is processed later in ParseDynamicOptions()
00414                                  */
00415                                 vector<string> opts;
00416                                 vector<int> vals;
00417                                 opts.push_back( "" );
00418                                 vals.push_back( 0 );
00419                                 opt.SetValueList( vals );
00420                                 opt.SetOptionList( opts );
00421                         }
00422                         else
00423                         {
00424                                 cout << "Error: " << opt_id << " bad or empty values type! this option will not have values." << endl;
00425                         }
00426 
00427                         int_options.push_back( opt );
00428                 }
00429                 else if( type == "bool" )
00430                 {
00431                         OPTION<bool> opt;
00432                         string val_type = "";
00433                         bool default_val = false;
00434                         string true_val, false_val;
00435 
00436                         opt.SetCat( cat );
00437                         opt.SetName( name );
00438                         opt.SetTitle( title );
00439                         opt.SetDesc( desc );
00440 
00441                         if( !options_configfile.GetParam( opt_id + ".default", default_val ) )
00442                         {
00443                                 cout << "Error: " << opt_id << " is missing its default value." << endl;
00444                         }
00445                         opt.SetDefaultValue( default_val );
00446 
00447                         if( !options_configfile.GetParam( opt_id + ".values", val_type ) )
00448                         {
00449                                 cout << "Error: " << opt_id << " is missing its values type." << endl;
00450                         }
00451 
00452                         if( val_type == "bool" )
00453                         {
00454                                 if( !options_configfile.GetParam( opt_id + ".true", true_val ) )
00455                                 {
00456                                         true_val = "True";
00457                                 }
00458                                 opt.SetTrueValue( true_val );
00459 
00460                                 if( !options_configfile.GetParam( opt_id + ".false", false_val ) )
00461                                 {
00462                                         false_val = "False";
00463                                 }
00464                                 opt.SetFalseValue( false_val );
00465                         }
00466                         else
00467                         {
00468                                 cout << "Error: " << opt_id << " bad or empty values type! this option will not have values." << endl;
00469                         }
00470 
00471                         bool_options.push_back( opt );
00472                 }
00473                 else if( type == "string" )
00474                 {
00475                         OPTION<string> opt;
00476                         string val_type = "";
00477                         string default_val = "";
00478 
00479                         opt.SetCat( cat );
00480                         opt.SetName( name );
00481                         opt.SetTitle( title );
00482                         opt.SetDesc( desc );
00483 
00484                         if( !options_configfile.GetParam( opt_id + ".default", default_val ) )
00485                         {
00486                                 cout << "Error: " << opt_id << " is missing its default value." << endl;
00487                         }
00488                         opt.SetDefaultValue( default_val );
00489 
00490                         if( !options_configfile.GetParam( opt_id + ".values", val_type ) )
00491                         {
00492                                 cout << "Error: " << opt_id << " is missing its values type." << endl;
00493                         }
00494 
00495                         if( val_type == "list" )
00496                         {
00497                                 int num_vals = 0;
00498                                 vector<string> opts;
00499                                 vector<string> vals;
00500                                 if( !options_configfile.GetParam( opt_id + ".num_vals", num_vals ) )
00501                                 {
00502                                         cout << "Error: " << opt_id << " is missing its values list number." << endl;
00503                                 }
00504                                 for( int j = 0; j < num_vals; j++ )
00505                                 {
00506                                         string opt = "";
00507                                         string val = "";
00508                                         ostringstream value_id_num;
00509                                         value_id_num << setfill( '0' ) << setw( 2 ) << j;
00510                                         string v_id = opt_id + ".val" + value_id_num.str();
00511                                         string o_id = opt_id + ".opt" + value_id_num.str();
00512 
00513                                         if( !options_configfile.GetParam( v_id, val ) )
00514                                         {
00515                                                 cout << "Error: " << v_id << " is missing." << endl;
00516                                         }
00517                                         if( !options_configfile.GetParam( o_id, opt ) )
00518                                         {
00519                                                 cout << "Error: " << o_id << " is missing." << endl;
00520                                         }
00521                                         opts.push_back( opt );
00522                                         vals.push_back( val );
00523                                 }
00524                                 opt.SetValueList( vals );
00525                                 opt.SetOptionList( opts );
00526                         }
00527                         else if( val_type == "ip_valid" )
00528                         {
00529                                 opt.SetAccepts( "0123456789." );
00530                         }
00531                         else if( val_type == "port_valid" )
00532                         {
00533                                 opt.SetAccepts( "0123456789" );
00534                         }
00535                         else if( val_type == "tracks" )
00536                         {
00537                                 vector<string> opts;
00538                                 vector<string> vals;
00539                                 list<string> tracklist;
00540                                 string folderpath = data_directory + "/tracks";
00541                                 utility.GetFolderIndex(folderpath, tracklist);
00542                                 for( list<string>::iterator i = tracklist.begin(); i != tracklist.end(); ++i )
00543                                 {
00544                                         string track_about_filename = data_directory + "/tracks/" + *i + "/about.txt";
00545                                         if( utility.FileExists( track_about_filename ) )
00546                                         {
00547                                                 ifstream track_about_file;
00548                                                 track_about_file.open( track_about_filename.c_str() );
00549                                                 string track_name = utility.sGetLine( track_about_file );
00550                                                 vals.push_back( *i );
00551                                                 opts.push_back( track_name );
00552                                         }
00553                                 }
00554                                 opt.SetValueList( vals );
00555                                 opt.SetOptionList( opts );
00556                         }
00557                         else if( val_type == "cars" )
00558                         {
00559                                 vector<string> opts;
00560                                 vector<string> vals;
00561                                 list<string> carlist;
00562                                 string folderpath = data_directory + "/cars";
00563                                 utility.GetFolderIndex(folderpath, carlist);
00564                                 for( list<string>::iterator i = carlist.begin(); i != carlist.end(); ++i )
00565                                 {
00566                                         string car_about_filename = data_directory + "/cars/" + *i + "/about.txt";
00567                                         if( utility.FileExists( car_about_filename ) )
00568                                         {
00569                                                 ifstream car_about_file;
00570                                                 car_about_file.open( car_about_filename.c_str() );
00571                                                 string car_name = utility.sGetLine( car_about_file );
00572                                                 vals.push_back( *i );
00573                                                 opts.push_back( car_name );
00574                                         }
00575                                 }
00576                                 opt.SetValueList( vals );
00577                                 opt.SetOptionList( opts );
00578                         }
00579                         else
00580                         {
00581                                 cout << "Error: " << opt_id << " bad or empty values type! this option will not have values." << endl;
00582                         }
00583 
00584                         string_options.push_back( opt );
00585                 }
00586                 else if( type == "float" )
00587                 {
00588                         OPTION<float> opt;
00589                         string val_type = "";
00590                         float default_val = 0;
00591 
00592                         opt.SetCat( cat );
00593                         opt.SetName( name );
00594                         opt.SetTitle( title );
00595                         opt.SetDesc( desc );
00596 
00597                         if( !options_configfile.GetParam( opt_id + ".default", default_val ) )
00598                         {
00599                                 cout << "Error: " << opt_id << " is missing its default value." << endl;
00600                         }
00601                         opt.SetDefaultValue( default_val );
00602 
00603                         if( !options_configfile.GetParam( opt_id + ".values", val_type ) )
00604                         {
00605                                 cout << "Error: " << opt_id << " is missing its values type." << endl;
00606                         }
00607 
00608                         if( val_type == "list" )
00609                         {
00610                                 int num_vals = 0;
00611                                 vector<string> opts;
00612                                 vector<float> vals;
00613                                 if( !options_configfile.GetParam( opt_id + ".num_vals", num_vals ) )
00614                                 {
00615                                         cout << "Error: " << opt_id << " is missing its values list number." << endl;
00616                                 }
00617                                 for( int j = 0; j < num_vals; j++ )
00618                                 {
00619                                         string opt = "";
00620                                         float val = 0.0;
00621                                         ostringstream value_id_num;
00622                                         value_id_num << setfill( '0' ) << setw( 2 ) << j;
00623                                         string v_id = opt_id + ".val" + value_id_num.str();
00624                                         string o_id = opt_id + ".opt" + value_id_num.str();
00625 
00626                                         if( !options_configfile.GetParam( v_id, val ) )
00627                                         {
00628                                                 cout << "Error: " << v_id << " is missing." << endl;
00629                                         }
00630                                         if( !options_configfile.GetParam( o_id, opt ) )
00631                                         {
00632                                                 cout << "Error: " << o_id << " is missing." << endl;
00633                                         }
00634                                         opts.push_back( opt );
00635                                         vals.push_back( val );
00636                                 }
00637                                 opt.SetValueList( vals );
00638                                 opt.SetOptionList( opts );
00639                         }
00640                         else if( val_type == "float" )
00641                         {
00642                                 float min_val, max_val;
00643                                 min_val = 0.0f;
00644                                 max_val = 1.0f;
00645 
00646                                 options_configfile.GetParam( opt_id + ".min", min_val );
00647                                 opt.SetMinValue( min_val );
00648                                 options_configfile.GetParam( opt_id + ".max", max_val );
00649                                 opt.SetMaxValue( max_val );
00650                         }
00651                         else
00652                         {
00653                                 cout << "Error: " << opt_id << " bad or empty values type! this option will not have values." << endl;
00654                         }
00655 
00656                         float_options.push_back( opt );
00657                 }
00658                 else
00659                 {
00660                         cout << "Error: " << opt_id <<  "bad or empty option type! this option will not be added." << endl;
00661                 }
00662         }
00663 }
00664 
00665 void SETTINGS::ParseDynamicOptions()
00666 {
00667         // generate list of valid video modes
00668         GetValidVideoModes();
00669 
00670         vector< OPTION<int> >::iterator int_opt_iter;
00671         vector< OPTION<string> >::iterator string_opt_iter;
00672         string opt_full_name;
00673 
00674         for( int_opt_iter = int_options.begin(); int_opt_iter != int_options.end(); ++int_opt_iter )
00675         {
00676                 vector<int> vals;
00677                 vector<string> opts;
00678                 opt_full_name = int_opt_iter->GetCat() + "." + int_opt_iter->GetName();
00679         
00680                 if( opt_full_name == "display.width" )
00681                 {
00682                         vector<SDL_Rect> modes = valid_display_modes.GetModes();
00683                         vector<SDL_Rect>::iterator modes_iter;
00684                         for( modes_iter = modes.begin(); modes_iter != modes.end(); ++modes_iter )
00685                         {
00686                                 ostringstream wstream;
00687                                 wstream << modes_iter->w;
00688                                 string width = wstream.str();
00689                                 ostringstream hstream;
00690                                 hstream << modes_iter->h;
00691                                 string height = hstream.str();
00692                                 vals.push_back( modes_iter->w );
00693                                 opts.push_back( width + "x" + height );
00694                         }
00695                         int_opt_iter->SetValueList( vals );
00696                         int_opt_iter->SetOptionList( opts );
00697                 }
00698                 else if( opt_full_name == "display.height" )
00699                 {
00700                         vector<SDL_Rect> modes = valid_display_modes.GetModes();
00701                         vector<SDL_Rect>::iterator modes_iter;
00702                         for( modes_iter = modes.begin(); modes_iter != modes.end(); ++modes_iter )
00703                         {
00704                                 ostringstream wstream;
00705                                 wstream << modes_iter->h;
00706                                 string width = wstream.str();
00707                                 vals.push_back( modes_iter->h );
00708                                 opts.push_back( width );
00709                         }
00710                         int_opt_iter->SetValueList( vals );
00711                         int_opt_iter->SetOptionList( opts );
00712                 }
00713                 else if( opt_full_name == "joystick.selected_index" )
00714                 {
00715                         int num_joysticks = SDL_NumJoysticks();
00716                         for( int i = 0; i < num_joysticks; i++ )
00717                         {
00718                                 ostringstream j;
00719                                 j << "Joystick ";
00720                                 j << i;
00721                                 opts.push_back( j.str() );
00722                                 vals.push_back( i );
00723                         }
00724                         int_opt_iter->SetValueList( vals );
00725                         int_opt_iter->SetOptionList( opts );
00726                 }
00727                 else if( opt_full_name == "display.anisotropic" )
00728                 {
00729                         int card_max_anisotropy = gfxcard.GetCapability(CARDINFOTYPE::MAXANISOTROPY);
00730                         int a = 0;
00731                         for( int i = -1; a < card_max_anisotropy; ++i )
00732                         {
00733                                 a = ( i < 1 ) ? i + 1 : int( pow( 2.0, i ) );
00734                                 ostringstream al;
00735                                 if( a == 0 )
00736                                 {
00737                                         al << "Off";
00738                                 }
00739                                 else
00740                                 {
00741                                         al << a;
00742                                         al << "x";
00743                                 }
00744                                 opts.push_back( al.str() );
00745                                 vals.push_back( a );
00746                         }
00747                         int_opt_iter->SetValueList( vals );
00748                         int_opt_iter->SetOptionList( opts );
00749                 }
00750         }
00751 }
00752 
00753 void SETTINGS::GetValidVideoModes()
00754 {
00755         int videoFlags = SDL_OPENGL;       /* Enable OpenGL in SDL */
00756         videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
00757         videoFlags |= SDL_HWPALETTE;       /* Store the palette in hardware */
00758         videoFlags |= SDL_RESIZABLE;       /* Enable window resizing */
00759         videoFlags |= SDL_HWSURFACE|SDL_ANYFORMAT|SDL_FULLSCREEN;  
00760 
00761         /* Get available fullscreen/hardware modes */
00762         SDL_Rect **tmodes = SDL_ListModes( NULL, SDL_HWSURFACE | SDL_FULLSCREEN );
00763         vector<SDL_Rect> modes;
00764         
00765         // put all dynamic determined modes into the vector
00766         for( int i = 0; tmodes[i] != NULL; i++ )
00767         {
00768                 modes.push_back( *tmodes[i] );
00769         }
00770 
00771         ifstream vmf;
00772         vmf.open( GetFullDataPath( "lists/videomodes" ).c_str() );
00773         while( !vmf.eof() )
00774         {
00775                 int w, h;
00776                 vmf >> w;
00777                 vmf >> h;
00778 
00779                 if( !vmf.eof() )
00780                 {
00781                         // put all valid modes from the videomodes file into the vector
00782                         if( SDL_VideoModeOK( w,h, 16, videoFlags ) ) 
00783                         {                       
00784                                 SDL_Rect r = {0, 0, w, h};
00785                                 modes.push_back( r );
00786                         }
00787                 }
00788         }
00789 
00790         // sort vector by (w*h)
00791         sort( modes.begin(), modes.end(), gt_rect );
00792         // make items in vector unique
00793         vector<SDL_Rect>::iterator new_end = unique( modes.begin(), modes.end(), eq_rect );
00794         vector<SDL_Rect> unique_modes;
00795         for( vector<SDL_Rect>::iterator mi = modes.begin(); mi != new_end; ++mi )
00796         {
00797                 unique_modes.push_back( *mi );
00798         }
00799         valid_display_modes.SetModes( unique_modes );
00800 }
00801 
00802 
00803 void SETTINGS::CreateDir(string path)
00804 {
00805 #ifndef _WIN32
00806         // use mode 755
00807         mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
00808 #else
00809         mkdir(path.c_str());
00810 #endif
00811 }
00812 
00813 void SETTINGS::FindHomeDir()
00814 {
00815         // Figure out the user's home directory - POSIX only...
00816         char *homedir;
00817 #ifndef _WIN32
00818         homedir = getenv("HOME");
00819         if (homedir == NULL)
00820         {
00821                 homedir = getenv("USER");
00822                 if (homedir == NULL)
00823                 {
00824                         homedir = getenv("USERNAME");
00825                         if (homedir == NULL)
00826                         {
00827                                 fprintf( stderr, "Could not find user's home directory!\n" );
00828                                 //Quit( 1 );
00829                         }
00830                 }
00831                 home_directory = "/home/";
00832         }
00833 #else
00834         homedir = getenv("USERPROFILE");
00835         if(homedir == NULL)
00836         {
00837             homedir = "data"; // WIN 9x/Me
00838         }
00839 #endif
00840         home_directory += homedir;
00841         home_directory += "/";
00842 }
00843 
00844 /*
00845 bool SETTINGS::FileExists(string path)
00846 {
00847         int result;
00848         struct stat dir_stat;
00849         result = stat(path.c_str(), &dir_stat);
00850         return ( result == 0 );
00851 }
00852 
00853 bool SETTINGS::DirExists(string path)
00854 {
00855         int result;
00856         struct stat dir_stat;
00857         result = stat(path.c_str(), &dir_stat);
00858         return  S_ISDIR(dir_stat.st_mode);
00859 }
00860 */
00861 
00862 bool SETTINGS::FileExists(string path)
00863 {
00864         bool result;
00865         ifstream testfile(path.c_str());
00866         result = !testfile.fail();
00867         return result;
00868 
00869         /*return utility.FileExists(path);*/
00870 }
00871 
00872 void SETTINGS::SaveSettings(CONFIGFILE &c)
00873 {
00874         // set the current parameters in the config file
00875 
00876         c.SetParam("main.data_dir", data_directory);
00877         c.SetParam("main.version", config_version);
00878 }
00879 
00880 void SETTINGS::ParseSettings(CONFIGFILE &c)
00881 {
00882 #ifndef __APPLE__
00883 #ifndef _WIN32
00884         string d_dir;
00885         if( c.GetParam( "main.data_dir", d_dir ) )
00886         {
00887                 //data_directory = "/usr/share/games/vdrift"; /*TODO: should not be hardcoded*/
00888                 //c.SetParam("main.data_dir", data_directory);
00889                 data_directory = d_dir;
00890         }
00891         else
00892         {
00893                 cout << "No data_dir found in VDrift.config, using " << data_directory << endl;
00894         }
00895 #else
00896         data_directory = "data";
00897 #endif
00898 #endif
00899 }
00900 
00901 vector<string> SETTINGS::LoadCarPartsSettings()
00902 {
00903         string game_car;
00904         Get( "game.selected_car", game_car );
00905         string filename = settings.GetSettingsDir() + "/carsettings/" + game_car;
00906         char partid[256];
00907         int i = 0;
00908         string part;
00909         parts_list.clear();
00910         car_parts.Clear();
00911 
00912         car_parts.Load( filename.c_str() );
00913         car_parts.SuppressError( true );
00914         sprintf( partid, "parts.part-%02d", i );
00915 
00916         while( car_parts.GetParam( partid, part ) )
00917         {
00918                 //cout << "part loaded: " << part;
00919                 parts_list.push_back( part );
00920                 i++;
00921                 sprintf( partid, "parts.part-%02d", i );
00922         }
00923         return parts_list;
00924 }
00925 
00926 void SETTINGS::SaveCarPartsSettings(vector<string> &p_list)
00927 {
00928         char partid[256];
00929         for(int i = 0; i < 100; i++)
00930         {
00931                 sprintf( partid, "parts.part-%02d", i );
00932                 car_parts.ClearParam(partid);
00933         }
00934         for(unsigned int i = 0; i < p_list.size(); i++)
00935         {
00936                 sprintf( partid, "parts.part-%02d", i );
00937                 car_parts.SetParam( partid, p_list[i] );
00938         }
00939         car_parts.Write();
00940 }
00941 
00942 string SETTINGS::GetCarPartName(string part_path)
00943 {
00944         string filename = settings.GetFullDataPath("carparts/" + part_path);
00945         CONFIGFILE part_file;
00946         string result;
00947         part_file.Load(filename.c_str());
00948         part_file.GetParam(".partname", result);
00949         return result;
00950 }
00951 
00952 string SETTINGS::GetDataDir()
00953 {
00954         return data_directory;
00955 }
00956 
00957 string SETTINGS::GetDataDir(string filename)
00958 {
00959 #ifndef _WIN32
00960         if(FileExists(settings_path + "/userdata/" + filename))
00961                 return (settings_path + "/userdata");
00962         else
00963 #endif
00964                 return data_directory;
00965 }
00966 
00967 #ifdef ENABLE_NLS
00968 string SETTINGS::GetLocaleDir()
00969 {
00970         return locale_directory;
00971 }
00972 #endif
00973 
00974 string SETTINGS::GetFullDataPath(string filename)
00975 {
00976         return ( GetDataDir( filename ) + "/" + filename );
00977 }
00978 
00979 string SETTINGS::GetHomeDir()
00980 {
00981         return home_directory;
00982 }
00983 
00984 string SETTINGS::GetSettingsDir()
00985 {
00986         return settings_path;
00987 }
00988 
00989 void SETTINGS::SetDataDir(string new_data_dir)
00990 {
00991         data_directory = new_data_dir;
00992 }
00993 
00994 void SETTINGS::SetDefaultDataDir(string new_data_dir)
00995 {
00996         CONFIGFILE default_config((new_data_dir + "/settings/VDrift.config").c_str());
00997         ParseSettings(default_config);
00998         data_directory = new_data_dir;
00999         SaveSettings(default_config);
01000 }
01001 
01002 string SETTINGS::GetSkinPath()
01003 {
01004         string skin_path = "skins/";
01005         string skin_dir = "simple";
01006         if( !Get( "display.skin", skin_dir ) )
01007         {
01008                 cout << "Skin name not found in config file..." << endl;
01009         }
01010 
01011         skin_path += skin_dir;
01012 
01013         return skin_path;
01014 }
01015 
01016 
01017 bool SETTINGS::Get( string val_name, float & out_var )
01018 {
01019         vector< OPTION<float> >::iterator opt_iter;
01020         string opt_full_name;
01021 
01022         if( spew ) cout << "Getting float value " << val_name << "...";
01023 
01024         for( opt_iter = float_options.begin(); opt_iter != float_options.end(); ++opt_iter )
01025         {
01026                 opt_full_name = opt_iter->GetCat() + "." + opt_iter->GetName();
01027 
01028                 if( val_name == opt_full_name )
01029                 {
01030                         if( spew ) cout << "this is a float value...";
01031 
01032                         if( !configfile.GetParam( val_name, out_var ) )
01033                         {
01034                                 if( spew ) cout << "can't find value in local config, fetching default...";
01035                                 out_var = opt_iter->GetDefaultValue();
01036                                 configfile.SetParam( val_name, out_var );
01037                         }
01038 
01039                         if( spew ) cout << "found value: [" << out_var << "]. done." << endl;
01040 
01041                         return true;
01042                 }
01043 
01044         }
01045         if( spew ) cout << "this is not a float value." << endl;
01046         return false;
01047 }
01048 /*
01049 bool SETTINGS::Get( string val_name, float * out_var )
01050 {
01051         if( spew ) cout << "Getting vector value " << val_name << "...";
01052         for( string::size_type i = 0; i < vec_settings.size(); i++ )
01053         {
01054                 if( val_name == vec_settings[i] )
01055                 {
01056                         if( spew ) cout << "this is a vector value...";
01057                         if( !configfile.GetParam( val_name, out_var ) )
01058                         {
01059                                 if( spew ) cout << "can't find value in local config, fetching default...";
01060                                 default_configfile.GetParam( val_name, out_var );
01061                                 configfile.SetParam( val_name, out_var );
01062                         }
01063                         if( spew ) cout << "found value: [" << out_var << "]. done." << endl;
01064                         return true;
01065                 }
01066         }
01067         if( spew ) cout << "this is not a vector value." << endl;
01068         return false;
01069 }
01070 */
01071 bool SETTINGS::Get( string val_name, int & out_var )
01072 {
01073         vector< OPTION<int> >::iterator opt_iter;
01074         string opt_full_name;
01075 
01076         if( spew ) cout << "Getting int value " << val_name << "...";
01077 
01078         for( opt_iter = int_options.begin(); opt_iter != int_options.end(); ++opt_iter )
01079         {
01080                 opt_full_name = opt_iter->GetCat() + "." + opt_iter->GetName();
01081 
01082                 if( val_name == opt_full_name )
01083                 {
01084                         if( spew ) cout << "this is a int value...";
01085                         if( !configfile.GetParam( val_name, out_var ) )
01086                         {
01087                                 if( spew ) cout << "can't find value in local config, fetching default...";
01088                                 out_var = opt_iter->GetDefaultValue();
01089                                 configfile.SetParam( val_name, out_var );
01090                         }
01091                         if( spew ) cout << "found value: [" << out_var << "]. done." << endl;
01092                         return true;
01093                 }
01094         }
01095         if( spew ) cout << "this is not an int value." << endl;
01096         return false;
01097 }
01098 
01099 bool SETTINGS::Get( string val_name, string & out_var )
01100 {
01101         vector< OPTION<string> >::iterator opt_iter;
01102         string opt_full_name;
01103 
01104         if( spew ) cout << "Getting string value " << val_name << "...";
01105 
01106         for( opt_iter = string_options.begin(); opt_iter != string_options.end(); ++opt_iter )
01107         {
01108                 opt_full_name = opt_iter->GetCat() + "." + opt_iter->GetName();
01109 
01110                 if( val_name == opt_full_name )
01111                 {
01112                         if( spew ) cout << "this is a string value...";
01113                         if( !configfile.GetParam( val_name, out_var ) )
01114                         {
01115                                 if( spew ) cout << "can't find value in local config, fetching default...";
01116                                 out_var = opt_iter->GetDefaultValue();
01117                                 configfile.SetParam( val_name, out_var );
01118                         }
01119                         
01120                         if( spew ) cout << "found value: [" << out_var << "]. done." << endl;
01121                         
01122                         return true;
01123                 }
01124         }
01125         
01126         if( spew ) cout << "this is not a string value." << endl;
01127                 
01128         return false;
01129         //return configfile.GetParam(val_name, out_var);
01130 }
01131 
01132 bool SETTINGS::Get( string val_name, bool & out_var )
01133 {
01134         vector< OPTION<bool> >::iterator opt_iter;
01135         string opt_full_name;
01136 
01137         if( spew ) cout << "Getting bool value " << val_name << "...";
01138 
01139         for( opt_iter = bool_options.begin(); opt_iter != bool_options.end(); ++opt_iter )
01140         {
01141                 opt_full_name = opt_iter->GetCat() + "." + opt_iter->GetName();
01142 
01143                 if( val_name == opt_full_name )
01144                 {
01145                         if( spew ) cout << "this is a bool value...";
01146                         if( !configfile.GetParam( val_name, out_var ) )
01147                         {
01148                                 if( spew ) cout << "can't find value in local config, fetching default...";
01149                                 out_var = opt_iter->GetDefaultValue();
01150                                 configfile.SetParam( val_name, out_var );
01151                         }
01152                         if( spew ) cout << "found value: [" << out_var << "]. done." << endl;
01153                         return true;
01154                 }
01155         }
01156         if( spew ) cout << "this is not a bool value." << endl;
01157         return false;
01158 }
01159 
01160 bool SETTINGS::Set( string val_name, float in_var )
01161 {
01162         vector< OPTION<float> >::iterator opt_iter;
01163         string opt_full_name;
01164 
01165         if( spew ) cout << "Setting float value " << val_name << "...";
01166 
01167         for( opt_iter = float_options.begin(); opt_iter != float_options.end(); ++opt_iter )
01168         {
01169                 opt_full_name = opt_iter->GetCat() + "." + opt_iter->GetName();
01170 
01171                 if( val_name == opt_full_name )
01172                 {
01173                         if( spew ) cout << "this is a float value...setting to [" << in_var << "]...done." << endl;
01174                         return configfile.SetParam( val_name, in_var );
01175                 }
01176         }
01177         if( spew ) cout << "this is not a float value." << endl;
01178         return false;
01179 }
</