Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef HAVE_CONFIG_H
00023 #include <config.h>
00024 #endif
00025 #include <getopt.h>
00026 #include <stdio.h>
00027 #include <iostream>
00028 #include <sys/stat.h>
00029 #include <dirent.h>
00030 #include <unistd.h>
00031 #include "prefs.h"
00032 #include "python_class.h"
00033 #include "game.h"
00034
00035 config::config ()
00036 {
00037
00038 #if defined (WIN32) || defined (__APPLE__)
00039 screen_mode = 1;
00040 #else
00041 screen_mode = 0;
00042 #endif
00043 #if defined (QTOPIA)
00044 double_screen = 0;
00045 #else
00046 double_screen = 1;
00047 #endif
00048 quick_load = 0;
00049 audio_channels = 1;
00050 audio_resolution = 1;
00051 audio_sample_rate = 2;
00052 audio_volume = 100;
00053 language = "";
00054 font = "";
00055
00056
00057 #ifndef SINGLE_DIR_INST
00058 adonthellrc = string (getenv ("HOME")) + "/.adonthell";
00059 #else
00060 adonthellrc = string (".");
00061 #endif
00062 }
00063
00064
00065
00066
00067
00068 void print_help_message (char * argv[])
00069 {
00070 cout << "Usage: " << argv[0] << " [OPTIONS] GAME" << endl;
00071 cout << endl;
00072 cout << "Where [OPTIONS] can be:\n";
00073 cout << "-h print this help message" << endl;
00074 cout << "-d print the data directory and exit" << endl;
00075 cout << "-v print version and exit" << endl;
00076 cout << "-l list installed games and exit" << endl;
00077 cout << "-g dir play the game contained in dir (for development only)" << endl;
00078 cout << "-c byte-compile all Python scripts in this directory (for " << endl;
00079 cout << " development only)" << endl;
00080 }
00081
00082
00083
00084
00085
00086 void print_available_games ()
00087 {
00088 struct dirent * d;
00089 DIR * mydir = opendir ((game::global_data_dir() + "/games").c_str());
00090 bool nogames = true;
00091
00092 if (!mydir)
00093 {
00094 cerr << "Cannot open directory " << game::global_data_dir() + "/games!" << endl;
00095 exit (1);
00096 }
00097
00098 while ((d = readdir (mydir)) != NULL)
00099 {
00100 string s (d->d_name);
00101 if (s != "." && s != "..")
00102 {
00103 if (nogames)
00104 {
00105 nogames = false;
00106 cout << "Installed games (Suitable for the GAME parameter):\n";
00107 }
00108 cout << " - " << d->d_name << endl;
00109 }
00110 }
00111
00112 if (nogames) cout << "No games available.\n";
00113
00114 closedir (mydir);
00115 }
00116
00117 void config::parse_arguments (int argc, char * argv[])
00118 {
00119 int c;
00120
00121
00122 while (1)
00123 {
00124 c = getopt (argc, argv, "lcdhvg:");
00125 if (c == -1)
00126 break;
00127
00128 switch (c)
00129 {
00130 case 'l':
00131 print_available_games ();
00132 exit (0);
00133 break;
00134
00135 case 'd':
00136 cout << game::global_data_dir() << endl;
00137 exit (0);
00138 break;
00139
00140 case 'v':
00141 cout << VERSION << endl;
00142 exit (0);
00143 break;
00144
00145 case 'c':
00146 {
00147 python::init ();
00148 python::exec_string ("import compileall; compileall.compile_dir (\".\", 0);");
00149 python::cleanup ();
00150 exit (0);
00151 break;
00152 }
00153
00154 case 'g':
00155 {
00156 gamedir = optarg;
00157 if (gamedir[gamedir.size () - 1] == '/')
00158 gamedir.erase (gamedir.size () - 1);
00159
00160
00161 DIR * mydir = opendir (gamedir.c_str ());
00162
00163 if (!mydir)
00164 {
00165 cerr << "Cannot open directory " << gamedir << "!" << endl;
00166 exit (1);
00167 }
00168 closedir (mydir);
00169
00170 break;
00171 }
00172
00173 case '?':
00174 case 'h':
00175 print_help_message (argv);
00176 exit (0);
00177 break;
00178 }
00179 }
00180
00181
00182 if (gamedir == "")
00183 {
00184
00185 if (argc - optind != 1)
00186 {
00187 print_help_message (argv);
00188 exit (0);
00189 }
00190
00191
00192 struct dirent * d;
00193 DIR * mydir = opendir ((game::global_data_dir() + "/games").c_str());
00194 bool found = false;
00195
00196 if (!mydir)
00197 {
00198 cerr << "Cannot open directory " << game::global_data_dir() + "/games!" << endl;
00199 exit (1);
00200 }
00201
00202 while ((d = readdir (mydir)) != NULL)
00203 {
00204 if (string (d->d_name) == argv[optind]) found = true;
00205 }
00206
00207 closedir (mydir);
00208
00209 if (!found)
00210 {
00211 cerr << "Game '" << argv[optind] << "' can't be found.\n"
00212 << "Run '" << argv[0] << " -l' for a list of available games.\n";
00213 exit (1);
00214 }
00215
00216
00217 gamedir = game::global_data_dir() + "/games/";
00218 gamedir += argv[optind];
00219 }
00220
00221
00222 string tfile = gamedir + "/gamename.txt";
00223 ifstream f (tfile.c_str ());
00224 if (!f.is_open ())
00225 {
00226 cerr << "Directory " << gamedir << " is not a valid game directory.\n";
00227 exit (1);
00228 }
00229 char t[256];
00230 f.getline (t, 256);
00231 game_name = t;
00232 f.close ();
00233 }
00234
00235
00236
00237
00238 config& config::operator =(const config *c)
00239 {
00240 screen_mode = c->screen_mode;
00241 audio_channels = c->audio_channels;
00242 audio_resolution = c->audio_resolution;
00243 audio_sample_rate = c->audio_sample_rate;
00244 audio_volume = c->audio_volume;
00245 adonthellrc = c->adonthellrc;
00246
00247 delete c;
00248 return *this;
00249 }
00250
00251 char *config::get_adonthellrc ()
00252 {
00253 return (char *) adonthellrc.c_str ();
00254 }
00255
00256
00257 void config::write_adonthellrc ()
00258 {
00259 string fname;
00260
00261 #ifndef WIN32
00262 fname = adonthellrc + "/adonthellrc";
00263 #else
00264 fname = adonthellrc + "/adonthell.ini";
00265 #endif
00266
00267 ofstream rc (fname.c_str ());
00268
00269 rc << "# Sample Adonthell configuration file;\n"
00270 << "# edit to your needs!\n\n"
00271 << "# Screen-mode num\n# 0 Windowed mode\n"
00272 << "# 1 Fullscreen mode\n Screen-mode " << (int) screen_mode
00273 << "\n\n" << "# Double-size num\n# 0 320x240 mode\n"
00274 << "# 1 640x480 (double) mode\n Double-size "
00275 << (int) double_screen << "\n\n"
00276 << "# Language [locale]\n# Where locale has the form fr_FR or de_DE, etc.\n"
00277 << " Language [" << language << "]\n\n"
00278 << "# Font [font.ttf]\n# Path to a true type font to use. Leave empty for default\n"
00279 << " Font [" << font << "]\n\n"
00280 << "# Quick-load num\n# 0 off\n# 1 on\n Quick-load "
00281 << (int) quick_load << "\n\n"
00282 << "# Audio-channels num\n# 0 Mono\n# 1 Stereo\n"
00283 << " Audio-channels " << (int) audio_channels << "\n\n"
00284 << "# Audio-resolution num\n# 0 8 bit\n# 1 16 bit\n"
00285 << " Audio-resolution " << (int) audio_resolution << "\n\n"
00286 << "# Audio-sample-rate num\n# 0 11025 Hz\n# 1 22050 Hz\n# 2 44100 Hz\n"
00287 << " Audio-sample-rate " << (int) audio_sample_rate << "\n\n"
00288 << "# Audio-volume num\n# 0 - 100 %\n"
00289 << " Audio-volume " << (int) audio_volume << "\n\n"
00290 << "# Version number of this file. Please don't edit\n Version [" << VERSION << "]\n";
00291
00292 rc.close ();
00293 }
00294
00295 bool config::read_adonthellrc ()
00296 {
00297 int n, i = 1;
00298 u_int32 major = 0, minor = 0, micro = 0, MAJOR, MINOR, MICRO;
00299 char suffix[16] = "\0", SUFFIX[16] = "\0";
00300 string s, fname;
00301
00302 #ifndef WIN32
00303 fname = adonthellrc + "/adonthellrc";
00304 #else
00305 fname = adonthellrc + "/adonthell.ini";
00306 #endif
00307
00308
00309 #ifdef WIN32
00310 mkdir (adonthellrc.c_str ());
00311 #else
00312 mkdir (adonthellrc.c_str (), 0700);
00313 #endif
00314
00315
00316 prefsin = fopen (fname.c_str (), "r");
00317
00318
00319 if (!prefsin)
00320 {
00321 write_adonthellrc ();
00322
00323
00324 if (!(prefsin = fopen (fname.c_str (), "r")))
00325 {
00326 fprintf (stderr, "*** warning: prefs::read_adonthellrc: creating config file failed\n");
00327 return false;
00328 }
00329 }
00330
00331
00332 while (i)
00333 {
00334 switch (i = parse_adonthellrc (n, s))
00335 {
00336 case PREFS_LANGUAGE:
00337 {
00338 if (parse_adonthellrc (n, s) == PREFS_STR) language = s;
00339 break;
00340 }
00341 case PREFS_FONT:
00342 {
00343 if (parse_adonthellrc (n, s) == PREFS_NUM) font = s;
00344 break;
00345 }
00346 case PREFS_SCREEN_MODE:
00347 {
00348 if (parse_adonthellrc (n, s) == PREFS_NUM) screen_mode = n;
00349 break;
00350 }
00351
00352 case PREFS_DOUBLE_SCREEN:
00353 {
00354 if (parse_adonthellrc (n, s) == PREFS_NUM) double_screen = n;
00355 break;
00356 }
00357
00358 case PREFS_QUICK_LOAD:
00359 {
00360 if (parse_adonthellrc (n, s) == PREFS_NUM) quick_load = n;
00361 break;
00362 }
00363
00364 case PREFS_AUDIO_RESOLUTION:
00365 {
00366 if (parse_adonthellrc (n, s) == PREFS_NUM) audio_resolution = n;
00367 break;
00368 }
00369
00370 case PREFS_AUDIO_CHANNELS:
00371 {
00372 if (parse_adonthellrc (n, s) == PREFS_NUM) audio_channels = n;
00373 break;
00374 }
00375
00376 case PREFS_AUDIO_SAMPLE_RATE:
00377 {
00378 if (parse_adonthellrc (n, s) == PREFS_NUM) audio_sample_rate = n;
00379 break;
00380 }
00381
00382 case PREFS_AUDIO_VOLUME:
00383 {
00384 if (parse_adonthellrc (n, s) == PREFS_NUM) audio_volume = n;
00385 break;
00386 }
00387
00388 case PREFS_VERSION:
00389 {
00390
00391 if (parse_adonthellrc (n, s) == PREFS_STR)
00392 sscanf (s.c_str (), "%d.%d.%d%15s", &major, &minor, µ, suffix);
00393 break;
00394 }
00395 default: break;
00396 }
00397 }
00398
00399 fclose (prefsin);
00400
00401
00402 sscanf (VERSION, "%d.%d.%d%15s", &MAJOR, &MINOR, &MICRO, SUFFIX);
00403
00404
00405 if (major < MAJOR ||
00406 (major == MAJOR && minor < MINOR) ||
00407 (major == MAJOR && minor == MINOR && micro < MICRO) ||
00408 strcmp (suffix, SUFFIX) != 0)
00409 {
00410
00411 write_adonthellrc ();
00412 }
00413
00414 return true;
00415 }