diff --git a/src/Makefile.am b/src/Makefile.am index 68caf7229..ea13d3bfc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -120,6 +120,7 @@ supertuxkart_SOURCES = main.cpp \ gui/race_options.cpp gui/race_options.hpp \ gui/char_sel.cpp gui/char_sel.hpp \ gui/start_race_feedback.cpp gui/start_race_feedback.hpp \ + gui/network_info.cpp gui/network_info.hpp \ gui/main_menu.cpp gui/main_menu.hpp \ gui/help_page_one.cpp gui/help_page_one.hpp \ gui/help_page_two.cpp gui/help_page_two.hpp \ diff --git a/src/gui/main_menu.cpp b/src/gui/main_menu.cpp index 1f4783aa9..a93417baa 100644 --- a/src/gui/main_menu.cpp +++ b/src/gui/main_menu.cpp @@ -32,6 +32,7 @@ enum WidgetTokens { WTOK_SINGLE, WTOK_MULTI, + WTOK_NETWORK, WTOK_CHALLENGES, WTOK_OPTIONS, WTOK_QUIT, @@ -47,6 +48,11 @@ MainMenu::MainMenu() const int WIDTH=30; widget_manager->addTextButtonWgt( WTOK_SINGLE, WIDTH, 7, _("Single Player") ); widget_manager->addTextButtonWgt( WTOK_MULTI, WIDTH, 7, _("Multiplayer") ); +#ifdef HAVE_ENET + // Only display the networking entry when not already connected. + if(network_manager->getMode()==NetworkManager::NW_NONE) + widget_manager->addTextButtonWgt( WTOK_NETWORK, WIDTH, 7, _("Networking") ); +#endif std::vector all_challenges=unlock_manager->getActiveChallenges(); // Only allow challenges if not networking for now! @@ -104,6 +110,9 @@ void MainMenu::select() case WTOK_MULTI: menu_manager->pushMenu(MENUID_NUMPLAYERS); break; + case WTOK_NETWORK: + menu_manager->pushMenu(MENUID_NETWORK_GUI); + break; case WTOK_CHALLENGES: menu_manager->pushMenu(MENUID_CHALLENGES); break; diff --git a/src/gui/menu_manager.cpp b/src/gui/menu_manager.cpp index b7eee42e9..400bf53ae 100644 --- a/src/gui/menu_manager.cpp +++ b/src/gui/menu_manager.cpp @@ -55,6 +55,7 @@ #include "feature_unlocked.hpp" #include "start_race_feedback.hpp" #include "network_info.hpp" +#include "network_gui.hpp" using namespace std; @@ -240,6 +241,9 @@ void MenuManager::update() case MENUID_START_RACE_FEEDBACK: m_current_menu = new StartRaceFeedback(); break; + case MENUID_NETWORK_GUI: + m_current_menu = new NetworkGUI(); + break; case MENUID_NETWORK_INFO: m_current_menu = new NetworkInfo(); break; diff --git a/src/gui/menu_manager.hpp b/src/gui/menu_manager.hpp index ce72f4f8d..87094ce96 100644 --- a/src/gui/menu_manager.hpp +++ b/src/gui/menu_manager.hpp @@ -45,6 +45,7 @@ enum MenuManagerIDs MENUID_GRANDPRIXSELECT, MENUID_UNLOCKED_FEATURE, MENUID_START_RACE_FEEDBACK, // 'loading' + MENUID_NETWORK_GUI, MENUID_NETWORK_INFO, // wait for clients to connect // menu configuration diff --git a/src/gui/network_info.cpp b/src/gui/network_info.cpp index c34b893b9..44990d19a 100644 --- a/src/gui/network_info.cpp +++ b/src/gui/network_info.cpp @@ -33,7 +33,6 @@ enum WidgetTokens NetworkInfo::NetworkInfo() { - //Add some feedback so people know they are going to start the race widget_manager->reset(); Widget *w_prev=widget_manager->addTitleWgt( WTOK_MSG, 60, 7, _("Waiting for clients ...") ); w_prev->setPosition(WGT_DIR_CENTER, 0.0, NULL, diff --git a/src/gui/race_options.cpp b/src/gui/race_options.cpp index 37b0417ad..bc9a4c8fb 100644 --- a/src/gui/race_options.cpp +++ b/src/gui/race_options.cpp @@ -56,13 +56,9 @@ enum WidgetTokens RaceOptions::RaceOptions() { // First update the server's race_manager with the number of players - if(network_manager->getMode()==NetworkManager::NW_CLIENT) + if(network_manager->getMode()==NetworkManager::NW_SERVER) { - network_manager->sendKartsInformationToServer(); - } - else if(network_manager->getMode()==NetworkManager::NW_SERVER) - { - network_manager->waitForKartsInformation(); + network_manager->switchToReceiveKartInfo(); // NS_WAIT_FOR_KART_INFO } m_difficulty=race_manager->getDifficulty(); @@ -146,6 +142,8 @@ RaceOptions::RaceOptions() widget_manager->setWgtBorderPercentage( WTOK_START, 20 ); widget_manager->setWgtBorderColor( WTOK_START, WGT_TRANS_BLUE ); widget_manager->showWgtBorder( WTOK_START ); + // Disable till all messages from the clients have arrived + widget_manager->deactivateWgt(WTOK_START); widget_manager->breakLine(); widget_manager->addEmptyWgt( WidgetManager::WGT_NONE, 1, 10); @@ -163,6 +161,15 @@ RaceOptions::~RaceOptions() widget_manager->reset(); } // ~RaceOptions +//----------------------------------------------------------------------------- +void RaceOptions::update(float dt) +{ + if(network_manager->getState()!=NetworkManager::NS_WAIT_FOR_KART_INFO) + { + widget_manager->activateWgt(WTOK_START); + } + BaseGUI::update(dt); +} // update //----------------------------------------------------------------------------- void RaceOptions::select() { @@ -283,11 +290,7 @@ void RaceOptions::select() menu_manager->pushMenu(MENUID_START_RACE_FEEDBACK); if(network_manager->getMode()==NetworkManager::NW_SERVER) { - network_manager->sendRaceInformationToClients(); - } - else if(network_manager->getMode()==NetworkManager::NW_CLIENT) - { - network_manager->waitForRaceInformation(); + network_manager->sendRaceInformationToClients(); // NS_READY_SET_GO_BARRIER } break; case WTOK_QUIT: diff --git a/src/gui/race_options.hpp b/src/gui/race_options.hpp index c543aebe2..6a8e06c64 100644 --- a/src/gui/race_options.hpp +++ b/src/gui/race_options.hpp @@ -33,6 +33,7 @@ public: ~RaceOptions(); void select(); + void update(float dt); }; #endif diff --git a/src/gui/start_race_feedback.cpp b/src/gui/start_race_feedback.cpp index cc45764a6..51e63a940 100644 --- a/src/gui/start_race_feedback.cpp +++ b/src/gui/start_race_feedback.cpp @@ -30,13 +30,11 @@ enum WidgetTokens StartRaceFeedback::StartRaceFeedback() { - network_manager->switchToRaceDataSynchronisation(); - - m_state = network_manager->getMode()==NetworkManager::NW_NONE ? SRF_LOADING : SRF_NETWORK; + m_state = SRF_NETWORK; //Add some feedback so people know they are going to start the race widget_manager->reset(); - if(m_state==SRF_NETWORK) + if(network_manager->getMode()!=NetworkManager::NW_NONE) widget_manager->addTextWgt( WTOK_MSG, 60, 7, _("Synchronising network...") ); else widget_manager->addTextWgt( WTOK_MSG, 60, 7, _("Loading race...") ); @@ -68,15 +66,17 @@ void StartRaceFeedback::update(float DELTA) break; case SRF_NETWORK: // The server only waits for one frame: - if(network_manager->getMode()==NetworkManager::NW_SERVER) + if(network_manager->getMode()!=NetworkManager::NW_CLIENT) { + // Server or stand alone: network_manager->sendRaceInformationToClients(); + network_manager->setupPlayerKartInfo(); m_state = SRF_LOADING_DISPLAY; widget_manager->setWgtText(WTOK_MSG, _("Loading race...") ); return; } // The client have to be busy waiting till the race data has arrived: - if(network_manager->getState()==NetworkManager::NS_WAITING_FOR_RACE_DATA) + if(network_manager->getState()==NetworkManager::NS_WAIT_FOR_RACE_DATA) return; m_state = SRF_LOADING_DISPLAY; widget_manager->setWgtText(WTOK_MSG, _("Loading race...") ); diff --git a/src/ide/vc9/supertuxkart.vcproj b/src/ide/vc9/supertuxkart.vcproj index 9125dd276..a880e7232 100644 --- a/src/ide/vc9/supertuxkart.vcproj +++ b/src/ide/vc9/supertuxkart.vcproj @@ -1006,6 +1006,10 @@ RelativePath="../../../src\gui\menu_manager.cpp" > + + @@ -1484,6 +1488,10 @@ RelativePath="../../../src\gui\menu_manager.hpp" > + + diff --git a/src/main.cpp b/src/main.cpp index f59a36c04..d0754bdb4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -163,7 +163,7 @@ int handleCmdLine(int argc, char **argv) else if(sscanf(argv[i], "--server=%d",&n)==1) { network_manager->setMode(NetworkManager::NW_SERVER); - network_manager->setPort(n); + user_config->m_server_port = n; } else if( !strcmp(argv[i], "--server") ) { @@ -171,12 +171,12 @@ int handleCmdLine(int argc, char **argv) } else if( sscanf(argv[i], "--port=%d", &n) ) { - network_manager->setPort(n); + user_config->m_server_port=n; } else if( sscanf(argv[i], "--client=%s", s) ) { network_manager->setMode(NetworkManager::NW_CLIENT); - network_manager->setServerIP(s); + user_config->m_server_address=s; } #endif else if( (!strcmp(argv[i], "--kart") && i+1initialiseConnections()) { fprintf(stderr, "Problems initialising network connections,\n" "Running in non-network mode.\n"); } - // On the server start with the network information page + // On the server start with the network information page for now if(network_manager->getMode()==NetworkManager::NW_SERVER) { - menu_manager->pushMenu(MENUID_NETWORK_INFO); + menu_manager->pushMenu(MENUID_NETWORK_GUI); } // Not replaying // ============= diff --git a/src/network/network_kart.cpp b/src/network/network_kart.cpp index c49f5f225..f40c6a0a8 100644 --- a/src/network/network_kart.cpp +++ b/src/network/network_kart.cpp @@ -18,8 +18,12 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#include "network_kart.hpp" +#include "network/network_manager.hpp" +#include "network/network_kart.hpp" +/** A network kart. On the server, it receives its control information (steering etc) + from the network manager. + */ NetworkKart::NetworkKart(const std::string &kart_name, int position, const btTransform &init_transform, int global_player_id) : Kart(kart_name, position, init_transform) @@ -28,3 +32,10 @@ NetworkKart::NetworkKart(const std::string &kart_name, int position, } // NetworkKart // ---------------------------------------------------------------------------- +void NetworkKart::setControl(const KartControl& kc) +{ + assert(network_manager->getMode()==NetworkManager::NW_SERVER); + m_controls = kc; +} // setControl + +// ---------------------------------------------------------------------------- diff --git a/src/network/network_kart.hpp b/src/network/network_kart.hpp index 3a95ab4a8..4a1d1182b 100644 --- a/src/network/network_kart.hpp +++ b/src/network/network_kart.hpp @@ -27,9 +27,9 @@ class NetworkKart : public Kart private: int m_global_player_id; // to identify this kart to the network manager public: - NetworkKart(const std::string& kart_name, int position, - const btTransform& init_transform, - int global_player_id); - + NetworkKart(const std::string& kart_name, int position, + const btTransform& init_transform, + int global_player_id); + void setControl(const KartControl& kc); }; // NetworkKart #endif diff --git a/src/network/network_manager.cpp b/src/network/network_manager.cpp index 7385045eb..a101f6c0c 100644 --- a/src/network/network_manager.cpp +++ b/src/network/network_manager.cpp @@ -29,8 +29,7 @@ NetworkManager::NetworkManager() { m_mode = NW_NONE; m_state = NS_ACCEPT_CONNECTIONS; - m_port = 12345; - m_server_address = "172.31.41.53"; + m_num_clients = 0; m_host_id = 0; #ifdef HAVE_ENET @@ -67,11 +66,11 @@ NetworkManager::~NetworkManager() bool NetworkManager::initServer() { #ifdef HAVE_ENET - fprintf(stderr, "Initialising server, listening on %d\n", m_port); + fprintf(stderr, "Initialising server, listening on %d\n", user_config->m_server_port); ENetAddress address; address.host = ENET_HOST_ANY; - address.port = m_port; + address.port = user_config->m_server_port; m_host = enet_host_create (& address /* the address to bind the server host to */, stk_config->m_max_karts /* number of connections */, @@ -113,8 +112,8 @@ bool NetworkManager::initClient() ENetEvent event; ENetPeer *peer; - enet_address_set_host (& address, m_server_address.c_str()); - address.port = m_port; + enet_address_set_host (& address, user_config->m_server_address.c_str()); + address.port = user_config->m_server_port; /* Initiate the connection, allocating the two channels 0 and 1. */ peer = enet_host_connect (m_host, &address, 2); @@ -136,11 +135,11 @@ bool NetworkManager::initClient() enet_peer_reset (peer); fprintf(stderr, "Connection to '%s:%d' failed.\n", - m_server_address.c_str(), m_port); + user_config->m_server_address.c_str(), user_config->m_server_port); return false; } fprintf(stderr, "Connection to %s:%d succeeded.\n", - m_server_address.c_str(), m_port); + user_config->m_server_address.c_str(), user_config->m_server_port); enet_host_service(m_host, &event, 1000); // FIXME Receive host id from server here!! m_host_id = 1; @@ -213,12 +212,13 @@ void NetworkManager::handleServerMessage(ENetEvent *event) m_state = NS_RACING; } break; - case NS_KART_INFO_BARRIER: + case NS_WAIT_FOR_KART_INFO: m_barrier_count++; + // handle message, i.e. append to m_kart_info if(m_barrier_count==m_num_clients) { // broadcast start message - m_state = NS_RACING; + m_state = NS_READY_SET_GO_BARRIER; } break; @@ -228,9 +228,15 @@ void NetworkManager::handleServerMessage(ENetEvent *event) // ---------------------------------------------------------------------------- void NetworkManager::switchToReadySetGoBarrier() { - assert(m_state == NS_CHARACTER_SELECT); - m_state = NS_READY_SET_GO_BARRIER; - m_barrier_count = 0; + if(m_num_clients==0) + { + m_state = NS_RACING; + } + else + { + m_state = NS_READY_SET_GO_BARRIER; + m_barrier_count = 0; + } } // switchToReadySetGoBarrier // ---------------------------------------------------------------------------- @@ -243,10 +249,16 @@ void NetworkManager::switchToCharacterSelection() } // switchTocharacterSelection // ---------------------------------------------------------------------------- -void NetworkManager::switchToRaceDataSynchronisation() +void NetworkManager::switchToReceiveKartInfo() { assert(m_state == NS_CHARACTER_SELECT); - m_state = NS_KART_INFO_BARRIER; + m_state = NS_WAIT_FOR_KART_INFO; +} // switchToReceiveKartInfo + +// ---------------------------------------------------------------------------- +void NetworkManager::switchToRaceDataSynchronisation() +{ + m_state = NS_WAIT_FOR_RACE_DATA; m_barrier_count = 0; } // switchToRaceDataSynchronisation @@ -255,10 +267,10 @@ void NetworkManager::handleClientMessage(ENetEvent *event) { switch(m_state) { - case NS_ACCEPT_CONNECTIONS: - fprintf(stderr, "Received a receive event while waiting for client - ignored.\n"); - return; - + case NS_WAIT_FOR_RACE_DATA: + // check if message is really race data + fprintf(stderr, "Client received race data\n"); + break; } // switch m_state } // handleClientMessage @@ -301,19 +313,19 @@ void NetworkManager::sendKartsInformationToServer() fprintf(stderr, "kart name '%s'\n", race_manager->getLocalKartInfo(i).getKartName().c_str()); } // for igetNumLocalPlayers(); i++) @@ -334,7 +346,7 @@ void NetworkManager::waitForKartsInformation() { race_manager->setPlayerKart(i, m_kart_info[i]); } -} // waitForKartsInformation +} // setupPlayerKartInfo // ---------------------------------------------------------------------------- /** Sends the information from the race_manager to all clients. @@ -348,6 +360,9 @@ void NetworkManager::sendRaceInformationToClients() fprintf(stderr, "Sending kart '%s' playerid %d host %d\n", ki.getKartName().c_str(), ki.getLocalPlayerId(), ki.getHostId()); } // for i + + // Go + m_state=NS_READY_SET_GO_BARRIER; } // sendRaceInformationToClients // ---------------------------------------------------------------------------- diff --git a/src/network/network_manager.hpp b/src/network/network_manager.hpp index edc31b067..be61c7dc7 100644 --- a/src/network/network_manager.hpp +++ b/src/network/network_manager.hpp @@ -36,19 +36,17 @@ public: enum NetworkMode {NW_SERVER, NW_CLIENT, NW_NONE}; // States for the finite state machine. First for server: - enum NetworkState {NS_ACCEPT_CONNECTIONS, NS_KART_INFO_BARRIER, + enum NetworkState {NS_ACCEPT_CONNECTIONS, NS_WAIT_FOR_KART_INFO, // Then client only states: NS_CHARACTER_CONFIRMED, NS_CHARACTER_REJECTED, - NS_WAITING_FOR_RACE_DATA, + NS_WAIT_FOR_RACE_DATA, // Shared states NS_CHARACTER_SELECT, NS_READY_SET_GO_BARRIER, NS_RACING}; private: NetworkMode m_mode; NetworkState m_state; - int m_port; - std::string m_server_address; int m_num_clients; std::vector m_kart_info; int m_host_id; @@ -77,19 +75,19 @@ public: unsigned int getNumClients() const {return m_num_clients; } const std::string& getClientName(int i) const {return m_client_names[i];} - void setPort(int p) {m_port=p; } - void setServerIP(const std::string &s) {m_server_address=s; } void setKartInfo(int player_id, const std::string& kart, const std::string& user="", int hostid=-1); bool initialiseConnections(); void update(float dt); void sendKartsInformationToServer(); - void waitForKartsInformation(); + void setupPlayerKartInfo(); void sendRaceInformationToClients(); void waitForRaceInformation(); - void switchToReadySetGoBarrier(); + void switchToCharacterSelection(); + void switchToReceiveKartInfo(); void switchToRaceDataSynchronisation(); + void switchToReadySetGoBarrier(); }; diff --git a/src/user_config.cpp b/src/user_config.cpp index 2490ca5bd..10108edf5 100644 --- a/src/user_config.cpp +++ b/src/user_config.cpp @@ -121,6 +121,8 @@ void UserConfig::setDefaults() m_log_errors = false; m_kart_group = "standard"; m_track_group = "standard"; + m_server_address = "localhost"; + m_server_port = 2305; if(getenv("USERNAME")!=NULL) // for windows m_username=getenv("USERNAME"); @@ -444,9 +446,13 @@ void UserConfig::loadConfig(const std::string& filename) lisp->get("log-errors", m_log_errors); lisp->get("kart-group", m_kart_group); lisp->get("track-group", m_track_group); - // Handle loading the stick config in it own method. + // Handle loading the stick config in it own method. readStickConfigs(lisp); + // Address of server + lisp->get("server-address", m_server_address); + lisp->get("server-port", m_server_port); + // Unlock information: const lisp::Lisp* unlock_info = lisp->getLisp("unlock-info"); if(unlock_info) unlock_manager->load(unlock_info); @@ -691,6 +697,10 @@ void UserConfig::saveConfig(const std::string& filename) writer->write("kart-group", m_kart_group); writer->writeComment("Last selected track group"); writer->write("track-group", m_track_group); + writer->writeComment("Information about last server used"); + writer->write("server-address", m_server_address); + writer->write("server-port", m_server_port); + writeStickConfigs(writer); // Write unlock information back diff --git a/src/user_config.hpp b/src/user_config.hpp index 4bd906f4e..8b6a8b627 100644 --- a/src/user_config.hpp +++ b/src/user_config.hpp @@ -178,6 +178,8 @@ public: std::string m_background_music; std::string m_kart_group; // Kart group used last std::string m_track_group; // Track group used last + std::string m_server_address; + int m_server_port; bool m_replay_history; bool m_use_kph; int m_width; diff --git a/src/widget.cpp b/src/widget.cpp index 2def31077..9046693a1 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -811,13 +811,6 @@ void Widget::draw() if(m_enable_text) { - if(m_text.empty()) - { - std::cerr << "Warning: widget tried to print an empty string.\n"; - std::cerr << "(Did you set the text?)\n"; - } - - //For multilines we have to do a *very* ugly workaround for a plib //bug which causes multiline strings to move to the left, at least //while centering, and also gives wrong values for the size of the diff --git a/src/widget_manager.hpp b/src/widget_manager.hpp index f94faf78f..0ee60aff5 100644 --- a/src/widget_manager.hpp +++ b/src/widget_manager.hpp @@ -298,6 +298,9 @@ public: //size). void setWgtCornerRadius(const int TOKEN, const int RADIUS); void showWgtRect(const int TOKEN); + // Completely hide and show a widget + void hideWgt(const int t) {hideWgtRect(t); hideWgtText(t);} + void showWgt(const int t) {showWgtRect(t); showWgtText(t);} void hideWgtRect(const int TOKEN); void setWgtBorderColor(const int TOKEN, const GLfloat* const COLOR); diff --git a/src/world.cpp b/src/world.cpp index 6c0293e97..7f5ac5247 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -306,7 +306,7 @@ void World::update(float dt) menu_manager->pushMenu(MENUID_RACERESULT); } if(!user_config->m_replay_history) history->StoreDelta(dt); - m_physics->update(dt); + if(network_manager->getMode()!=NetworkManager::NW_CLIENT) m_physics->update(dt); for (int i = 0 ; i <(int) m_kart.size(); ++i) { // Update all karts that are not eliminated