00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
00090 tmp.video.width = 800;
00091 tmp.video.height = 600;
00092 tmp.video.fullscreen = false;
00093
00094
00095 tmp.sound.music = true;
00096 tmp.sound.effects = true;
00097 tmp.sound.frequency = 44100;
00098
00099
00100 tmp.network.enable_network = false;
00101
00102 Constants::GetInstance();
00103
00104
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
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
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
00163 XmlReader::ReadString(xml, "map", tmp.map_name);
00164
00165
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
00184 i++;
00185 team = XmlReader::GetMarker(elem, "team_"+ulong2str(i));
00186 }
00187
00188
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
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
00216 elem = XmlReader::GetMarker(xml, "network");
00217 if (elem != NULL)
00218 {
00219 XmlReader::ReadBool(elem, "enable_network", tmp.network.enable_network);
00220 }
00221
00222
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
00273 my_weapons_list = new WeaponsList();
00274
00275 GameMode::GetInstance()->Load(m_game_mode);
00276
00277
00278 jukebox.ActiveMusic (tmp.sound.music);
00279 jukebox.ActiveEffects (tmp.sound.effects);
00280 jukebox.SetFrequency (tmp.sound.frequency);
00281
00282
00283 teams_list.LoadList();
00284 if (m_xml_loaded)
00285 teams_list.InitList (tmp.teams);
00286
00287
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
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
00324 doc.WriteElement(root, "map", MapsList::GetInstance()->ActiveMap().ReadName());
00325
00326
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
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
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
00368 xmlpp::Element *net_node = root->add_child("network");
00369 doc.WriteElement(net_node, "enable_network", ulong2str(IsNetworkActivated()));
00370
00371
00372 doc.WriteElement(root, "game_mode", m_game_mode);
00373 return doc.Save();
00374 }
00375
00376
00377
00378
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 }