src/game/config.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *  Wormux is a convivial mass murder game.
00003  *  Copyright (C) 2001-2004 Lawrence Azzoug.
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00018  ******************************************************************************
00019  * Wormux configuration : all variables interesting to tweak should be here.
00020  * A default value is affected for each variable, the value can be changed by
00021  * the configuration file.
00022  *****************************************************************************/
00023 
00024 #include "config.h"
00025 
00026 #define USE_AUTOPACKAGE
00027 
00028 #include <sstream>
00029 #include <string>
00030 #include <iostream>
00031 #include <sys/stat.h>
00032 #include <errno.h>
00033 #ifdef WIN32
00034 #  include <direct.h>
00035 #endif
00036 #include "game_mode.h"
00037 #include "errno.h"
00038 #include "../graphic/video.h"
00039 #include "../include/action.h"
00040 #include "../include/app.h"
00041 #include "../interface/keyboard.h"
00042 #include "../include/constant.h"
00043 #include "../map/maps_list.h"
00044 #include "../sound/jukebox.h"
00045 #include "../team/teams_list.h"
00046 #include "../tool/file_tools.h"
00047 #include "../tool/string_tools.h"
00048 #include "../tool/i18n.h"
00049 #include "../weapon/weapons_list.h"
00050 #ifdef USE_AUTOPACKAGE
00051 #  include "../include/binreloc.h"
00052 #endif
00053 
00054 
00055 const std::string FILENAME="config.xml";
00056 Config * Config::singleton = NULL;
00057 
00058 Config * Config::GetInstance() {
00059   if (singleton == NULL) {
00060     singleton = new Config();
00061   }
00062   return singleton;
00063 }
00064 
00065 Config::Config()
00066 {
00067 
00068 #ifdef USE_AUTOPACKAGE
00069   BrInitError error;
00070   std::string filename;
00071 
00072   if (br_init (&error) == 0 && error != BR_INIT_ERROR_DISABLED) {
00073     std::cout << "Warning: BinReloc failed to initialize (error code "
00074               << error << ")" << std::endl;
00075     std::cout << "Will fallback to hardcoded default path." << std::endl;
00076   }
00077 #endif
00078 
00079   // Default values
00080   exterieur_monde_vide = true;
00081   m_game_mode = "classic";
00082   display_energy_character = true;
00083   display_name_character = true;
00084   display_wind_particles = true;
00085   default_mouse_cursor = false;
00086   scroll_on_border = true;
00087   transparency = ALPHA;
00088 
00089   // video
00090   tmp.video.width = 800;
00091   tmp.video.height = 600;
00092   tmp.video.fullscreen = false;
00093 
00094   // sound
00095   tmp.sound.music = true;
00096   tmp.sound.effects = true;
00097   tmp.sound.frequency = 44100;
00098 
00099   // network
00100   tmp.network.enable_network = false;
00101 
00102   Constants::GetInstance();
00103 
00104   // directories
00105 #ifdef USE_AUTOPACKAGE
00106   data_dir     = GetEnv(Constants::ENV_DATADIR, br_find_data_dir(INSTALL_DATADIR));
00107   locale_dir   = GetEnv(Constants::ENV_LOCALEDIR, br_find_locale_dir(INSTALL_LOCALEDIR));
00108   filename     = data_dir + PATH_SEPARATOR + "font" + PATH_SEPARATOR + "DejaVuSans.ttf";
00109   ttf_filename = GetEnv(Constants::ENV_FONT_PATH, br_find_locale_dir(filename.c_str()));
00110 #else
00111   data_dir     = GetEnv(Constants::ENV_DATADIR, INSTALL_DATADIR);
00112   locale_dir   = GetEnv(Constants::ENV_LOCALEDIR, INSTALL_LOCALEDIR);
00113   ttf_filename = GetEnv(Constants::ENV_FONT_PATH, FONT_FILE);
00114 #endif
00115 
00116 #ifndef WIN32
00117   personal_dir = GetHome() + "/.wormux/";
00118 #else
00119   personal_dir = GetHome() + "\\Wormux\\";
00120 #endif
00121   InitI18N(locale_dir.c_str());
00122 
00123   DoLoading();
00124   std::string dir = TranslateDirectory(locale_dir);
00125   I18N_SetDir (dir + PATH_SEPARATOR);
00126 
00127   dir = TranslateDirectory(data_dir);
00128   resource_manager.AddDataPath(dir + PATH_SEPARATOR);
00129 }
00130 
00131 bool Config::DoLoading(void)
00132 {
00133   m_xml_loaded = false;
00134   try
00135   {
00136     // Load XML conf
00137     XmlReader doc;
00138     m_filename = personal_dir + FILENAME;
00139     if (!doc.Load(m_filename))
00140       return false;
00141     if (!LoadXml(doc.GetRoot()))
00142       return false;
00143     m_xml_loaded = true;
00144   }
00145   catch (const xmlpp::exception &e)
00146   {
00147     std::cout << "o "
00148         << _("Error while loading configuration file: %s") << std::endl
00149         << e.what() << std::endl;
00150     return false;
00151   }
00152   return true;
00153 }
00154 
00155 // Read personal config file
00156 bool Config::LoadXml(xmlpp::Element *xml)
00157 {
00158   std::cout << "o " << _("Reading personal config file") << std::endl;
00159 
00160   xmlpp::Element *elem;
00161 
00162   //=== Map ===
00163   XmlReader::ReadString(xml, "map", tmp.map_name);
00164 
00165   //=== Teams ===
00166   elem = XmlReader::GetMarker(xml, "teams");
00167   int i = 0;
00168 
00169   xmlpp::Element *team = XmlReader::GetMarker(elem, "team_" + ulong2str(i));
00170 
00171   while (team != NULL)
00172   {
00173     ConfigTeam one_team;
00174     XmlReader::ReadString(team, "id", one_team.id);
00175     XmlReader::ReadString(team, "player_name", one_team.player_name);
00176 
00177     int tmp_nb_characters;
00178     XmlReader::ReadInt(team, "nb_characters", tmp_nb_characters);
00179     one_team.nb_characters = (uint)tmp_nb_characters;
00180 
00181     tmp.teams.push_back(one_team);
00182 
00183     // get next team
00184     i++;
00185     team = XmlReader::GetMarker(elem, "team_"+ulong2str(i));
00186   }
00187 
00188   //=== Video ===
00189   elem = XmlReader::GetMarker(xml, "video");
00190   if (elem != NULL)
00191   {
00192     uint max_fps;
00193     if (XmlReader::ReadUint(elem, "max_fps", max_fps))
00194       AppWormux::GetInstance()->video.SetMaxFps(max_fps);
00195 
00196     XmlReader::ReadBool(elem, "display_wind_particles", display_wind_particles);
00197     XmlReader::ReadBool(elem, "display_energy_character", display_energy_character);
00198     XmlReader::ReadBool(elem, "display_name_character", display_name_character);
00199     XmlReader::ReadBool(elem, "default_mouse_cursor", default_mouse_cursor);
00200     XmlReader::ReadBool(elem, "scroll_on_border", scroll_on_border);
00201     XmlReader::ReadInt(elem, "width", tmp.video.width);
00202     XmlReader::ReadInt(elem, "height", tmp.video.height);
00203     XmlReader::ReadBool(elem, "full_screen", tmp.video.fullscreen);
00204   }
00205 
00206   //=== Sound ===
00207   elem = XmlReader::GetMarker(xml, "sound");
00208   if (elem != NULL)
00209   {
00210     XmlReader::ReadBool(elem, "music", tmp.sound.music);
00211     XmlReader::ReadBool(elem, "effects", tmp.sound.effects);
00212     XmlReader::ReadUint(elem, "frequency", tmp.sound.frequency);
00213   }
00214 
00215   //=== network ===
00216   elem = XmlReader::GetMarker(xml, "network");
00217   if (elem != NULL)
00218   {
00219     XmlReader::ReadBool(elem, "enable_network", tmp.network.enable_network);
00220   }
00221 
00222   //=== game mode ===
00223   XmlReader::ReadString(xml, "game_mode", m_game_mode);
00224   return true;
00225 }
00226 
00227 void Config::SetKeyboardConfig()
00228 {
00229   my_keyboard = new Keyboard();
00230 
00231   my_keyboard->SetKeyAction(SDLK_LEFT,      Action::ACTION_MOVE_LEFT);
00232   my_keyboard->SetKeyAction(SDLK_RIGHT,     Action::ACTION_MOVE_RIGHT);
00233   my_keyboard->SetKeyAction(SDLK_UP,        Action::ACTION_UP);
00234   my_keyboard->SetKeyAction(SDLK_DOWN,      Action::ACTION_DOWN);
00235   my_keyboard->SetKeyAction(SDLK_RETURN,    Action::ACTION_JUMP);
00236   my_keyboard->SetKeyAction(SDLK_BACKSPACE, Action::ACTION_HIGH_JUMP);
00237   my_keyboard->SetKeyAction(SDLK_b,         Action::ACTION_BACK_JUMP);
00238   my_keyboard->SetKeyAction(SDLK_SPACE,     Action::ACTION_SHOOT);
00239   my_keyboard->SetKeyAction(SDLK_TAB,       Action::ACTION_NEXT_CHARACTER);
00240   my_keyboard->SetKeyAction(SDLK_ESCAPE,    Action::ACTION_QUIT);
00241   my_keyboard->SetKeyAction(SDLK_p,         Action::ACTION_PAUSE);
00242   my_keyboard->SetKeyAction(SDLK_F10,       Action::ACTION_FULLSCREEN);
00243   my_keyboard->SetKeyAction(SDLK_F9,        Action::ACTION_TOGGLE_INTERFACE);
00244   my_keyboard->SetKeyAction(SDLK_F1,        Action::ACTION_WEAPONS1);
00245   my_keyboard->SetKeyAction(SDLK_F2,        Action::ACTION_WEAPONS2);
00246   my_keyboard->SetKeyAction(SDLK_F3,        Action::ACTION_WEAPONS3);
00247   my_keyboard->SetKeyAction(SDLK_F4,        Action::ACTION_WEAPONS4);
00248   my_keyboard->SetKeyAction(SDLK_F5,        Action::ACTION_WEAPONS5);
00249   my_keyboard->SetKeyAction(SDLK_F6,        Action::ACTION_WEAPONS6);
00250   my_keyboard->SetKeyAction(SDLK_F7,        Action::ACTION_WEAPONS7);
00251   my_keyboard->SetKeyAction(SDLK_F8,        Action::ACTION_WEAPONS8);
00252   my_keyboard->SetKeyAction(SDLK_c,         Action::ACTION_CENTER);
00253   my_keyboard->SetKeyAction(SDLK_1,         Action::ACTION_WEAPON_1);
00254   my_keyboard->SetKeyAction(SDLK_2,         Action::ACTION_WEAPON_2);
00255   my_keyboard->SetKeyAction(SDLK_3,         Action::ACTION_WEAPON_3);
00256   my_keyboard->SetKeyAction(SDLK_4,         Action::ACTION_WEAPON_4);
00257   my_keyboard->SetKeyAction(SDLK_5,         Action::ACTION_WEAPON_5);
00258   my_keyboard->SetKeyAction(SDLK_6,         Action::ACTION_WEAPON_6);
00259   my_keyboard->SetKeyAction(SDLK_7,         Action::ACTION_WEAPON_7);
00260   my_keyboard->SetKeyAction(SDLK_8,         Action::ACTION_WEAPON_8);
00261   my_keyboard->SetKeyAction(SDLK_9,         Action::ACTION_WEAPON_9);
00262   my_keyboard->SetKeyAction(SDLK_PAGEUP,    Action::ACTION_WEAPON_MORE);
00263   my_keyboard->SetKeyAction(SDLK_PAGEDOWN,  Action::ACTION_WEAPON_LESS);
00264   my_keyboard->SetKeyAction(SDLK_s,         Action::ACTION_CHAT);
00265 
00266 }
00267 
00268 void Config::Apply()
00269 {
00270   SetKeyboardConfig();
00271 
00272   // Charge le mode jeu
00273   my_weapons_list = new WeaponsList();
00274 
00275   GameMode::GetInstance()->Load(m_game_mode);
00276 
00277   // Son
00278   jukebox.ActiveMusic (tmp.sound.music);
00279   jukebox.ActiveEffects (tmp.sound.effects);
00280   jukebox.SetFrequency (tmp.sound.frequency);
00281 
00282   // load the teams
00283   teams_list.LoadList();
00284   if (m_xml_loaded)
00285     teams_list.InitList (tmp.teams);
00286 
00287   // Load maps
00288   if (m_xml_loaded && !tmp.map_name.empty())
00289     MapsList::GetInstance()->SelectMapByName (tmp.map_name);
00290   else
00291     MapsList::GetInstance()->SelectMapByIndex (0);
00292 }
00293 
00294 bool Config::Save()
00295 {
00296   std::string rep = personal_dir;
00297 
00298   // Create the directory if it doesn't exist
00299 #ifndef WIN32
00300    if (mkdir (personal_dir.c_str(), 0750) != 0 && errno != EEXIST)
00301 #else
00302   if (_mkdir (personal_dir.c_str()) != 0 && errno != EEXIST)
00303 #endif
00304   {
00305     std::cerr << "o "
00306       << Format(_("Error while creating directory \"%s\": unable to store configuration file."),
00307           rep.c_str())
00308       << std::endl;
00309     return false;
00310   }
00311 
00312   return SaveXml();
00313 }
00314 
00315 bool Config::SaveXml()
00316 {
00317   XmlWriter doc;
00318 
00319   doc.Create(m_filename, "config", "1.0", "utf-8");
00320   xmlpp::Element *root = doc.GetRoot();
00321   doc.WriteElement(root, "version", Constants::VERSION);
00322 
00323   //=== Map ===
00324   doc.WriteElement(root, "map", MapsList::GetInstance()->ActiveMap().ReadName());
00325 
00326   //=== Teams ===
00327   xmlpp::Element *team_elements = root->add_child("teams");
00328 
00329   TeamsList::iterator
00330     it=teams_list.playing_list.begin(),
00331     fin=teams_list.playing_list.end();
00332   for (int i=0; it != fin; ++it, i++)
00333   {
00334     xmlpp::Element *a_team = team_elements->add_child("team_"+ulong2str(i));
00335     doc.WriteElement(a_team, "id", (**it).GetId());
00336     doc.WriteElement(a_team, "player_name", (**it).GetPlayerName());
00337     doc.WriteElement(a_team, "nb_characters", ulong2str((**it).GetNbCharacters()));
00338   }
00339 
00340   //=== Video ===
00341   AppWormux * app = AppWormux::GetInstance();
00342 
00343   xmlpp::Element *video_node = root->add_child("video");
00344   doc.WriteElement(video_node, "display_wind_particles", ulong2str(display_wind_particles));
00345   doc.WriteElement(video_node, "display_energy_character", ulong2str(display_energy_character));
00346   doc.WriteElement(video_node, "display_name_character", ulong2str(display_name_character));
00347   doc.WriteElement(video_node, "default_mouse_cursor", ulong2str(default_mouse_cursor));
00348   doc.WriteElement(video_node, "scroll_on_border", ulong2str(scroll_on_border));
00349   doc.WriteElement(video_node, "width", ulong2str(app->video.window.GetWidth()));
00350   doc.WriteElement(video_node, "height", ulong2str(app->video.window.GetHeight()));
00351   doc.WriteElement(video_node, "full_screen",
00352                    ulong2str(static_cast<uint>(app->video.IsFullScreen())) );
00353   doc.WriteElement(video_node, "max_fps",
00354                    long2str(static_cast<int>(app->video.GetMaxFps())));
00355 
00356   if (transparency == ALPHA)
00357     doc.WriteElement(video_node, "transparency", "alpha");
00358   else if (transparency == COLORKEY)
00359     doc.WriteElement(video_node, "transparency", "colorkey");
00360 
00361   //=== Sound ===
00362   xmlpp::Element *sound_node = root->add_child("sound");
00363   doc.WriteElement(sound_node, "music",  ulong2str(jukebox.UseMusic()));
00364   doc.WriteElement(sound_node, "effects", ulong2str(jukebox.UseEffects()));
00365   doc.WriteElement(sound_node, "frequency", ulong2str(jukebox.GetFrequency()));
00366 
00367   //=== Network ===
00368   xmlpp::Element *net_node = root->add_child("network");
00369   doc.WriteElement(net_node, "enable_network",  ulong2str(IsNetworkActivated()));
00370 
00371   //=== game mode ===
00372   doc.WriteElement(root, "game_mode", m_game_mode);
00373   return doc.Save();
00374 }
00375 
00376 /*
00377  * Return the value of the environment variable 'name' or
00378  * 'default' if not set
00379  */
00380 std::string Config::GetEnv(const std::string & name, const std::string &default_value)
00381 {
00382   const char *env = std::getenv(name.c_str());
00383   if (env != NULL) {
00384     return env;
00385   } else {
00386     return default_value;
00387   }
00388 }
00389 
00390 std::string Config::GetDataDir() const
00391 {
00392   return data_dir;
00393 }
00394 
00395 std::string Config::GetLocaleDir() const
00396 {
00397   return locale_dir;
00398 }
00399 
00400 std::string Config::GetPersonalDir() const
00401 {
00402   return personal_dir;
00403 }
00404 
00405 bool Config::GetExterieurMondeVide() const
00406 {
00407   return exterieur_monde_vide;
00408 }
00409 
00410 bool Config::GetDisplayEnergyCharacter() const
00411 {
00412   return display_energy_character;
00413 }
00414 
00415 bool Config::GetDisplayNameCharacter() const
00416 {
00417   return display_name_character;
00418 }
00419 
00420 bool Config::GetDisplayWindParticles() const
00421 {
00422   return display_wind_particles;
00423 }
00424 
00425 bool Config::GetDefaultMouseCursor() const
00426 {
00427   return default_mouse_cursor;
00428 }
00429 
00430 bool Config::GetScrollOnBorder() const
00431 {
00432   return scroll_on_border;
00433 }
00434 
00435 std::string Config::GetTtfFilename() const
00436 {
00437   return ttf_filename;
00438 }
00439 
00440 bool Config::IsNetworkActivated() const
00441 {
00442   return tmp.network.enable_network;
00443 }
00444 
00445 void Config::SetDisplayEnergyCharacter(bool dec)
00446 {
00447   display_energy_character = dec;
00448 }
00449 
00450 void Config::SetDisplayNameCharacter(bool dnc)
00451 {
00452   display_name_character = dnc;
00453 }
00454 
00455 void Config::SetDisplayWindParticles(bool dwp)
00456 {
00457   display_wind_particles = dwp;
00458 }
00459 
00460 void Config::SetDefaultMouseCursor(bool dmc)
00461 {
00462   default_mouse_cursor = dmc;
00463 }
00464 
00465 void Config::SetScrollOnBorder(bool sob)
00466 {
00467   scroll_on_border = sob;
00468 }
00469 
00470 void Config::SetExterieurMondeVide(bool emv)
00471 {
00472   exterieur_monde_vide = emv;
00473 }
00474 
00475 int Config::GetTransparency() const
00476 {
00477   return transparency;
00478 }

Generated on Mon Jan 1 13:10:56 2007 for Wormux by  doxygen 1.4.7