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
00025 spew = verbose_output;
00026
00027
00028 FindHomeDir();
00029
00030
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
00054
00055
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
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
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 }
00176
00177 SETTINGS::~SETTINGS()
00178 {
00179
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
00194 spew = verbose_output;
00195 vector<string> files;
00196 files.push_back( "controls" );
00197 files.push_back( "VDrift.config" );
00198
00199
00200
00201
00202
00203
00204
00205 vector<string> subdirs;
00206 subdirs.push_back( "replays/" );
00207 subdirs.push_back( "screenshots/" );
00208 subdirs.push_back( "logs/" );
00209
00210 subdirs.push_back( "userdata/" );
00211
00212
00213 if(!FileExists(settings_path + "/VDrift.config"))
00214 {
00215
00216 cout << "Can't find the settings directory at \"" + settings_path + "\". Making a new one..." << endl;
00217
00218 CreateDir(settings_path);
00219
00220
00221 default_configfile.Write( true, settings_path + "/VDrift.config" );
00222 }
00223
00224
00225 for( unsigned int i = 0; i < subdirs.size(); i++ )
00226 {
00227 CreateDir(settings_path + "/" + subdirs[i]);
00228 }
00229
00230
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
00245
00246
00247
00248
00249
00250
00251 files.clear();
00252 subdirs.clear();
00253
00254 }
00255
00256 void SETTINGS::ParseOptionFile()
00257 {
00258 spew = verbose_output;
00259
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
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 }
00374 else if( val_type == "resolution_widths" )
00375 {
00376
00377
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
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
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
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
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;
00756 videoFlags |= SDL_GL_DOUBLEBUFFER;
00757 videoFlags |= SDL_HWPALETTE;
00758 videoFlags |= SDL_RESIZABLE;
00759 videoFlags |= SDL_HWSURFACE|SDL_ANYFORMAT|SDL_FULLSCREEN;
00760
00761
00762 SDL_Rect **tmodes = SDL_ListModes( NULL, SDL_HWSURFACE | SDL_FULLSCREEN );
00763 vector<SDL_Rect> modes;
00764
00765
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
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
00791 sort( modes.begin(), modes.end(), gt_rect );
00792
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
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
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
00829 }
00830 }
00831 home_directory = "/home/";
00832 }
00833 #else
00834 homedir = getenv("USERPROFILE");
00835 if(homedir == NULL)
00836 {
00837 homedir = "data";
00838 }
00839 #endif
00840 home_directory += homedir;
00841 home_directory += "/";
00842 }
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
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
00870 }
00871
00872 void SETTINGS::SaveSettings(CONFIGFILE &c)
00873 {
00874
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
00888
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
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
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
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
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 }