diff --git a/data/gui/options_players.stkgui b/data/gui/options_players.stkgui index d3ca57450..3602a52ec 100644 --- a/data/gui/options_players.stkgui +++ b/data/gui/options_players.stkgui @@ -15,9 +15,13 @@ <spacer width="20" height="25"/> <button id="addplayer" x="20" width="35%" height="30" text="Add Player" align="center"/> + <!-- + <spacer width="50" height="10" /> + <button id="renameplayer" x="20" width="35%" height="30" text="Rename Player" align="center"/> <spacer width="50" height="10" /> <button id="rempayer" x="20" width="35%" height="30" text="Remove Player" align="center"/> - + --> + <spacer width="20" height="15"/> </box> diff --git a/src/config/player.hpp b/src/config/player.hpp index 0c7b0e185..b3fbf8cf3 100644 --- a/src/config/player.hpp +++ b/src/config/player.hpp @@ -17,26 +17,34 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef TUXKART_PLAYER_H -#define TUXKART_PLAYER_H +#ifndef HEADER_PLAYER_HPP +#define HEADER_PLAYER_HPP #include <string> -#include "input/input.hpp" +#include "config/user_config.hpp" -/*class for managing player name and control configuration*/ +/** + * class for managing player name and control configuration + */ class Player { private: - std::string m_name; - Input m_action_map[PA_COUNT]; + + // for saving to config file + GroupUserConfigParam m_player_group; + + StringUserConfigParam m_name; + int m_last_kart_id; public: - Player(){} - Player(const std::string &name_):m_name(name_),m_last_kart_id(-1){} + Player(const char* name) : m_player_group("Player", "Represents one human player"), + m_name(name, "name", &m_player_group), + m_last_kart_id(-1) {} + void setName(const std::string &name_){m_name = name_;} - const std::string& getName() {return m_name;} + const char* getName() { return m_name.c_str(); } int getLastKartId(){ return m_last_kart_id; } void setLastKartId(int newLastKartId){ m_last_kart_id = newLastKartId; } diff --git a/src/config/user_config.cpp b/src/config/user_config.cpp index 0a78b2f90..e42f2f986 100644 --- a/src/config/user_config.cpp +++ b/src/config/user_config.cpp @@ -26,6 +26,8 @@ #include <string> #include <stdlib.h> #include <fstream> +#include <vector> +#include "utils/ptr_vector.hpp" // for mkdir: #if !defined(WIN32) || defined(__CYGWIN__) @@ -35,7 +37,17 @@ # include <direct.h> #endif +class UserConfigParam; +static ptr_vector<UserConfigParam, REF> all_params; + + +// X-macros +#define PARAM_PREFIX +#define PARAM_DEFAULT(X) = X +#include "config/user_config.hpp" + #include "challenges/unlock_manager.hpp" +#include "config/player.hpp" #include "config/stk_config.hpp" #include "io/file_manager.hpp" #include "io/xml_node.hpp" @@ -47,18 +59,13 @@ #include "utils/string_utils.hpp" #include "utils/translation.hpp" - -class UserConfigParam; -static std::vector<UserConfigParam*> all_params; - - -// X-macros -#define PARAM_PREFIX -#define PARAM_DEFAULT(X) = X -#include "config/user_config.hpp" - // --------------------------------------------------------------------------------------- +UserConfigParam::~UserConfigParam() +{ + all_params.remove(this); +} + GroupUserConfigParam::GroupUserConfigParam(const char* groupName, const char* comment) { this->paramName = groupName; @@ -326,14 +333,20 @@ UserConfig *user_config; UserConfig::UserConfig() { setDefaults(); - loadConfig(); + if(!loadConfig()) + { + addDefaultPlayer(); + } } // UserConfig // ----------------------------------------------------------------------------- UserConfig::UserConfig(const std::string& filename) { setDefaults(); - loadConfig(filename); + if(!loadConfig(filename)) + { + addDefaultPlayer(); + } } // UserConfig @@ -343,28 +356,9 @@ UserConfig::~UserConfig() } // ~UserConfig // ----------------------------------------------------------------------------- -/** - * Set the config filename for each platform - */ -void UserConfig::setFilename() +void UserConfig::addDefaultPlayer() { -#ifdef WIN32 - m_filename = file_manager->getLogFile("supertuxkart.cfg"); -#else - m_filename = file_manager->getLogFile("config"); -#endif -} // setFilename - -// ----------------------------------------------------------------------------- -/** - * Load default values for options - */ -void UserConfig::setDefaults() -{ - setFilename(); - m_warning = ""; - //m_blacklist_res.clear(); - + std::string username = "unnamed player"; if(getenv("USERNAME")!=NULL) // for windows @@ -373,17 +367,26 @@ void UserConfig::setDefaults() username = getenv("USER"); else if(getenv("LOGNAME")!=NULL) // Linux, Macs username = getenv("LOGNAME"); - - - std::cout << "creating Players with name " << username.c_str() << std::endl; // Set the name as the default name for all players. - // TODO : create only one by default and let users add more? - UserConfigParams::m_player.push_back( Player(username + " 1") ); - UserConfigParams::m_player.push_back( Player(username + " 2") ); - UserConfigParams::m_player.push_back( Player(username + " 3") ); - UserConfigParams::m_player.push_back( Player(username + " 4") ); + UserConfigParams::m_player.push_back( new Player(username.c_str()) ); +} + +// ----------------------------------------------------------------------------- +/** + * Load default values for options + */ +void UserConfig::setDefaults() +{ +#ifdef WIN32 + m_filename = file_manager->getLogFile("supertuxkart.cfg"); +#else + m_filename = file_manager->getLogFile("config"); +#endif + + m_warning = ""; + //m_blacklist_res.clear(); } // setDefaults @@ -391,9 +394,9 @@ void UserConfig::setDefaults() /** * load default configuration file for this platform */ -void UserConfig::loadConfig() +bool UserConfig::loadConfig() { - loadConfig(m_filename); + return loadConfig(m_filename); } // loadConfig // ----------------------------------------------------------------------------- @@ -448,19 +451,19 @@ int UserConfig::CheckAndCreateDir() // ----------------------------------------------------------------------------- /** Load configuration values from file. */ -void UserConfig::loadConfig(const std::string& filename) +bool UserConfig::loadConfig(const std::string& filename) { XMLNode* root = file_manager->createXMLTree(filename); if(!root) { std::cerr << "Could not read user config file file " << filename.c_str() << std::endl; - return; + return false; } // ---- Read config file version int configFileVersion = CURRENT_CONFIG_VERSION; - if(!root->get("version", &configFileVersion) < 1) + if(root->get("version", &configFileVersion) < 1) { std::cerr << "Warning, malformed user config file! Contains no version\n"; } @@ -497,21 +500,35 @@ void UserConfig::loadConfig(const std::string& filename) { printf("The old config file is deleted, a new one will be created.\n"); delete root; - return; + return false; } printf("This warning can be ignored, the config file will be automatically updated.\n"); // Keep on reading the config files as far as possible } // if configFileVersion<SUPPORTED_CONFIG_VERSION - - + // ---- Read all other parameters const int paramAmount = all_params.size(); for(int i=0; i<paramAmount; i++) { - all_params[i]->readAsNode(root); + all_params[i].readAsNode(root); + } + + // ---- Read players + UserConfigParams::m_player.clearAndDeleteAll(); + + std::vector<XMLNode*> players; + root->getNodes("Player", players); + const int amount = players.size(); + for(int i=0; i<amount; i++) + { + std::string name; + players[i]->get("name", &name); + UserConfigParams::m_player.push_back( new Player(name.c_str()) ); + std::cout << "----- player : " << name.c_str() << std::endl; } delete root; + return true; } // loadConfig @@ -542,13 +559,14 @@ void UserConfig::saveConfig(const std::string& filepath) return; } + configfile << "<?xml version=\"1.0\"?>\n"; configfile << "<stkconfig version=\"" << CURRENT_CONFIG_VERSION << "\" >\n\n"; const int paramAmount = all_params.size(); for(int i=0; i<paramAmount; i++) { //std::cout << "saving parameter " << i << " to file\n"; - all_params[i]->write(configfile); + all_params[i].write(configfile); } configfile << "</stkconfig>\n"; configfile.close(); diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index 7eab9c1ca..c60fe9e4c 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -45,13 +45,14 @@ const int CURRENT_CONFIG_VERSION = 7; #include <vector> #include <fstream> -#include "config/player.hpp" #include "input/input.hpp" #include "lisp/lisp.hpp" #include "lisp/parser.hpp" #include "lisp/writer.hpp" +#include "utils/ptr_vector.hpp" class XMLNode; +class Player; /** * The base of a set of small utilities to enable quickly adding/removing stuff to/from config painlessly. @@ -62,7 +63,7 @@ class UserConfigParam protected: std::string paramName, comment; public: - virtual ~UserConfigParam() {} + virtual ~UserConfigParam(); virtual void write(std::ofstream& stream) const = 0; virtual void readAsNode(const XMLNode* node) = 0; virtual void readAsProperty(const XMLNode* node) = 0; @@ -262,8 +263,7 @@ namespace UserConfigParams // TODO? implement blacklist for new irrlicht device and GUI PARAM_PREFIX std::vector<std::string> m_blacklist_res; - // TODO : implement saving to config file - PARAM_PREFIX std::vector<Player> m_player; + PARAM_PREFIX ptr_vector<Player> m_player; } #undef PARAM_PREFIX @@ -277,7 +277,7 @@ private: /** Filename of the user config file. */ std::string m_filename; - void setFilename (); + void addDefaultPlayer (); public: @@ -289,8 +289,8 @@ public: ~UserConfig(); void setDefaults(); - void loadConfig(); - void loadConfig(const std::string& filename); + bool loadConfig(); + bool loadConfig(const std::string& filename); void saveConfig() { saveConfig(m_filename); } void saveConfig(const std::string& filename); diff --git a/src/gui/options_screen.cpp b/src/gui/options_screen.cpp index 437d01c93..f897fafa2 100644 --- a/src/gui/options_screen.cpp +++ b/src/gui/options_screen.cpp @@ -15,19 +15,20 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "gui/options_screen.hpp" -#include "gui/engine.hpp" -#include "gui/modaldialog.hpp" -#include "gui/screen.hpp" -#include "gui/widget.hpp" #include "audio/sound_manager.hpp" #include "audio/sfx_manager.hpp" #include "audio/sfx_base.hpp" +#include "config/player.hpp" +#include "graphics/irr_driver.hpp" +#include "gui/engine.hpp" +#include "gui/modaldialog.hpp" +#include "gui/options_screen.hpp" +#include "gui/screen.hpp" +#include "gui/state_manager.hpp" +#include "gui/widget.hpp" #include "input/input_manager.hpp" #include "input/device_manager.hpp" -#include "graphics/irr_driver.hpp" -#include "gui/state_manager.hpp" + #include <iostream> using namespace GUIEngine; @@ -288,7 +289,20 @@ namespace StateManager const std::string name2("devices"); eventInput(devices, name2); } - + + // ----------------------------------------------------------------------------- + void initPlayers(Widget* widget, const std::string& name) + { + ListWidget* players = getCurrentScreen()->getWidget<ListWidget>("players"); + assert(players != NULL); + + const int playerAmount = UserConfigParams::m_player.size(); + for(int n=0; n<playerAmount; n++) + { + players->addItem( UserConfigParams::m_player[n].getName() ); + } + } + void eventPlayers(Widget* widget, const std::string& name) { new EnterPlayerNameDialog(0.5f, 0.4f); @@ -483,8 +497,13 @@ namespace StateManager void gotNewPlayerName(const stringw& newName) { - std::cout << "got player name : " << stringc( newName ).c_str() << std::endl; - // TODO + stringc newNameC( newName ); + + UserConfigParams::m_player.push_back( new Player(newNameC.c_str()) ); + + ListWidget* players = getCurrentScreen()->getWidget<ListWidget>("players"); + if(players != NULL) + players->addItem( newNameC.c_str() ); } // ----------------------------------------------------------------------------- @@ -507,8 +526,7 @@ namespace StateManager if(screen_name == "options_av.stkgui") initAudioVideo(widget, name); else if(screen_name == "options_input.stkgui") initInput(widget, name); - - //getCurrentScreen()->m_inited; + else if(screen_name == "options_players.stkgui") initPlayers(widget, name); } else if(name == "options_choice") { diff --git a/src/gui/widget.cpp b/src/gui/widget.cpp index 8f404d6e3..ba908f727 100644 --- a/src/gui/widget.cpp +++ b/src/gui/widget.cpp @@ -1262,16 +1262,12 @@ void ListWidget::add() { rect<s32> widget_size = rect<s32>(x, y, x + w, y + h); - IGUIListBox* list = GUIEngine::getGUIEnv()->addListBox (widget_size, NULL, ++id_counter); - - id = list->getID(); - list->addItem( L"Hiker" ); - list->addItem( L"Conso" ); - list->addItem( L"Auria" ); - list->addItem( L"MiniBjorn" ); - list->addItem( L"Arthur" ); - - m_element = list; - - //list->setSelected(0); + m_element = GUIEngine::getGUIEnv()->addListBox (widget_size, NULL, ++id_counter); +} + +void ListWidget::addItem(const char* item) +{ + IGUIListBox* list = dynamic_cast<IGUIListBox*>(m_element); + assert(list != NULL); + list->addItem( stringw(item).c_str() ); } diff --git a/src/gui/widget.hpp b/src/gui/widget.hpp index ffb908820..5ef719e4e 100644 --- a/src/gui/widget.hpp +++ b/src/gui/widget.hpp @@ -340,6 +340,8 @@ namespace GUIEngine { public: void add(); + void addItem(const char* item); + }; } diff --git a/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj b/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj index c8f0c127e..09cd03649 100644 --- a/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj +++ b/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj @@ -993,7 +993,6 @@ 951C35BD0FC066ED00A48379 /* credits.hpp */, 9505577A0F696A900056E88C /* engine.cpp */, 9505577B0F696A900056E88C /* engine.hpp */, - 95C2AE370F296541000D3E5D /* enet */, 95C1E3FF0F699427005D33E6 /* font.cpp */, 95C1E4020F69943D005D33E6 /* font.hpp */, 954A57DB0FEC5AE40073C16C /* modaldialog.cpp */, @@ -1109,6 +1108,7 @@ 95C2AC360F296540000D3E5D /* bullet */, 95D950CC0FE473CA002E10AD /* config */, 95C2AE250F296541000D3E5D /* challenges */, + 95C2AE370F296541000D3E5D /* enet */, 950557790F696A900056E88C /* gui */, 95C2AE870F296542000D3E5D /* graphics */, 95C65D750F532F7D00BE7BA7 /* io */, diff --git a/src/io/xml_node.cpp b/src/io/xml_node.cpp index 8c559d305..09d903a14 100644 --- a/src/io/xml_node.cpp +++ b/src/io/xml_node.cpp @@ -126,6 +126,21 @@ const XMLNode *XMLNode::getNode(const std::string &s) const } return NULL; } // getNode +// ---------------------------------------------------------------------------- +/** Returns all nodes with the given name. + * \param s Name of the nodes to return. + * \param s Vector that will be filled with output values. + */ +const void XMLNode::getNodes(const std::string &s, std::vector<XMLNode*>& out) const +{ + for(unsigned int i=0; i<m_nodes.size(); i++) + { + if(m_nodes[i]->getName()==s) + { + out.push_back(m_nodes[i]); + } + } +} // getNode // ---------------------------------------------------------------------------- /** If 'attribute' was defined, set 'value' to the value of the diff --git a/src/io/xml_node.hpp b/src/io/xml_node.hpp index a94af7f3f..cd98bdf99 100644 --- a/src/io/xml_node.hpp +++ b/src/io/xml_node.hpp @@ -44,6 +44,7 @@ public: ~XMLNode(); const std::string &getName() const {return m_name; } const XMLNode *getNode(const std::string &name) const; + const void getNodes(const std::string &s, std::vector<XMLNode*>& out) const; const XMLNode *getNode(unsigned int i) const; unsigned int getNumNodes() const {return m_nodes.size(); } int get(const std::string &attribute, std::string *value) const; diff --git a/src/network/connect_message.cpp b/src/network/connect_message.cpp index e1bee8666..8468f1df3 100644 --- a/src/network/connect_message.cpp +++ b/src/network/connect_message.cpp @@ -27,6 +27,7 @@ #endif #include "config/user_config.hpp" +#include "config/player.hpp" #include "karts/kart_properties_manager.hpp" #include "tracks/track_manager.hpp"