Merge branch 'master' of https://github.com/supertuxkart/stk-code into ScriptEngine

This commit is contained in:
sachith500 2014-05-26 16:58:16 +05:30
commit 3cb24f55d5
62 changed files with 2777 additions and 3133 deletions

View File

@ -11,10 +11,10 @@
<spacer height="20" width="20" />
<!-- TODO: ok button? -->
<button id="cancel" I18N="When configuring input" text="Press ESC to cancel" align="center"/>
<buttonbar proportion="1" id="options" width="100%" height="100%">
<button id="ok" I18N="When configuring input" text="OK" align="center"/>
<button id="cancel" I18N="When configuring input" text="Cancel" align="center"/>
</buttonbar>
<spacer height="15" width="20" />
</div>

View File

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-16"?>
<stkgui>
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
<header align="center" width="80%" text="Login" text_align="center"/>
<spacer height="15" width="10"/>
<tabs id="login_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_login" width="128" height="128" icon="gui/track_random.png"
I18N="Tab in login menu" text="Sign In"/>
<icon-button id="tab_guest_login" width="128" height="128" icon="gui/mode_ftl.png"
I18N="Tab in login menu" text="Sign In As Guest"/>
<icon-button id="tab_register" width="128" height="128" icon="gui/mode_ftl.png"
I18N="Tab in login menu" text="Register"/>
</tabs>
<box proportion="1" width="100%" layout="vertical-row">
<header id="title" width="96%" height="fit" text_align="center" word_wrap="true"
I18N="In the login dialog" text="Sign in"/>
<spacer height="20" width="20"/>
<div width="80%" align="center" layout="vertical-row" height="fit" >
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the login dialog" text="Username"/>
<textbox proportion="2" height="fit" id="username" I18N="In the login dialog"/>
</div>
<spacer height="20" width="20"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the login dialog" text="Password"/>
<textbox x="5" proportion="2" height="fit" id="password" I18N="In the login dialog"/>
</div>
<spacer height="20" width="20"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" text_align="left" I18N="In the login dialog" text="Stay signed in"/>
<div proportion="2" height="100%" layout="horizontal-row">
<checkbox width="fit" height="fit" id="remember" I18N="In the login dialog"/>
</div>
</div>
</div>
<label id="info" proportion="1" width="90%" align="center" text_align="center"
word_wrap="true" text=""/>
<spacer height="20" width="20"/>
<buttonbar id="options" width="90%" height="13%" align="bottom">
<icon-button id="sign_in" width="64" height="64" icon="gui/green_check.png"
I18N="Login dialog" text="Sign In" label_location="bottom"/>
<icon-button id="recovery" width="64" height="64" icon="gui/main_help.png"
I18N="Login dialog" text="Recovery" label_location="bottom"/>
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
I18N="Login dialog" text="Close" label_location="bottom"/>
</buttonbar>
<spacer height="20" width="20"/>
</box>
</div>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
</stkgui>

View File

@ -3,55 +3,59 @@
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
<header align="center" width="80%" text="Login" text_align="center"/>
<header align="center" width="80%" text="Create User" text_align="center"
I18N="In the registration dialog" />
<spacer height="15" width="10"/>
<tabs id="login_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_login" width="128" height="128" icon="gui/track_random.png"
I18N="Tab in login menu" text="Sign In"/>
<icon-button id="tab_guest_login" width="128" height="128" icon="gui/mode_ftl.png"
I18N="Tab in login menu" text="Sign In As Guest"/>
<icon-button id="tab_register" width="128" height="128" icon="gui/mode_ftl.png"
I18N="Tab in login menu" text="Register"/>
</tabs>
<box proportion="1" width="100%" layout="vertical-row">
<header id="title" width="96%" height="fit" text_align="center" word_wrap="true"
I18N="In the login dialog" text="Sign in"/>
<spacer height="40" width="20"/>
<div width="80%" align="center" layout="vertical-row" height="fit">
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the registration dialog" text="Username"/>
<textbox proportion="2" height="fit" id="username" I18N="In the registration dialog"/>
<label proportion="1" height="100%" text_align="left"
I18N="In the registration dialog" text="Local Username"/>
<textbox id="local_username" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_online" proportion="1" height="100%" text_align="left"
I18N="In the login screen" text="Online"/>
<checkbox id="online" I18N="In the login screen" text_align="left"/>
</div>
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_username" proportion="1" height="100%" text_align="left"
I18N="In the registration dialog" text="Online Username"/>
<textbox id="username" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
<spacer height="20" width="20"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the registration dialog" text="Password"/>
<textbox proportion="2" height="fit" id="password" I18N="In the registration dialog"/>
<label id="label_password" proportion="1" height="100%" text_align="left"
I18N="In the registration dialog" text="Password"/>
<textbox id="password" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
<spacer height="20" width="20"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the registration dialog" text="Confirm"/>
<textbox proportion="2" height="fit" id="password_confirm" I18N="In the registration dialog"/>
<label id="label_password_confirm" proportion="1" height="100%" text_align="left"
I18N="In the registration dialog" text="Confirm"/>
<textbox id="password_confirm" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
<spacer height="20" width="20"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the registration dialog" text="Email"/>
<textbox proportion="2" height="fit" id="email" I18N="In the registration dialog"/>
<label id="label_email" proportion="1" height="100%" text_align="left"
I18N="In the registration dialog" text="Email"/>
<textbox id="email" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
<spacer height="20" width="20"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the registration dialog" text="Confirm"/>
<textbox proportion="2" height="fit" id="email_confirm" I18N="In the registration dialog"/>
<label id="label_email_confirm" proportion="1" height="100%" text_align="left"
I18N="In the registration dialog" text="Confirm"/>
<textbox id="email_confirm" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
<spacer height="20" width="50"/>
@ -66,7 +70,7 @@
<buttonbar id="options" width="25%" height="14%" align="center">
<icon-button id="next" width="64" height="64" icon="gui/green_check.png"
I18N="Registration dialog" text="Next" label_location="none"/>
I18N="Registration dialog" text="OK" label_location="none"/>
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
I18N="Registration dialog" text="Cancel" label_location="none"/>
</buttonbar>

View File

@ -39,6 +39,12 @@
<label height="100%" I18N="In the ui settings" text="Allow STK to connect to the Internet"/>
</div>
<div width="75%" height="fit" layout="horizontal-row" >
<checkbox id="remember-me"/>
<spacer width="20" height="100%" />
<label height="100%" I18N="In the ui settings" text="Remember user"/>
</div>
<spacer height="18" width="4"/>
<!-- ************ LANGUAGE CHOICE ************ -->

View File

@ -1,28 +0,0 @@
<stkgui>
<div x="2%" y="2%" width="96%" height="97%" layout="vertical-row" >
<header text_align="center" width="80%" align="center" text="Select a Player"/>
<spacer height="15" width="10"/>
<box proportion="6" width="75%" align="center" layout="vertical-row" padding="8">
<list id="gameslots" x="0" y="0" width="100%" height="100%"/>
</box>
<spacer width="20" height="25"/>
<div layout="horizontal-row" align="center" width="70%" height="fit">
<checkbox id="rememberme" />
<label text="Remember me" height="100%"/>
</div>
<spacer width="20" height="15"/>
<button id="creategame" x="20"
I18N="In story mode 'select a game slot' menu"
text="Create a new player" align="center"/>
<spacer width="20" height="15"/>
</div>
</stkgui>

View File

@ -1,36 +0,0 @@
<stkgui>
<div x="5%" y="5%" width="90%" height="90%" layout="vertical-row" >
<header width="80%" text="New Game" align="center" text_align="center" />
<spacer proportion="1" width="25"/>
<div layout="horizontal-row" width="100%" height="50" align="center">
<label proportion="1" height="100%"
I18N="In the new story mode game dialog" text="Select your identity" text_align="right" />
<spacer width="50" height="25"/>
<spinner id="identity" proportion="1" height="100%" min_value="0" wrap_around="true"/>
</div>
<spacer proportion="1" width="25"/>
<ribbon id="difficulty" height="135" width="85%" align="center">
<icon-button id="novice" width="128" height="128" icon="gui/difficulty_easy.png"
I18N="Difficulty" text="Novice"/>
<icon-button id="intermediate" width="128" height="128" icon="gui/difficulty_medium.png"
I18N="Difficulty" text="Intermediate"/>
<icon-button id="expert" width="128" height="128" icon="gui/difficulty_hard.png"
I18N="Difficulty" text="Expert"/>
</ribbon>
<spacer width="25" proportion="1"/>
<button id="startgame" text="Start Game" align="center"/>
<spacer width="25" height="5"/>
<button id="cancel" text="Cancel" align="center"/>
</div>
</stkgui>

View File

@ -0,0 +1,60 @@
<stkgui>
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
<header align="center" width="80%" text="Login" text_align="center"/>
<spacer height="15" width="10"/>
<box proportion="1" width="98%" layout="vertical-row">
<spacer height="15" width="10"/>
<scrollable_ribbon id="players" height="120" y="10" x="10" width="98%" align="center" label_location="each"
square_items="true" child_width="160" child_height="120" />
<spacer height="15" width="10"/>
<div width="80%" align="center" layout="vertical-row" height="fit">
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the login screen" text="Online"/>
<checkbox id="online" I18N="In the login screen" text_align="left"/>
</div>
<!-- Disable guest accounts for now
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_guest" proportion="1" height="100%" text_align="left"
I18N="In the login screen" text="Guest login"/>
<checkbox id="guest" I18N="In the login screen" text_align="left"/>
</div>
-->
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_username" proportion="1" height="100%" text_align="left"
I18N="In the login screen" text="Username"/>
<textbox id="username" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
<spacer height="20" width="20"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_password" proportion="1" height="100%" text_align="left"
I18N="In the registration dialog" text="Password"/>
<textbox id="password" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
</div>
<div width="80%" align="center" layout="vertical-row" height="fit">
<label id="message" width="80%" align="center" text_align="left"/>
</div>
<spacer width="20" height="25"/>
<buttonbar id="options" width="90%" height="13%" align="bottom">
<icon-button id="ok" width="64" height="64" icon="gui/green_check.png"
I18N="Login dialog" text="OK" label_location="bottom"/>
<icon-button id="new_user" width="64" height="64" icon="gui/gp_add_track.png"
I18N="Login dialog" text="Add user" label_location="bottom"/>
<icon-button id="delete" width="64" height="64" icon="gui/gp_remove_track.png"
I18N="Login dialog" text="Delete" label_location="bottom"/>
<icon-button id="rename" width="64" height="64" icon="gui/gp_rename.png"
I18N="Login dialog" text="Rename" label_location="bottom"/>
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
I18N="Login dialog" text="Cancel" label_location="bottom"/>
</buttonbar>
</box>
<spacer width="20" height="15"/>
</div>
</stkgui>

View File

@ -0,0 +1,69 @@
<stkgui>
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
<header text_align="center" width="80%" align="center" text="SuperTuxKart Options"/>
<spacer height="15" width="10"/>
<tabs id="options_choice" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"/>
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"/>
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"/>
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
I18N="Section in the settings menu" text="Players"/>
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"/>
</tabs>
<box proportion="1" width="98%" layout="vertical-row">
<spacer height="15" width="10"/>
<scrollable_ribbon id="players" height="120" y="10" x="10" width="98%" align="center" label_location="each"
square_items="true" child_width="160" child_height="120" />
<spacer height="15" width="10"/>
<div width="80%" align="center" layout="vertical-row" height="fit">
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the login screen" text="Online"/>
<checkbox id="online" I18N="In the login screen" text_align="left"/>
</div>
<!-- Disable guest accounts for now
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_guest" proportion="1" height="100%" text_align="left"
I18N="In the login screen" text="Guest login"/>
<checkbox id="guest" I18N="In the login screen" text_align="left"/>
</div>
-->
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_username" proportion="1" height="100%" text_align="left"
I18N="In the login screen" text="Username"/>
<textbox id="username" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
<spacer height="20" width="20"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_password" proportion="1" height="100%" text_align="left"
I18N="In the registration dialog" text="Password"/>
<textbox id="password" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
</div>
<div width="80%" align="center" layout="vertical-row" height="fit">
<label id="message" width="80%" align="center" text_align="left"/>
</div>
<spacer width="20" height="25"/>
<buttonbar id="options" width="90%" height="13%" align="bottom">
<icon-button id="ok" width="64" height="64" icon="gui/green_check.png"
I18N="Login dialog" text="OK" label_location="bottom"/>
<icon-button id="new_user" width="64" height="64" icon="gui/gp_add_track.png"
I18N="Login dialog" text="Add user" label_location="bottom"/>
<icon-button id="delete" width="64" height="64" icon="gui/gp_remove_track.png"
I18N="Login dialog" text="Delete" label_location="bottom"/>
<icon-button id="rename" width="64" height="64" icon="gui/gp_rename.png"
I18N="Login dialog" text="Rename" label_location="bottom"/>
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
I18N="Login dialog" text="Cancel" label_location="bottom"/>
</buttonbar>
</box>
<spacer width="20" height="15"/>
</div>
</stkgui>

View File

@ -55,7 +55,7 @@
from BurningWell.
* zipper_collect
by Dakal, released under CC-BY-SA 3.0
by Connor, released as Public Domain
* rubber_ball and jump-bomb.jpg
by Samuncle, released under CC-BY-SA

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -20,6 +20,7 @@
#include "achievements/achievements_manager.hpp"
#include "config/player_profile.hpp"
#include "config/user_config.hpp"
#include "io/file_manager.hpp"
#include "io/utf_writer.hpp"
#include "io/xml_node.hpp"
@ -38,12 +39,6 @@ void PlayerManager::create()
{
assert(!m_player_manager);
m_player_manager = new PlayerManager();
if(m_player_manager->getNumPlayers() == 0)
{
m_player_manager->addDefaultPlayer();
m_player_manager->save();
}
} // create
// ----------------------------------------------------------------------------
@ -120,7 +115,8 @@ void PlayerManager::resumeSavedSession()
*/
void PlayerManager::onSTKQuit()
{
getCurrentPlayer()->onSTKQuit();
if (getCurrentPlayer() && getCurrentPlayer()->isLoggedIn())
getCurrentPlayer()->requestSignOut();
} // onSTKQuit
// ----------------------------------------------------------------------------
@ -134,12 +130,9 @@ void PlayerManager::onSTKQuit()
*/
Online::XMLRequest *PlayerManager::requestSignIn(const irr::core::stringw &username,
const irr::core::stringw &password,
bool save_session,
bool request_now)
const irr::core::stringw &password)
{
return getCurrentPlayer()->requestSignIn(username, password, save_session,
request_now);
return getCurrentPlayer()->requestSignIn(username, password);
} // requestSignIn
// ----------------------------------------------------------------------------
@ -197,14 +190,21 @@ void PlayerManager::load()
return;
}
m_current_player = NULL;
for(unsigned int i=0; i<m_player_data->getNumNodes(); i++)
std::vector<XMLNode*> player_list;
m_player_data->getNodes("player", player_list);
for(unsigned int i=0; i<player_list.size(); i++)
{
const XMLNode *player_xml = m_player_data->getNode(i);
const XMLNode *player_xml = player_list[i];
PlayerProfile *player = new Online::OnlinePlayerProfile(player_xml);
m_all_players.push_back(player);
if(player->isDefault())
m_current_player = player;
}
m_current_player = NULL;
const XMLNode *current = m_player_data->getNode("current");
if(current)
{
stringw name;
current->get("player", &name);
m_current_player = getPlayer(name);
}
} // load
@ -218,6 +218,12 @@ void PlayerManager::load()
*/
void PlayerManager::initRemainingData()
{
// Filter the player nodes out (there is one additional node 'online-ids'
// which makes this necessary), otherwise the index of m_all_players
// is not identical with the index in the xml file.
std::vector<XMLNode*> player_nodes;
if(m_player_data)
m_player_data->getNodes("player", player_nodes);
for (unsigned int i = 0; i<m_all_players.size(); i++)
{
// On the first time STK is run, there is no player data,
@ -226,7 +232,7 @@ void PlayerManager::initRemainingData()
if (!m_player_data)
m_all_players[i].initRemainingData();
else // not a first time start, load remaining data
m_all_players[i].loadRemainingData(m_player_data->getNode(i));
m_all_players[i].loadRemainingData(player_nodes[i]);
}
delete m_player_data;
@ -249,6 +255,12 @@ void PlayerManager::save()
players_file << L"<?xml version=\"1.0\"?>\n";
players_file << L"<players version=\"1\" >\n";
if(m_current_player && UserConfigParams::m_remember_user)
{
players_file << L" <current player=\""
<< m_current_player->getName() << L"\"/>\n";
}
PlayerProfile *player;
for_in(player, m_all_players)
{
@ -270,9 +282,11 @@ void PlayerManager::save()
/** Adds a new player to the list of all players.
* \param name Name of the new player.
*/
void PlayerManager::addNewPlayer(const core::stringw& name)
PlayerProfile* PlayerManager::addNewPlayer(const core::stringw& name)
{
m_all_players.push_back( new Online::OnlinePlayerProfile(name) );
PlayerProfile *profile = new Online::OnlinePlayerProfile(name);
m_all_players.push_back(profile);
return profile;
} // addNewPlayer
// ----------------------------------------------------------------------------
@ -281,6 +295,8 @@ void PlayerManager::addNewPlayer(const core::stringw& name)
void PlayerManager::deletePlayer(PlayerProfile *player)
{
m_all_players.erase(player);
if(player==m_current_player)
m_current_player = NULL;
} // deletePlayer
// ----------------------------------------------------------------------------
@ -315,7 +331,7 @@ void PlayerManager::enforceCurrentPlayer()
if (!player->isGuestAccount())
{
Log::info("PlayerManager", "Enfocring current player '%s'.",
player->getName().c_str());
player->getName().c_str());
m_current_player = player;
return;
}
@ -350,6 +366,20 @@ void PlayerManager::addDefaultPlayer()
m_all_players.push_back(new Online::OnlinePlayerProfile(_LTR("Guest"), /*guest*/true));
} // addDefaultPlayer
// ----------------------------------------------------------------------------
/** Returns the number of 'real' (non-guest) players.
*/
unsigned int PlayerManager::getNumNonGuestPlayers() const
{
unsigned int count=0;
const PlayerProfile *player;
for_in(player, m_all_players)
{
if(!player->isGuestAccount()) count ++;
}
return count;
} // getNumNonGuestPlayers
// ----------------------------------------------------------------------------
/** This returns a unique id. This is 1 + largest id used so far.
*/
@ -399,24 +429,15 @@ PlayerProfile *PlayerManager::getPlayer(const irr::core::stringw &name)
} // getPlayer
// ----------------------------------------------------------------------------
/** Sets the current player. This is the player that is used for story mode
* and achievements. If 'remember_me' is set, this information will be
* stored in the players.xml file, and automatically loaded next time
* STK is started.
* and achievements.
* \param Player profile to be the current player.
* \param remember_me If this player should be marked as default
* player in players.xml
*/
void PlayerManager::setCurrentPlayer(PlayerProfile *player, bool remember_me)
void PlayerManager::setCurrentPlayer(PlayerProfile *player)
{
// Reset current default player
if(m_current_player)
m_current_player->setDefault(false);
m_current_player = player;
if(m_current_player)
{
m_current_player->setDefault(remember_me);
m_current_player->computeActive();
}
} // setCurrentPlayer
// ----------------------------------------------------------------------------

View File

@ -91,11 +91,12 @@ public:
void initRemainingData();
unsigned int getUniqueId() const;
void addDefaultPlayer();
void addNewPlayer(const irr::core::stringw& name);
PlayerProfile* addNewPlayer(const irr::core::stringw& name);
void deletePlayer(PlayerProfile *player);
void setCurrentPlayer(PlayerProfile *player, bool remember_me);
void setCurrentPlayer(PlayerProfile *player);
const PlayerProfile *getPlayerById(unsigned int id);
void enforceCurrentPlayer();
unsigned int getNumNonGuestPlayers() const;
static void setUserDetails(Online::HTTPRequest *request,
const std::string &action,
const std::string &php_name = "");
@ -110,9 +111,7 @@ public:
static void onSTKQuit();
static void requestSignOut();
static Online::XMLRequest *requestSignIn(const irr::core::stringw &username,
const irr::core::stringw &password,
bool save_session,
bool request_now = true);
const irr::core::stringw &password);
// ------------------------------------------------------------------------
/** Returns the current player. */

View File

@ -21,14 +21,13 @@
#include "achievements/achievements_manager.hpp"
#include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "online/online_player_profile.hpp"
#include "io/xml_node.hpp"
#include "io/utf_writer.hpp"
#include "utils/string_utils.hpp"
#include <sstream>
#include <stdlib.h>
//------------------------------------------------------------------------------
/** Constructor to create a new player that didn't exist before.
* \param name Name of the player.
@ -43,13 +42,12 @@ PlayerProfile::PlayerProfile(const core::stringw& name, bool is_guest)
m_is_guest_account = is_guest;
m_use_frequency = is_guest ? -1 : 0;
m_unique_id = PlayerManager::get()->getUniqueId();
m_is_default = false;
m_is_default = false;
m_saved_session = false;
m_saved_token = "";
m_saved_user_id = 0;
m_achievements_status = NULL;
m_story_mode_status = NULL;
m_last_online_name = "";
m_last_was_online = false;
initRemainingData();
} // PlayerProfile
//------------------------------------------------------------------------------
@ -59,11 +57,12 @@ PlayerProfile::PlayerProfile(const core::stringw& name, bool is_guest)
* that the achievement and story mode data depends on other data to be
* read first (challenges and achievement files), which in turn can only be
* created later in the startup process (they depend on e.g. all tracks to
* be known). On the other hand, automatic login needs to happen asap
* (i.e. as soon as the network thread is started), which needs the main
* player data (i.e. the default player, and saved session data). So the
* constructor only reads this data, the rest of the player data is handled
* in loadRemainingData later in the initialisation process.
* be known). On the other hand, automatic login needs to happen asap (i.e.
* as soon as the network thread is started) to avoid the player having to
* wait for the login to finish , which needs the main player data (i.e.
* the default player, and saved session data). So the constructor only
* reads this data, the rest of the player data is handled in
* loadRemainingData later in the initialisation process.
* \param node The XML node representing this player.
*/
PlayerProfile::PlayerProfile(const XMLNode* node)
@ -71,21 +70,27 @@ PlayerProfile::PlayerProfile(const XMLNode* node)
m_saved_session = false;
m_saved_token = "";
m_saved_user_id = 0;
m_last_online_name = "";
m_last_was_online = false;
m_story_mode_status = NULL;
m_achievements_status = NULL;
m_icon_filename = "";
node->get("name", &m_local_name );
node->get("guest", &m_is_guest_account);
node->get("use-frequency", &m_use_frequency );
node->get("unique-id", &m_unique_id );
node->get("is-default", &m_is_default );
node->get("saved-session", &m_saved_session );
node->get("saved-user", &m_saved_user_id );
node->get("saved-token", &m_saved_token );
node->get("name", &m_local_name );
node->get("guest", &m_is_guest_account);
node->get("use-frequency", &m_use_frequency );
node->get("unique-id", &m_unique_id );
node->get("saved-session", &m_saved_session );
node->get("saved-user", &m_saved_user_id );
node->get("saved-token", &m_saved_token );
node->get("last-online-name", &m_last_online_name);
node->get("last-was-online", &m_last_was_online );
node->get("icon-filename", &m_icon_filename );
#ifdef DEBUG
m_magic_number = 0xABCD1234;
#endif
} // PlayerProfile
//------------------------------------------------------------------------------
@ -110,6 +115,8 @@ void PlayerProfile::loadRemainingData(const XMLNode *node)
const XMLNode *xml_achievements = node->getNode("achievements");
m_achievements_status = AchievementsManager::get()
->createAchievementsStatus(xml_achievements);
// Fix up any potentially missing icons.
addIcon();
} // initRemainingData
//------------------------------------------------------------------------------
@ -121,8 +128,60 @@ void PlayerProfile::initRemainingData()
m_story_mode_status = unlock_manager->createStoryModeStatus();
m_achievements_status =
AchievementsManager::get()->createAchievementsStatus();
addIcon();
} // initRemainingData
//------------------------------------------------------------------------------
/** Creates an icon for a player. It takes the unique player id modulo the
* number of karts to pick an icon from the karts. It then uses the unique
* number plus the extentsion of the original icon as the file name (it's
* not possible to use the player name, since the name is in utf-16, but
* typically the file systems are not, resulting in incorrect file names).
* The icon is then copied to the user config directory, so that it can
* be replaced by an icon made by the user.
* If there should be an error copying the file, the icon filename is set
* to "". Every time stk is started, it will try to fix missing icons
* (which allows it to start from old/incompatible config files).
* \pre This function must only be called after all karts are read in.
*/
void PlayerProfile::addIcon()
{
int n = m_unique_id % kart_properties_manager->getNumberOfKarts();
std::string source = kart_properties_manager->getKartById(n)
->getAbsoluteIconFile();
// Create the filename for the icon of this player: the unique id
// followed by .png or .jpg.
std::ostringstream out;
out << m_unique_id <<"."<<StringUtils::getExtension(source);
if(file_manager->copyFile(source,
file_manager->getUserConfigFile(out.str())) )
{
m_icon_filename = out.str();
}
else
{
m_icon_filename = "";
}
} // addIcon
//------------------------------------------------------------------------------
/** Returns the name of the icon file for this player. If the player icon
* file is undefined, it returns a "?" mark texture. Note, getAsset does
* not return a reference, but only a temporary string. So we must return a
* copy of the string (not a reference to).
*/
const std::string PlayerProfile::getIconFilename() const
{
// If the icon file is undefined or does not exist, return the "?" icon
if(m_icon_filename.size()==0 ||
!file_manager->fileExists(file_manager->getUserConfigFile(m_icon_filename)))
{
return file_manager->getAsset(FileManager::GUI, "main_help.png");
}
return file_manager->getUserConfigFile(m_icon_filename);
} // getIconFilename
//------------------------------------------------------------------------------
/** Writes the data for this player to the specified UTFWriter.
* \param out The utf writer to write the data to.
@ -133,13 +192,15 @@ void PlayerProfile::save(UTFWriter &out)
<< L"\" guest=\"" << m_is_guest_account
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n";
out << L" is-default=\"" << m_is_default
<< L"\" unique-id=\"" << m_unique_id
out << L" icon-filename=\"" << m_icon_filename <<L"\"\n";
out << L" unique-id=\"" << m_unique_id
<< L"\" saved-session=\"" << m_saved_session << L"\"\n";
out << L" saved-user=\"" << m_saved_user_id
<< L"\" saved-token=\"" << m_saved_token << L"\">\n";
<< L"\" saved-token=\"" << m_saved_token << L"\"\n";
out << L" last-online-name=\"" << m_last_online_name
<< L"\" last-was-online=\"" << m_last_was_online<< L"\">\n";
{
if(m_story_mode_status)
m_story_mode_status->save(out);

View File

@ -83,8 +83,8 @@ private:
/** A unique number for this player, used to link it to challenges etc. */
unsigned int m_unique_id;
/** True if this is the default (last used) player. */
bool m_is_default;
/** Absolute path of the icon file for this player. */
std::string m_icon_filename;
/** True if this user has a saved session. */
bool m_saved_session;
@ -95,6 +95,12 @@ private:
/** The token of the saved session. */
std::string m_saved_token;
/** The online user name used last (empty if not used online). */
core::stringw m_last_online_name;
/** True if the last time this player was used as online. */
bool m_last_was_online;
/** The complete challenge state. */
StoryModeStatus *m_story_mode_status;
@ -114,25 +120,25 @@ public:
void raceFinished();
void saveSession(int user_id, const std::string &token);
void clearSession();
void addIcon();
/** Abstract virtual classes, to be implemented by the OnlinePlayer. */
virtual void setUserDetails(Online::HTTPRequest *request,
const std::string &action,
const std::string &php_script = "") = 0;
const std::string &php_script = "") const = 0;
virtual uint32_t getOnlineId() const = 0;
virtual PlayerProfile::OnlineState getOnlineState() const = 0;
virtual Online::OnlineProfile* getProfile() const = 0;
virtual void requestPoll() const = 0;
virtual void requestSavedSession() = 0;
virtual void onSTKQuit() const = 0;
virtual Online::XMLRequest* requestSignIn(const irr::core::stringw &username,
const irr::core::stringw &password,
bool save_session,
bool request_now = true) = 0;
const irr::core::stringw &password) = 0;
virtual void signIn(bool success, const XMLNode * input) = 0;
virtual void signOut(bool success, const XMLNode * input) = 0;
virtual void signOut(bool success, const XMLNode * input,
const irr::core::stringw &info) = 0;
virtual void requestSignOut() = 0;
virtual bool isLoggedIn() const { return false; }
const std::string getIconFilename() const;
// ------------------------------------------------------------------------
/** Sets the name of this player. */
void setName(const core::stringw& name)
@ -160,16 +166,21 @@ public:
#endif
return m_is_guest_account;
} // isGuestAccount
// ------------------------------------------------------------------------
/** Returns the last used online name. */
const core::stringw& getLastOnlineName() const
{
return m_last_online_name;
} // getLastOnlineName
// ------------------------------------------------------------------------
/** Sets the last used online name. */
void setLastOnlineName(const core::stringw &name)
{
m_last_online_name = name;
} // setLastOnlineName
// ------------------------------------------------------------------------
/** Returns the unique id of this player. */
unsigned int getUniqueID() const { return m_unique_id; }
// -----------------------------------------------------------------------
/** Returns true if this is the default (last used) player. */
bool isDefault() const { return m_is_default; }
// ------------------------------------------------------------------------
/** Sets if this player is the default player or not. */
void setDefault(bool is_default) { m_is_default = is_default; }
// ------------------------------------------------------------------------
/** Returnes if the feature (kart, track) is locked. */
bool isLocked(const std::string &feature) const
@ -252,6 +263,13 @@ public:
return m_saved_token;
} // getSavedToken
// ------------------------------------------------------------------------
/** Returns if the last time this player was used it was used online or
* offline. */
bool wasOnlineLastTime() const { return m_last_was_online; }
// ------------------------------------------------------------------------
/** Sets if this player was logged in last time it was used. */
void setWasOnlineLastTime(bool b) { m_last_was_online = b; }
// ------------------------------------------------------------------------
}; // class PlayerProfile
#endif

View File

@ -677,6 +677,11 @@ namespace UserConfigParams
"wasn't asked, 1: allowed, 2: "
"not allowed") );
// ---- User managerment
PARAM_PREFIX BoolUserConfigParam m_remember_user
PARAM_DEFAULT( BoolUserConfigParam(true, "remember_me",
"Automatically remember login data"));
// ---- Online gameplay related
PARAM_PREFIX GroupUserConfigParam m_online_group

File diff suppressed because it is too large Load Diff

View File

@ -1,229 +1,229 @@
#ifndef GLWRAP_HEADER_H
#define GLWRAP_HEADER_H
#if defined(__APPLE__)
# include <OpenGL/gl.h>
# include <OpenGL/gl3.h>
# define OGL32CTX
# ifdef GL_ARB_instanced_arrays
# define glVertexAttribDivisor glVertexAttribDivisorARB
# endif
# ifndef GL_TEXTURE_SWIZZLE_RGBA
# define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
# endif
#elif defined(ANDROID)
# include <GLES/gl.h>
#elif defined(WIN32)
# define _WINSOCKAPI_
// has to be included before gl.h because of WINGDIAPI and APIENTRY definitions
# include <windows.h>
# include <GL/gl.h>
#else
#define GL_GLEXT_PROTOTYPES
#define DEBUG_OUTPUT_DECLARED
# include <GL/gl.h>
#endif
#include <vector>
#include "utils/log.hpp"
// already includes glext.h, which defines useful GL constants.
// COpenGLDriver has already loaded the extension GL functions we use (e.g glBeginQuery)
#include "../../lib/irrlicht/source/Irrlicht/COpenGLDriver.h"
#ifdef WIN32
extern PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks;
extern PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback;
extern PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback;
extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
extern PFNGLGENBUFFERSPROC glGenBuffers;
extern PFNGLBINDBUFFERPROC glBindBuffer;
extern PFNGLBUFFERDATAPROC glBufferData;
extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
extern PFNGLCREATESHADERPROC glCreateShader;
extern PFNGLCOMPILESHADERPROC glCompileShader;
extern PFNGLSHADERSOURCEPROC glShaderSource;
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
extern PFNGLATTACHSHADERPROC glAttachShader;
extern PFNGLLINKPROGRAMPROC glLinkProgram;
extern PFNGLUSEPROGRAMPROC glUseProgram;
extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
extern PFNGLUNIFORM1FPROC glUniform1f;
extern PFNGLUNIFORM3FPROC glUniform3f;
extern PFNGLUNIFORM1FVPROC glUniform1fv;
extern PFNGLUNIFORM4FVPROC glUniform4fv;
extern PFNGLDELETESHADERPROC glDeleteShader;
extern PFNGLGETSHADERIVPROC glGetShaderiv;
extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
extern PFNGLACTIVETEXTUREPROC glActiveTexture;
extern PFNGLUNIFORM2FPROC glUniform2f;
extern PFNGLUNIFORM1IPROC glUniform1i;
extern PFNGLUNIFORM3IPROC glUniform3i;
extern PFNGLUNIFORM4IPROC glUniform4i;
extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
extern PFNGLBLENDEQUATIONPROC glBlendEquation;
extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
extern PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
extern PFNGLTEXBUFFERPROC glTexBuffer;
extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
extern PFNGLTEXIMAGE3DPROC glTexImage3D;
extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
extern PFNGLBLENDCOLORPROC glBlendColor;
extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
#ifdef DEBUG
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
#endif
#endif
void initGL();
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount);
void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF = false);
GLuint LoadShader(const char * file, unsigned type);
template<typename ... Types>
void loadAndAttach(GLint ProgramID)
{
return;
}
template<typename ... Types>
void loadAndAttach(GLint ProgramID, GLint ShaderType, const char *filepath, Types ... args)
{
GLint ShaderID = LoadShader(filepath, ShaderType);
glAttachShader(ProgramID, ShaderID);
glDeleteShader(ShaderID);
loadAndAttach(ProgramID, args...);
}
template<typename ...Types>
void printFileList()
{
return;
}
template<typename ...Types>
void printFileList(GLint ShaderType, const char *filepath, Types ... args)
{
Log::error("GLWrapp", filepath);
printFileList(args...);
}
template<typename ... Types>
GLint LoadProgram(Types ... args)
{
GLint ProgramID = glCreateProgram();
loadAndAttach(ProgramID, args...);
glLinkProgram(ProgramID);
GLint Result = GL_FALSE;
int InfoLogLength;
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
if (Result == GL_FALSE) {
Log::error("GLWrapp", "Error when linking these shaders :");
printFileList(args...);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char *ErrorMessage = new char[InfoLogLength];
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage);
Log::error("GLWrapp", ErrorMessage);
delete[] ErrorMessage;
}
GLenum glErr = glGetError();
if (glErr != GL_NO_ERROR)
{
Log::warn("IrrDriver", "GLWrap : OpenGL error %i\n", glErr);
}
return ProgramID;
}
class GPUTimer;
class ScopedGPUTimer
{
public:
ScopedGPUTimer(GPUTimer &);
~ScopedGPUTimer();
};
class GPUTimer
{
friend class ScopedGPUTimer;
GLuint query;
bool initialised;
public:
GPUTimer();
unsigned elapsedTimeus();
};
class FrameBuffer
{
private:
GLuint fbo;
std::vector<GLuint> RenderTargets;
GLuint DepthTexture;
size_t width, height;
public:
FrameBuffer();
FrameBuffer(const std::vector <GLuint> &RTTs, size_t w, size_t h);
FrameBuffer(const std::vector <GLuint> &RTTs, GLuint DS, size_t w, size_t h, bool layered = false);
~FrameBuffer();
void Bind();
std::vector<GLuint> &getRTT() { return RenderTargets; }
GLuint &getDepthTexture() { assert(DepthTexture); return DepthTexture; }
size_t getWidth() const { return width; }
size_t getHeight() const { return height; }
static void Blit(const FrameBuffer &Src, FrameBuffer &Dst, GLbitfield mask = GL_COLOR_BUFFER_BIT, GLenum filter = GL_NEAREST);
void BlitToDefault(size_t, size_t, size_t, size_t);
};
// core::rect<s32> needs these includes
#include <rect.h>
#include "utils/vec3.hpp"
GLuint getTextureGLuint(irr::video::ITexture *tex);
GLuint getDepthTexture(irr::video::ITexture *tex);
void resetTextureTable();
void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = false);
bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(const std::string& compressed_tex);
void draw3DLine(const core::vector3df& start,
const core::vector3df& end, irr::video::SColor color);
void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect<s32>& destRect,
const irr::core::rect<s32>& sourceRect, const irr::core::rect<s32>* clipRect,
const irr::video::SColor &color, bool useAlphaChannelOfTexture);
void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect<s32>& destRect,
const irr::core::rect<s32>& sourceRect, const irr::core::rect<s32>* clipRect,
const irr::video::SColor* const colors, bool useAlphaChannelOfTexture);
void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect<s32>& position,
const irr::core::rect<s32>* clip = 0);
#endif
#ifndef GLWRAP_HEADER_H
#define GLWRAP_HEADER_H
#if defined(__APPLE__)
# include <OpenGL/gl.h>
# include <OpenGL/gl3.h>
# define OGL32CTX
# ifdef GL_ARB_instanced_arrays
# define glVertexAttribDivisor glVertexAttribDivisorARB
# endif
# ifndef GL_TEXTURE_SWIZZLE_RGBA
# define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
# endif
#elif defined(ANDROID)
# include <GLES/gl.h>
#elif defined(WIN32)
# define _WINSOCKAPI_
// has to be included before gl.h because of WINGDIAPI and APIENTRY definitions
# include <windows.h>
# include <GL/gl.h>
#else
#define GL_GLEXT_PROTOTYPES
#define DEBUG_OUTPUT_DECLARED
# include <GL/gl.h>
#endif
#include <vector>
#include "utils/log.hpp"
// already includes glext.h, which defines useful GL constants.
// COpenGLDriver has already loaded the extension GL functions we use (e.g glBeginQuery)
#include "../../lib/irrlicht/source/Irrlicht/COpenGLDriver.h"
#ifdef WIN32
extern PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks;
extern PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback;
extern PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback;
extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
extern PFNGLGENBUFFERSPROC glGenBuffers;
extern PFNGLBINDBUFFERPROC glBindBuffer;
extern PFNGLBUFFERDATAPROC glBufferData;
extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
extern PFNGLCREATESHADERPROC glCreateShader;
extern PFNGLCOMPILESHADERPROC glCompileShader;
extern PFNGLSHADERSOURCEPROC glShaderSource;
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
extern PFNGLATTACHSHADERPROC glAttachShader;
extern PFNGLLINKPROGRAMPROC glLinkProgram;
extern PFNGLUSEPROGRAMPROC glUseProgram;
extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
extern PFNGLUNIFORM1FPROC glUniform1f;
extern PFNGLUNIFORM3FPROC glUniform3f;
extern PFNGLUNIFORM1FVPROC glUniform1fv;
extern PFNGLUNIFORM4FVPROC glUniform4fv;
extern PFNGLDELETESHADERPROC glDeleteShader;
extern PFNGLGETSHADERIVPROC glGetShaderiv;
extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
extern PFNGLACTIVETEXTUREPROC glActiveTexture;
extern PFNGLUNIFORM2FPROC glUniform2f;
extern PFNGLUNIFORM1IPROC glUniform1i;
extern PFNGLUNIFORM3IPROC glUniform3i;
extern PFNGLUNIFORM4IPROC glUniform4i;
extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
extern PFNGLBLENDEQUATIONPROC glBlendEquation;
extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
extern PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
extern PFNGLTEXBUFFERPROC glTexBuffer;
extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
extern PFNGLTEXIMAGE3DPROC glTexImage3D;
extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
extern PFNGLBLENDCOLORPROC glBlendColor;
extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
#ifdef DEBUG
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
#endif
#endif
void initGL();
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount);
void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF = false);
GLuint LoadShader(const char * file, unsigned type);
template<typename ... Types>
void loadAndAttach(GLint ProgramID)
{
return;
}
template<typename ... Types>
void loadAndAttach(GLint ProgramID, GLint ShaderType, const char *filepath, Types ... args)
{
GLint ShaderID = LoadShader(filepath, ShaderType);
glAttachShader(ProgramID, ShaderID);
glDeleteShader(ShaderID);
loadAndAttach(ProgramID, args...);
}
template<typename ...Types>
void printFileList()
{
return;
}
template<typename ...Types>
void printFileList(GLint ShaderType, const char *filepath, Types ... args)
{
Log::error("GLWrapp", filepath);
printFileList(args...);
}
template<typename ... Types>
GLint LoadProgram(Types ... args)
{
GLint ProgramID = glCreateProgram();
loadAndAttach(ProgramID, args...);
glLinkProgram(ProgramID);
GLint Result = GL_FALSE;
int InfoLogLength;
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
if (Result == GL_FALSE) {
Log::error("GLWrapp", "Error when linking these shaders :");
printFileList(args...);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char *ErrorMessage = new char[InfoLogLength];
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage);
Log::error("GLWrapp", ErrorMessage);
delete[] ErrorMessage;
}
GLenum glErr = glGetError();
if (glErr != GL_NO_ERROR)
{
Log::warn("IrrDriver", "GLWrap : OpenGL error %i\n", glErr);
}
return ProgramID;
}
class GPUTimer;
class ScopedGPUTimer
{
public:
ScopedGPUTimer(GPUTimer &);
~ScopedGPUTimer();
};
class GPUTimer
{
friend class ScopedGPUTimer;
GLuint query;
bool initialised;
public:
GPUTimer();
unsigned elapsedTimeus();
};
class FrameBuffer
{
private:
GLuint fbo;
std::vector<GLuint> RenderTargets;
GLuint DepthTexture;
size_t width, height;
public:
FrameBuffer();
FrameBuffer(const std::vector <GLuint> &RTTs, size_t w, size_t h);
FrameBuffer(const std::vector <GLuint> &RTTs, GLuint DS, size_t w, size_t h, bool layered = false);
~FrameBuffer();
void Bind();
std::vector<GLuint> &getRTT() { return RenderTargets; }
GLuint &getDepthTexture() { assert(DepthTexture); return DepthTexture; }
size_t getWidth() const { return width; }
size_t getHeight() const { return height; }
static void Blit(const FrameBuffer &Src, FrameBuffer &Dst, GLbitfield mask = GL_COLOR_BUFFER_BIT, GLenum filter = GL_NEAREST);
void BlitToDefault(size_t, size_t, size_t, size_t);
};
// core::rect<s32> needs these includes
#include <rect.h>
#include "utils/vec3.hpp"
GLuint getTextureGLuint(irr::video::ITexture *tex);
GLuint getDepthTexture(irr::video::ITexture *tex);
void resetTextureTable();
void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = false);
bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(const std::string& compressed_tex);
void draw3DLine(const core::vector3df& start,
const core::vector3df& end, irr::video::SColor color);
void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect<s32>& destRect,
const irr::core::rect<s32>& sourceRect, const irr::core::rect<s32>* clipRect,
const irr::video::SColor &color, bool useAlphaChannelOfTexture);
void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect<s32>& destRect,
const irr::core::rect<s32>& sourceRect, const irr::core::rect<s32>* clipRect,
const irr::video::SColor* const colors, bool useAlphaChannelOfTexture);
void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect<s32>& position,
const irr::core::rect<s32>* clip = 0);
#endif

View File

@ -1,14 +1,14 @@
#ifndef GPUPARTICLES_H
#define GPUPARTICLES_H
#include "graphics/glwrap.hpp"
#include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h"
#include <ISceneManager.h>
#include <IParticleSystemSceneNode.h>
namespace irr { namespace video{ class ITexture; } }
class ParticleSystemProxy : public scene::CParticleSystemSceneNode
{
protected:
@ -19,18 +19,18 @@ protected:
float size_increase_factor, track_x, track_z, track_x_len, track_z_len;
float m_color_from[3];
float m_color_to[3];
static GLuint quad_vertex_buffer;
GLuint texture;
unsigned count;
static void SimpleParticleVAOBind(GLuint PositionBuffer);
static void FlipParticleVAOBind(GLuint PositionBuffer, GLuint QuaternionBuffer);
static void SimpleSimulationBind(GLuint PositionBuffer, GLuint InitialValuesBuffer);
static void HeightmapSimulationBind(GLuint PositionBuffer, GLuint InitialValuesBuffer);
void generateVAOs();
void simulateHeightmap();
void simulateNoHeightmap();
void drawFlip();
@ -46,14 +46,14 @@ public:
const core::vector3df& position = core::vector3df(0, 0, 0),
const core::vector3df& rotation = core::vector3df(0, 0, 0),
const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f));
ParticleSystemProxy(bool createDefaultEmitter,
ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
const core::vector3df& position,
const core::vector3df& rotation,
const core::vector3df& scale);
~ParticleSystemProxy();
virtual void setEmitter(scene::IParticleEmitter* emitter);
virtual void render();
virtual void OnRegisterSceneNode();
@ -66,5 +66,5 @@ public:
void setHeightmap(const std::vector<std::vector<float> >&, float, float, float, float);
void setFlip();
};
#endif // GPUPARTICLES_H

View File

@ -305,10 +305,6 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
"Invalid graphical effect specification: '%s' - ignored.",
s.c_str());
}
else
{
m_shader_type = SHADERTYPE_SOLID;
}
bool use_normal_map = false;
node->get("use-normal-map", &use_normal_map);

View File

@ -473,7 +473,9 @@ void PostProcessing::renderSSAO()
glGenerateMipmap(GL_TEXTURE_2D);
setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR);
FullScreenShader::SSAOShader::setUniforms(core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0, 1);
FullScreenShader::SSAOShader::setUniforms(core::vector2df(float(UserConfigParams::m_width),
float(UserConfigParams::m_height)),
0, 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

View File

@ -170,7 +170,7 @@ void IrrDriver::renderGLSL(float dt)
UtilShader::ColoredLine::setUniforms(it->first);
const std::vector<float> &vertex = it->second;
const float *tmp = vertex.data();
for (int i = 0; i < vertex.size(); i += 1024 * 6)
for (unsigned int i = 0; i < vertex.size(); i += 1024 * 6)
{
unsigned count = MIN2(vertex.size() - i, 1024 * 6);
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]);
@ -313,7 +313,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
}
PROFILER_PUSH_CPU_MARKER("- Skybox", 0xFF, 0x00, 0xFF);
renderSkybox(camnode);
if (!SkyboxTextures.empty())
renderSkybox(camnode);
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00);
@ -493,17 +494,44 @@ void IrrDriver::renderSolidFirstPass()
glUseProgram(MeshShader::ObjectPass1Shader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
{
drawObjectPass1(*GroupedFPSM<FPSM_DEFAULT>::MeshSet[i], GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT>::TIMVSet[i]);
const GLMesh &mesh = *GroupedFPSM<FPSM_DEFAULT>::MeshSet[i];
if (mesh.textures[0])
{
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
}
else
{
setTexture(0, 0, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, false);
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
draw<MeshShader::ObjectPass1Shader>(mesh, mesh.vao_first_pass, GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT>::TIMVSet[i], 0);
if (!mesh.textures[0])
{
GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
}
glUseProgram(MeshShader::ObjectRefPass1Shader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet.size(); ++i)
{
drawObjectRefPass1(*GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::TIMVSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
const GLMesh &mesh = *GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i];
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::ObjectRefPass1Shader>(mesh, mesh.vao_first_pass, GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::TIMVSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix, 0);
}
glUseProgram(MeshShader::NormalMapShader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet.size(); ++i)
{
drawNormalPass(*GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet[i]);
const GLMesh &mesh = *GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i];
assert(mesh.textures[1]);
compressTexture(mesh.textures[1], false);
setTexture(0, getTextureGLuint(mesh.textures[1]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
compressTexture(mesh.textures[0], true);
setTexture(1, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::NormalMapShader>(mesh, mesh.vao_first_pass, GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet[i], 0, 1);
}
}
}
@ -695,8 +723,8 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
size_t size = irr_driver->getShadowViewProj().size();
for (unsigned i = 0; i < size; i++)
memcpy(&tmp[16 * i + 64], irr_driver->getShadowViewProj()[i].pointer(), 16 * sizeof(float));
tmp[128] = width;
tmp[129] = height;
tmp[128] = float(width);
tmp[129] = float(height);
glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO);
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 8 + 2) * sizeof(float), tmp);

View File

@ -179,7 +179,6 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
case scene::EPT_QUADS:
assert(0 && "Unsupported primitive type");
}
ITexture *tex;
for (unsigned i = 0; i < 6; i++)
result.textures[i] = mb->getMaterial().getTexture(i);
result.TextureMatrix = 0;
@ -213,56 +212,6 @@ core::vector3df getWind()
return m_speed * vector3df(1., 0., 0.) * cos(time);
}
void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
if (mesh.textures[0])
{
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
}
else
{
setTexture(0, 0, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, false);
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
MeshShader::ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0);
assert(mesh.vao_first_pass);
glBindVertexArray(mesh.vao_first_pass);
glDrawElements(ptype, count, itype, 0);
if (!mesh.textures[0])
{
GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
}
void drawObjectRefPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::ObjectRefPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix, 0);
assert(mesh.vao_first_pass);
glBindVertexArray(mesh.vao_first_pass);
glDrawElements(ptype, count, itype, 0);
}
void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, core::vector3df windDir)
{
irr_driver->IncreaseObjectCount();
@ -280,26 +229,6 @@ void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio
glDrawElements(ptype, count, itype, 0);
}
void drawNormalPass(const GLMesh &mesh, const core::matrix4 & ModelMatrix, const core::matrix4 &InverseModelMatrix)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
assert(mesh.textures[1]);
compressTexture(mesh.textures[1], false);
setTexture(0, getTextureGLuint(mesh.textures[1]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
compressTexture(mesh.textures[0], true);
setTexture(1, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::NormalMapShader::setUniforms(ModelMatrix, InverseModelMatrix, 0, 1);
assert(mesh.vao_first_pass);
glBindVertexArray(mesh.vao_first_pass);
glDrawElements(ptype, count, itype, 0);
}
void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix)
{
irr_driver->IncreaseObjectCount();

View File

@ -1,11 +1,13 @@
#ifndef STKMESH_H
#define STKMESH_H
#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp"
#include <IMeshSceneNode.h>
#include <IMesh.h>
#include "../lib/irrlicht/source/Irrlicht/CMeshSceneNode.h"
#include "glwrap.hpp"
#include <vector>
enum GeometricMaterial
@ -89,9 +91,22 @@ std::vector<core::matrix4> GroupedFPSM<T>::MVPSet;
template<enum GeometricMaterial T>
std::vector<core::matrix4> GroupedFPSM<T>::TIMVSet;
void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView);
void drawNormalPass(const GLMesh &mesh, const core::matrix4 & ModelMatrix, const core::matrix4 &InverseModelMatrix);
void drawObjectRefPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix);
template<typename Shader, typename...uniforms>
void draw(const GLMesh &mesh, GLuint vao, uniforms... Args)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
Shader::setUniforms(Args...);
assert(vao);
glBindVertexArray(vao);
glDrawElements(ptype, count, itype, 0);
}
void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, core::vector3df windDir);
// Pass 2 shader (ie shaders that outputs final color)

View File

@ -197,18 +197,9 @@ void STKMeshSceneNode::drawSolidPass1(const GLMesh &mesh, GeometricMaterial type
windDir = getWind();
switch (type)
{
case FPSM_NORMAL_MAP:
drawNormalPass(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
break;
case FPSM_ALPHA_REF_TEXTURE:
drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, mesh.TextureMatrix);
break;
case FPSM_GRASS:
drawGrassPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir);
break;
case FPSM_DEFAULT:
drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
break;
default:
assert(0 && "wrong geometric material");
}

View File

@ -17,6 +17,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef ENABLE_WIIUSE
#define WCONST
#include "input/wiimote_manager.hpp"
@ -61,24 +62,99 @@ WiimoteManager::~WiimoteManager()
*/
void WiimoteManager::launchDetection(int timeout)
{
// It's only needed on systems with bluez, because wiiuse_find does not find alredy connected wiimotes
#ifdef WIIUSE_BLUEZ
//Cleans up the config and the disconnected wiimotes
int number_previous_wiimotes = 0;
wiimote_t** previous_wiimotes = (wiimote_t**) malloc(sizeof(struct wiimote_t*) * MAX_WIIMOTES);
memset(previous_wiimotes,0,sizeof(struct wiimote_t*) * MAX_WIIMOTES);
for (unsigned int i = 0; i < m_wiimotes.size(); i++)
{
if (WIIMOTE_IS_CONNECTED(m_all_wiimote_handles[i]))
{
previous_wiimotes[i]=m_all_wiimote_handles[i];
m_all_wiimote_handles[i] = NULL;
number_previous_wiimotes++;
}
}
//To prevent segmentation fault, have to delete NULLs
wiimote_t** deletable_wiimotes = (wiimote_t**) malloc(sizeof(struct wiimote_t*) * (m_wiimotes.size()-number_previous_wiimotes));
memset(deletable_wiimotes,0,sizeof(struct wiimote_t*) * (m_wiimotes.size()-number_previous_wiimotes));
int number_deletables = 0;
for (unsigned int i = 0; i < m_wiimotes.size(); i++)
{
if (m_all_wiimote_handles[i] != NULL)
{
deletable_wiimotes[number_deletables++] = m_all_wiimote_handles[i];
}
}
m_all_wiimote_handles = wiiuse_init(MAX_WIIMOTES);
wiiuse_cleanup(deletable_wiimotes, number_deletables);
#endif
// Stop WiiUse, remove wiimotes, gamepads, gamepad configs.
cleanup();
m_all_wiimote_handles = wiiuse_init(MAX_WIIMOTES);
m_all_wiimote_handles = wiiuse_init(MAX_WIIMOTES);
// Detect wiimotes
int nb_found_wiimotes = wiiuse_find(m_all_wiimote_handles, MAX_WIIMOTES, timeout);
#ifndef WIIUSE_BLUEZ
// Couldn't find any wiimote?
if(nb_found_wiimotes == 0)
return;
#endif
#ifdef WIIUSE_BLUEZ
// Couldn't find any wiimote?
if(nb_found_wiimotes + number_previous_wiimotes == 0)
return;
#endif
// Try to connect to all found wiimotes
int nb_wiimotes = wiiuse_connect(m_all_wiimote_handles, nb_found_wiimotes);
#ifndef WIIUSE_BLUEZ
// Couldn't connect to any wiimote?
if(nb_wiimotes == 0)
return;
#endif
#ifdef WIIUSE_BLUEZ
// Couldn't connect to any wiimote?
if(nb_wiimotes + number_previous_wiimotes == 0)
return;
//Merges previous and new wiimote's list
int number_merged_wiimotes = 0;
for (int i = 0; i < number_previous_wiimotes && i + nb_wiimotes < MAX_WIIMOTES; i++)
{
m_all_wiimote_handles[i+nb_wiimotes] = previous_wiimotes[i];
previous_wiimotes[i] = NULL;
m_all_wiimote_handles[i]->unid = nb_wiimotes+i+1;
number_merged_wiimotes++;
}
nb_wiimotes += number_merged_wiimotes;
//To prevent segmentation fault, have to delete NULLs
number_deletables = 0;
number_deletables = 0;
deletable_wiimotes = (wiimote_t**) malloc(sizeof(struct wiimote_t*) * (number_previous_wiimotes-number_merged_wiimotes));
memset(deletable_wiimotes,0,sizeof(struct wiimote_t*) * (number_previous_wiimotes-number_merged_wiimotes));
for (int i = 0; i < number_previous_wiimotes; i++)
{
if (previous_wiimotes[i] != NULL)
{
deletable_wiimotes[number_deletables++] = previous_wiimotes[i];
}
}
// Cleans up wiimotes which ones didn't fit in limit
wiiuse_cleanup(deletable_wiimotes, number_deletables);
#endif
// ---------------------------------------------------
// Create or find a GamepadConfig for all wiimotes

View File

@ -1214,7 +1214,47 @@ bool FileManager::removeDirectory(const std::string &name) const
#endif
} // remove directory
// ----------------------------------------------------------------------------
/** Copies the file source to dest.
* \param source The file to read.
* \param dest The new filename.
* \return True if the copy was successful, false otherwise.
*/
bool FileManager::copyFile(const std::string &source, const std::string &dest)
{
FILE *f_source = fopen(source.c_str(), "rb");
if(!f_source) return false;
FILE *f_dest = fopen(dest.c_str(), "wb");
if(!f_dest)
{
fclose(f_source);
return false;
}
const int BUFFER_SIZE=32768;
char *buffer = new char[BUFFER_SIZE];
if(!buffer) return false;
size_t n;
while((n=fread(buffer, 1, BUFFER_SIZE, f_source))>0)
{
if(fwrite(buffer, 1, n, f_dest)!=n)
{
Log::error("FileManager", "Write error copying '%s' to '%s",
source.c_str(), dest.c_str());
delete buffer;
fclose(f_source);
fclose(f_dest);
return false;
} // if fwrite()!=n
} // while
delete buffer;
fclose(f_source);
fclose(f_dest);
return true;
} // copyFile
// ----------------------------------------------------------------------------
/** Returns true if the first file is newer than the second. The comparison is
* based on the modification time of the two files.

View File

@ -123,6 +123,7 @@ public:
void checkAndCreateDirForAddons(const std::string &dir);
bool removeFile(const std::string &name) const;
bool removeDirectory(const std::string &name) const;
bool copyFile(const std::string &source, const std::string &dest);
std::vector<std::string>getMusicDirs() const;
std::string getAssetChecked(AssetType type, const std::string& name,
bool abort_on_error=false) const;

View File

@ -2291,7 +2291,7 @@ void Kart::updateFlying()
{
float orientation = getHeading();
m_body->applyCentralImpulse(btVector3(-100.0f*sin(orientation), 0.0,
-100.0*cos(orientation)));
-100.0f*cos(orientation)));
}
}

View File

@ -1,3 +1,4 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2013 Steve Baker <sjbaker1@airmail.net>
@ -187,9 +188,10 @@
#include "race/race_manager.hpp"
#include "replay/replay_play.hpp"
#include "replay/replay_recorder.hpp"
#include "states_screens/story_mode_lobby.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/register_screen.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
@ -383,6 +385,43 @@ void handleXmasMode()
if(xmas)
kart_properties_manager->setHatMeshName("christmas_hat.b3d");
} // handleXmasMode
// ============================================================================
/** This function sets up all data structure for an immediate race start.
* It is used when the -N or -R command line options are used.
*/
void setupRaceStart()
{
// Skip the start screen. This esp. means that no login screen is
// displayed (if necessary), so we have to make sure there is
// a current player
PlayerManager::get()->enforceCurrentPlayer();
InputDevice *device;
// Use keyboard 0 by default in --no-start-screen
device = input_manager->getDeviceList()->getKeyboard(0);
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(
PlayerManager::get()->getPlayer(0), device, NULL);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
{
Log::warn("main", "Kart '%s' is unknown so will use the "
"default kart.",
UserConfigParams::m_default_kart.c_str());
race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart.getDefaultValue());
}
else
{
// Set up race manager appropriately
race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart);
}
// ASSIGN should make sure that only input from assigned devices
// is read.
input_manager->getDeviceList()->setAssignMode(ASSIGN);
} // setupRaceMode
// ----------------------------------------------------------------------------
/** Prints help for command line options to stdout.
@ -962,8 +1001,7 @@ int handleCmdLine()
{
irr::core::stringw s;
Online::XMLRequest* request =
PlayerManager::requestSignIn(login, password, false, false);
request->executeNow();
PlayerManager::requestSignIn(login, password);
if (request->isSuccess())
{
@ -1250,7 +1288,20 @@ int main(int argc, char *argv[] )
if(!UserConfigParams::m_no_start_screen)
{
StateManager::get()->pushScreen(StoryModeLobbyScreen::getInstance());
// If there is a current player, it was saved in the config file,
// so we immediately start the main menu. Otherwise show the login
// screen first.
if(PlayerManager::getCurrentPlayer())
StateManager::get()->pushScreen(MainMenuScreen::getInstance());
else
{
StateManager::get()->pushScreen(UserScreen::getInstance());
// If there is no player, push the RegisterScreen on top of
// the login screen. This way on first start players are
// forced to create a player.
if(PlayerManager::get()->getNumPlayers()==0)
StateManager::get()->pushScreen(RegisterScreen::getInstance());
}
#ifdef ENABLE_WIIUSE
// Show a dialog to allow connection of wiimotes. */
if(WiimoteManager::isEnabled())
@ -1262,37 +1313,7 @@ int main(int argc, char *argv[] )
}
else
{
// Skip the start screen. This esp. means that no login screen is
// displayed (if necessary), so we have to make sure there is
// a current player
PlayerManager::get()->enforceCurrentPlayer();
InputDevice *device;
// Use keyboard 0 by default in --no-start-screen
device = input_manager->getDeviceList()->getKeyboard(0);
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(
PlayerManager::get()->getPlayer(0), device, NULL);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
{
Log::warn("main", "Kart '%s' is unknown so will use the "
"default kart.",
UserConfigParams::m_default_kart.c_str());
race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart.getDefaultValue());
}
else
{
// Set up race manager appropriately
race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart);
}
// ASSIGN should make sure that only input from assigned devices
// is read.
input_manager->getDeviceList()->setAssignMode(ASSIGN);
setupRaceStart();
// Go straight to the race
StateManager::get()->enterGameState();
}

View File

@ -85,6 +85,12 @@ namespace Online
return irr::core::stringw(_("Processing")) + loadingDots();
}
// ------------------------------------------------------------------------
/** Convenience function to type less in calls. */
irr::core::stringw loadingDots(const wchar_t *s)
{
return irr::core::stringw(s)+loadingDots();
}
// ------------------------------------------------------------------------
/**
* Shows a increasing number of dots.

View File

@ -31,6 +31,7 @@ namespace Online
namespace Messages
{
irr::core::stringw loadingDots (float interval = 0.5f, int max_dots = 3);
irr::core::stringw loadingDots (const wchar_t *s);
irr::core::stringw signingIn ();
irr::core::stringw signingOut ();
irr::core::stringw validatingInfo ();

View File

@ -27,11 +27,11 @@
#include "online/online_profile.hpp"
#include "online/profile_manager.hpp"
#include "online/servers_manager.hpp"
#include "states_screens/login_screen.hpp"
#include "states_screens/online_profile_friends.hpp"
#include "states_screens/user_screen.hpp"
#include "states_screens/dialogs/change_password_dialog.hpp"
#include "states_screens/dialogs/user_info_dialog.hpp"
#include "states_screens/dialogs/notification_dialog.hpp"
#include "states_screens/dialogs/user_info_dialog.hpp"
#include "utils/log.hpp"
#include "utils/translation.hpp"
@ -52,8 +52,8 @@ namespace Online
* \param action If not empty, the action to be set.
*/
void OnlinePlayerProfile::setUserDetails(HTTPRequest *request,
const std::string &action,
const std::string &php_script)
const std::string &action,
const std::string &php_script) const
{
if (php_script.size()>0)
request->setServerURL(php_script);
@ -74,7 +74,6 @@ namespace Online
{
m_online_state = OS_SIGNED_OUT;
m_token = "";
m_save_session = false;
m_profile = NULL;
} // OnlinePlayerProfile
@ -84,7 +83,6 @@ namespace Online
{
m_online_state = OS_SIGNED_OUT;
m_token = "";
m_save_session = false;
m_profile = NULL;
} // OnlinePlayerProfile
@ -94,11 +92,12 @@ namespace Online
void OnlinePlayerProfile::requestSavedSession()
{
SignInRequest * request = NULL;
if (m_online_state == OS_SIGNED_OUT && hasSavedSession() )
if (m_online_state == OS_SIGNED_OUT && hasSavedSession())
{
request = new SignInRequest(true);
request->setServerURL("client-user.php");
request->addParameter("action", "saved-session" );
setUserDetails(request, "saved-session");
// The userid must be taken from the saved data,
// setUserDetails takes it from current data.
request->addParameter("userid", getSavedUserId());
request->addParameter("token", getSavedToken() );
request->queue();
@ -110,29 +109,25 @@ namespace Online
/** Create a signin request.
* \param username Name of user.
* \param password Password.
* \param save_session If true, the login credential will be saved to
* allow a password-less login.
* \param request_now Immediately submit this request to the
* RequestManager.
*/
OnlinePlayerProfile::SignInRequest*
OnlinePlayerProfile::requestSignIn(const core::stringw &username,
const core::stringw &password,
bool save_session, bool request_now)
const core::stringw &password)
{
assert(m_online_state == OS_SIGNED_OUT);
m_save_session = save_session;
// If the player changes the online account, there can be a
// logout stil happening.
assert(m_online_state == OS_SIGNED_OUT ||
m_online_state == OS_SIGNING_OUT );
SignInRequest * request = new SignInRequest(false);
// We can't use setUserDetail here, since there is no token yet
request->setServerURL("client-user.php");
request->addParameter("action","connect");
request->addParameter("username",username);
request->addParameter("password",password);
request->addParameter("save-session", save_session);
if (request_now)
{
request->queue();
m_online_state = OS_SIGNING_IN;
}
request->addParameter("save-session",
UserConfigParams::m_remember_user);
request->queue();
m_online_state = OS_SIGNING_IN;
return request;
} // requestSignIn
@ -143,7 +138,24 @@ namespace Online
{
PlayerManager::getCurrentPlayer()->signIn(isSuccess(), getXMLData());
GUIEngine::Screen *screen = GUIEngine::getCurrentScreen();
LoginScreen *login = dynamic_cast<LoginScreen*>(screen);
BaseUserScreen *login = dynamic_cast<BaseUserScreen*>(screen);
// If the login is successful, reset any saved session of other
// local players using the same online account (which are now invalid)
if(isSuccess())
{
PlayerProfile *current = PlayerManager::getCurrentPlayer();
for(unsigned int i=0; i<PlayerManager::get()->getNumPlayers(); i++)
{
PlayerProfile *player = PlayerManager::get()->getPlayer(i);
if(player!=current &&
player->hasSavedSession() &&
player->getLastOnlineName() == current->getLastOnlineName())
{
player->clearSession();
}
}
}
if(login)
{
if(isSuccess())
@ -170,10 +182,11 @@ namespace Online
int username_fetched = input->get("username", &username);
uint32_t userid(0);
int userid_fetched = input->get("userid", &userid);
setLastOnlineName(username);
m_profile = new OnlineProfile(userid, username, true);
assert(token_fetched && username_fetched && userid_fetched);
m_online_state = OS_SIGNED_IN;
if(doSaveSession())
if(UserConfigParams::m_remember_user)
{
saveSession(getOnlineId(), getToken() );
}
@ -194,38 +207,77 @@ namespace Online
} // signIn
// ------------------------------------------------------------------------
/** Requests a sign out from the server. If the user should be remembered,
* a 'client-quit' request is sent (which will log the user out, but
* remember the token), otherwise a 'disconnect' is sent.
*/
void OnlinePlayerProfile::requestSignOut()
{
assert(m_online_state == OS_SIGNED_IN || m_online_state == OS_GUEST);
SignOutRequest * request = new SignOutRequest();
request->setServerURL("client-user.php");
request->addParameter("action","disconnect");
request->addParameter("token", getToken());
request->addParameter("userid", getOnlineId());
// ----------------------------------------------------------------
class SignOutRequest : public XMLRequest
{
private:
PlayerProfile *m_player;
virtual void callback()
{
m_player->signOut(isSuccess(), getXMLData(), getInfo());
}
public:
/** Sign out request, with a higher priority than signin requests,
* so that when a user is changed the signout is done first
* (to avoid potential problems with a local user logged in twice
* - even if it's only a short period of time). */
SignOutRequest(PlayerProfile *player)
: XMLRequest(true,/*priority*/20)
{
m_player = player;
m_player->setUserDetails(this,
UserConfigParams::m_remember_user ? "client-quit"
:"disconnect");
} // SignOutRequest
}; // SignOutRequest
// ----------------------------------------------------------------
HTTPRequest *request = new SignOutRequest(this);
request->queue();
m_online_state = OS_SIGNING_OUT;
} // requestSignOut
// --------------------------------------------------------------------
void OnlinePlayerProfile::SignOutRequest::callback()
{
PlayerManager::getCurrentPlayer()->signOut(isSuccess(), getXMLData());
} // SignOutRequest::callback
// ------------------------------------------------------------------------
void OnlinePlayerProfile::signOut(bool success, const XMLNode * input)
/** Callback once the logout event has been processed.
* \param success If the request was successful.
* \param input
*/
void OnlinePlayerProfile::signOut(bool success, const XMLNode *input,
const irr::core::stringw &info)
{
if(!success)
GUIEngine::Screen *screen = GUIEngine::getCurrentScreen();
BaseUserScreen *user_screen = dynamic_cast<BaseUserScreen*>(screen);
// We can't do much of error handling here, no screen waits for
// a logout to finish, so we can only log the message to screen,
// and otherwise mark the player logged out internally.
if (!success)
{
Log::warn("OnlinePlayerProfile::signOut", "%s",
Log::warn("OnlinePlayerProfile::signOut",
"There were some connection issues while signing out. "
"Report a bug if this caused issues.");
Log::warn("OnlinePlayerProfile::signOut", core::stringc(info.c_str()).c_str());
if(user_screen)
user_screen->logoutError(info);
}
m_token = "";
else
{
if(user_screen)
user_screen->logoutSuccessful();
}
ProfileManager::get()->clearPersistent();
m_profile = NULL;
m_online_state = OS_SIGNED_OUT;
PlayerManager::getCurrentPlayer()->clearSession();
// Discard token if session should not be saved.
if(!UserConfigParams::m_remember_user)
clearSession();
} // signOut
// ------------------------------------------------------------------------
@ -236,10 +288,7 @@ namespace Online
{
assert(m_online_state == OS_SIGNED_IN);
OnlinePlayerProfile::PollRequest * request = new OnlinePlayerProfile::PollRequest();
request->setServerURL("client-user.php");
request->addParameter("action", "poll");
request->addParameter("token", getToken());
request->addParameter("userid", getOnlineId());
setUserDetails(request, "poll");
request->queue();
} // requestPoll()
@ -379,24 +428,6 @@ namespace Online
} // PollRequest::callback
// ------------------------------------------------------------------------
/** Sends a message to the server that the client has been closed, if a
* user is signed in.
*/
void OnlinePlayerProfile::onSTKQuit() const
{
if(isLoggedIn())
{
HTTPRequest * request =
new HTTPRequest(true, RequestManager::HTTP_MAX_PRIORITY);
request->setServerURL("client-user.php");
request->addParameter("action", "client-quit");
request->addParameter("token", getToken());
request->addParameter("userid", getOnlineId());
request->queue();
}
}
// ------------------------------------------------------------------------
/** \return the online id, or 0 if the user is not signed in.
*/

View File

@ -58,14 +58,6 @@ namespace Online
: XMLRequest(manage_memory, /*priority*/10) {}
}; // SignInRequest
// ----------------------------------------------------------------
class SignOutRequest : public XMLRequest
{
virtual void callback ();
public:
SignOutRequest() : XMLRequest(true,/*priority*/10) {}
}; // SignOutRequest
// ----------------------------------------------------------------
class PollRequest : public XMLRequest {
virtual void callback ();
@ -75,38 +67,20 @@ namespace Online
private:
std::string m_token;
bool m_save_session;
OnlineProfile *m_profile;
/** The state of the player (logged in, logging in, ...) */
PlayerProfile::OnlineState m_online_state;
bool doSaveSession() const { return m_save_session; }
virtual void signIn(bool success, const XMLNode * input);
virtual void signOut(bool success, const XMLNode * input);
// For now declare functions that will become part of PlayerManager
// or Playerprofile to be private, and give only PlayerManager
// access to them. FIXME
// FIXME: This apparently does not compile on linux :(
// So for now (while this is needed) I'll only add this on
// windows only (where it works).
#ifdef WIN32
friend class PlayerManager;
public:
#else
public:
#endif
virtual void signOut(bool success, const XMLNode * input,
const irr::core::stringw &info);
virtual uint32_t getOnlineId() const;
virtual void setUserDetails(Online::HTTPRequest *request,
const std::string &action,
const std::string &php_script = "");
const std::string &php_script = "") const;
virtual void requestPoll() const;
virtual void onSTKQuit() const;
// ----------------------------------------------------------------
/** Returns if this user is logged in. */
virtual bool isLoggedIn() const
@ -131,9 +105,7 @@ namespace Online
virtual void requestSavedSession();
virtual void requestSignOut();
virtual SignInRequest *requestSignIn(const irr::core::stringw &username,
const irr::core::stringw &password,
bool save_session,
bool request_now = true);
const irr::core::stringw &password);
public:
OnlinePlayerProfile(const XMLNode *player);

View File

@ -130,7 +130,8 @@ namespace Online
pthread_attr_destroy(&attr);
// In case that login id was not saved (or first start of stk),
// current player would not be defined at this stage.
if(PlayerManager::getCurrentPlayer())
PlayerProfile *player = PlayerManager::getCurrentPlayer();
if(player && player->wasOnlineLastTime())
PlayerManager::resumeSavedSession();
} // startNetworkThread

View File

@ -24,7 +24,6 @@
#include "input/device_manager.hpp"
#include "input/input_manager.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/cpp2011.h"

View File

@ -51,11 +51,11 @@ DebugSliderDialog::DebugSliderDialog(std::string id, irr::core::stringw msg) :
float val;
if (m_id == "lwhite")
val = irr_driver->getLwhite() * 10.;
val = irr_driver->getLwhite() * 10.f;
if (m_id == "exposure")
val = irr_driver->getExposure() * 100.;
val = irr_driver->getExposure() * 100.f;
getWidget<SpinnerWidget>("value_slider")->setValue(val);
getWidget<SpinnerWidget>("value_slider")->setValue(int(val));
}
// ------------------------------------------------------------------------------------------------------
@ -83,9 +83,9 @@ GUIEngine::EventPropagation DebugSliderDialog::processEvent(const std::string& e
int value = getWidget<SpinnerWidget>("value_slider")->getValue();
Log::info("DebugSlider", "Value for <%s> : %i", m_id.c_str(), value);
if (m_id == "lwhite")
irr_driver->setLwhite(value / 10.);
irr_driver->setLwhite(value / 10.f);
if (m_id == "exposure")
irr_driver->setExposure(value / 100.);
irr_driver->setExposure(value / 100.f);
return GUIEngine::EVENT_BLOCK;
}

View File

@ -1,162 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/dialogs/enter_player_name_dialog.hpp"
#include <IGUIEnvironment.h>
#include "audio/sfx_manager.hpp"
#include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp"
#include "config/player_profile.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/translation.hpp"
#include "utils/string_utils.hpp"
using namespace GUIEngine;
using namespace irr;
using namespace irr::core;
using namespace irr::gui;
// -----------------------------------------------------------------------------
EnterPlayerNameDialog::EnterPlayerNameDialog(INewPlayerListener* listener,
const float w, const float h) :
ModalDialog(w, h)
{
m_listener = listener;
m_self_destroy = false;
loadFromFile("enter_player_name_dialog.stkgui");
TextBoxWidget* textCtrl = getWidget<TextBoxWidget>("textfield");
assert(textCtrl != NULL);
textCtrl->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
//if (translations->isRTLLanguage()) textCtrl->addListener(this);
}
// -----------------------------------------------------------------------------
EnterPlayerNameDialog::~EnterPlayerNameDialog()
{
// FIXME: what is this code for?
TextBoxWidget* textCtrl = getWidget<TextBoxWidget>("textfield");
textCtrl->getIrrlichtElement()->remove();
textCtrl->clearListeners();
}
// -----------------------------------------------------------------------------
/*
void EnterPlayerNameDialog::onTextUpdated()
{
TextBoxWidget* textCtrl = getWidget<TextBoxWidget>("textfield");
LabelWidget* lbl = getWidget<LabelWidget>("preview");
lbl->setText( core::stringw(translations->fribidize(textCtrl->getText())), false );
}
*/
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation EnterPlayerNameDialog::processEvent(const std::string& eventSource)
{
if (eventSource == "cancel")
{
dismiss();
return GUIEngine::EVENT_BLOCK;
}
return GUIEngine::EVENT_LET;
}
// -----------------------------------------------------------------------------
void EnterPlayerNameDialog::onEnterPressedInternal()
{
// ---- Cancel button pressed
const int playerID = PLAYER_ID_GAME_MASTER;
ButtonWidget* cancelButton = getWidget<ButtonWidget>("cancel");
if (GUIEngine::isFocusedForPlayer(cancelButton, playerID))
{
std::string fakeEvent = "cancel";
processEvent(fakeEvent);
return;
}
// ---- Otherwise, see if we can accept the new name
TextBoxWidget* textCtrl = getWidget<TextBoxWidget>("textfield");
stringw player_name = textCtrl->getText().trim();
if (StringUtils::notEmpty(player_name))
{
// check for duplicates
const int amount = PlayerManager::get()->getNumPlayers();
for (int n=0; n<amount; n++)
{
if (PlayerManager::get()->getPlayer(n)->getName() == player_name)
{
LabelWidget* label = getWidget<LabelWidget>("title");
label->setText(_("Cannot add a player with this name."), false);
sfx_manager->quickSound( "anvil" );
return;
}
}
// Finally, add the new player.
PlayerManager::get()->addNewPlayer(player_name);
PlayerManager::get()->save();
// It's unsafe to delete from inside the event handler so we do it
// in onUpdate (which checks for m_self_destroy)
m_self_destroy = true;
} // if valid name
else
{
LabelWidget* label = getWidget<LabelWidget>("title");
label->setText(_("Cannot add a player with this name."), false);
sfx_manager->quickSound( "anvil" );
}
}
// -----------------------------------------------------------------------------
void EnterPlayerNameDialog::onUpdate(float dt)
{
// It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy)
{
TextBoxWidget* textCtrl = getWidget<TextBoxWidget>("textfield");
stringw player_name = textCtrl->getText().trim();
// irrLicht is too stupid to remove focus from deleted widgets
// so do it by hand
GUIEngine::getGUIEnv()->removeFocus( textCtrl->getIrrlichtElement() );
GUIEngine::getGUIEnv()->removeFocus( m_irrlicht_window );
// we will destroy the dialog before notifying the listener to be safer.
// but in order not to crash we must make a local copy of the listern
// otherwise we will crash
INewPlayerListener* listener = m_listener;
ModalDialog::dismiss();
if (listener != NULL) listener->onNewPlayerWithName( player_name );
}
}

View File

@ -1,71 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_ENTERPLAYERNAME_DIALOG_HPP
#define HEADER_ENTERPLAYERNAME_DIALOG_HPP
#include <irrString.h>
#include "guiengine/modaldialog.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
namespace GUIEngine
{
class TextBoxWidget;
class ButtonWidget;
class LabelWidget;
}
/**
* \brief Dialog that allows the player to enter the name for a new player
* \ingroup states_screens
*/
class EnterPlayerNameDialog : public GUIEngine::ModalDialog//, public GUIEngine::ITextBoxWidgetListener
{
public:
class INewPlayerListener
{
public:
virtual void onNewPlayerWithName(const irr::core::stringw& newName) = 0;
virtual ~INewPlayerListener(){}
};
private:
INewPlayerListener* m_listener;
bool m_self_destroy;
public:
/**
* Creates a modal dialog with given percentage of screen width and height
*/
EnterPlayerNameDialog(INewPlayerListener* listener, const float percentWidth,
const float percentHeight);
~EnterPlayerNameDialog();
void onEnterPressedInternal();
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
virtual void onUpdate(float dt);
//virtual void onTextUpdated();
};
#endif

View File

@ -1,312 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/dialogs/player_info_dialog.hpp"
#include <IGUIStaticText.h>
#include <IGUIEnvironment.h>
#include "audio/sfx_manager.hpp"
#include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp"
#include "config/player_profile.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
using namespace GUIEngine;
using namespace irr::gui;
using namespace irr::core;
// -----------------------------------------------------------------------------
/** Creates a modal dialog with given percentage of screen width and height.
*/
PlayerInfoDialog::PlayerInfoDialog(PlayerProfile* player, const float w,
const float h)
: ModalDialog(w, h)
{
m_player = player;
doInit();
showRegularDialog();
} // PlayerInfoDialog
// -----------------------------------------------------------------------------
/** When the dialog is finished, select the just edited player again in the
* option screen.
*/
PlayerInfoDialog::~PlayerInfoDialog()
{
if (m_player != NULL)
{
OptionsScreenPlayers::getInstance()->selectPlayer(
translations->fribidize(m_player->getName()) );
}
} // ~PlayerInfoDialog
// -----------------------------------------------------------------------------
/** Show the current data of this player.
*/
void PlayerInfoDialog::showRegularDialog()
{
if (m_irrlicht_window)
clearWindow();
const int y1 = m_area.getHeight()/6;
const int y2 = m_area.getHeight()*2/6;
const int y3 = m_area.getHeight()*3/6;
const int y4 = m_area.getHeight()*5/6;
ScalableFont* font = GUIEngine::getFont();
const int textHeight = GUIEngine::getFontHeight();
const int buttonHeight = textHeight + 10;
{
textCtrl = new TextBoxWidget();
textCtrl->m_properties[PROP_ID] = "newname";
textCtrl->setText(m_player->getName());
textCtrl->m_x = 50;
textCtrl->m_y = y1 - textHeight/2;
textCtrl->m_w = m_area.getWidth()-100;
textCtrl->m_h = textHeight + 5;
textCtrl->setParent(m_irrlicht_window);
m_widgets.push_back(textCtrl);
textCtrl->add();
}
{
ButtonWidget* widget = new ButtonWidget();
widget->m_properties[PROP_ID] = "renameplayer";
//I18N: In the player info dialog
widget->setText( _("Rename") );
const int textWidth =
font->getDimension( widget->getText().c_str() ).Width + 40;
widget->m_x = m_area.getWidth()/2 - textWidth/2;
widget->m_y = y2;
widget->m_w = textWidth;
widget->m_h = buttonHeight;
widget->setParent(m_irrlicht_window);
m_widgets.push_back(widget);
widget->add();
}
{
ButtonWidget* widget = new ButtonWidget();
widget->m_properties[PROP_ID] = "cancel";
widget->setText( _("Cancel") );
const int textWidth =
font->getDimension(widget->getText().c_str()).Width + 40;
widget->m_x = m_area.getWidth()/2 - textWidth/2;
widget->m_y = y3;
widget->m_w = textWidth;
widget->m_h = buttonHeight;
widget->setParent(m_irrlicht_window);
m_widgets.push_back(widget);
widget->add();
}
{
ButtonWidget* widget = new ButtonWidget();
widget->m_properties[PROP_ID] = "removeplayer";
//I18N: In the player info dialog
widget->setText( _("Remove"));
const int textWidth =
font->getDimension(widget->getText().c_str()).Width + 40;
widget->m_x = m_area.getWidth()/2 - textWidth/2;
widget->m_y = y4;
widget->m_w = textWidth;
widget->m_h = buttonHeight;
widget->setParent(m_irrlicht_window);
m_widgets.push_back(widget);
widget->add();
}
textCtrl->setFocusForPlayer( PLAYER_ID_GAME_MASTER );
} // showRegularDialog
// -----------------------------------------------------------------------------
/** Changes this dialog to confirm the changes.
*/
void PlayerInfoDialog::showConfirmDialog()
{
clearWindow();
IGUIFont* font = GUIEngine::getFont();
const int textHeight = GUIEngine::getFontHeight();
const int buttonHeight = textHeight + 10;
irr::core::stringw message =
//I18N: In the player info dialog (when deleting)
_("Do you really want to delete player '%s' ?", m_player->getName());
if (PlayerManager::getCurrentPlayer() == m_player)
{
message = _("You cannot delete this player "
"because it is currently in use.");
}
core::rect< s32 > area_left(5, 0, m_area.getWidth()-5, m_area.getHeight()/2);
// When there is no need to tab through / click on images/labels,
// we can add irrlicht labels directly
// (more complicated uses require the use of our widget set)
IGUIStaticText* a = GUIEngine::getGUIEnv()->addStaticText( message.c_str(),
area_left, false /* border */,
true /* word wrap */,
m_irrlicht_window);
a->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
if (PlayerManager::getCurrentPlayer() != m_player)
{
ButtonWidget* widget = new ButtonWidget();
widget->m_properties[PROP_ID] = "confirmremove";
//I18N: In the player info dialog (when deleting)
widget->setText( _("Confirm Remove") );
const int textWidth =
font->getDimension(widget->getText().c_str()).Width + 40;
widget->m_x = m_area.getWidth()/2 - textWidth/2;
widget->m_y = m_area.getHeight()/2;
widget->m_w = textWidth;
widget->m_h = buttonHeight;
widget->setParent(m_irrlicht_window);
m_widgets.push_back(widget);
widget->add();
}
{
ButtonWidget* widget = new ButtonWidget();
widget->m_properties[PROP_ID] = "cancelremove";
//I18N: In the player info dialog (when deleting)
widget->setText( _("Cancel Remove") );
const int textWidth =
font->getDimension( widget->getText().c_str() ).Width + 40;
widget->m_x = m_area.getWidth()/2 - textWidth/2;
widget->m_y = m_area.getHeight()*3/4;
widget->m_w = textWidth;
widget->m_h = buttonHeight;
widget->setParent(m_irrlicht_window);
m_widgets.push_back(widget);
widget->add();
widget->setFocusForPlayer( PLAYER_ID_GAME_MASTER );
}
} // showConfirmDialog
// -----------------------------------------------------------------------------
void PlayerInfoDialog::onEnterPressedInternal()
{
} // onEnterPressedInternal
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation
PlayerInfoDialog::processEvent(const std::string& eventSource)
{
if (eventSource == "renameplayer")
{
// accept entered name
stringw player_name = textCtrl->getText().trim();
const int player_amount = PlayerManager::get()->getNumPlayers();
for(int n=0; n<player_amount; n++)
{
const PlayerProfile *player = PlayerManager::get()->getPlayer(n);
if (player == m_player) continue;
if (player->getName() == player_name)
{
ButtonWidget* label = getWidget<ButtonWidget>("renameplayer");
label->setBadge(BAD_BADGE);
sfx_manager->quickSound( "anvil" );
return GUIEngine::EVENT_BLOCK;
}
}
if (player_name.size() <= 0) return GUIEngine::EVENT_BLOCK;
OptionsScreenPlayers::getInstance()->renamePlayer(player_name,m_player);
// irrLicht is too stupid to remove focus from deleted widgets
// so do it by hand
GUIEngine::getGUIEnv()->removeFocus( textCtrl->getIrrlichtElement() );
GUIEngine::getGUIEnv()->removeFocus( m_irrlicht_window );
ModalDialog::dismiss();
dismiss();
return GUIEngine::EVENT_BLOCK;
}
else if (eventSource == "removeplayer")
{
showConfirmDialog();
return GUIEngine::EVENT_BLOCK;
}
else if (eventSource == "confirmremove")
{
OptionsScreenPlayers::getInstance()->deletePlayer( m_player );
m_player = NULL;
// irrLicht is too stupid to remove focus from deleted widgets
// so do it by hand
GUIEngine::getGUIEnv()->removeFocus( textCtrl->getIrrlichtElement() );
GUIEngine::getGUIEnv()->removeFocus( m_irrlicht_window );
ModalDialog::dismiss();
return GUIEngine::EVENT_BLOCK;
}
else if(eventSource == "cancelremove")
{
showRegularDialog();
return GUIEngine::EVENT_BLOCK;
}
else if(eventSource == "cancel")
{
// irrLicht is too stupid to remove focus from deleted widgets
// so do it by hand
GUIEngine::getGUIEnv()->removeFocus( textCtrl->getIrrlichtElement() );
GUIEngine::getGUIEnv()->removeFocus( m_irrlicht_window );
ModalDialog::dismiss();
return GUIEngine::EVENT_BLOCK;
}
return GUIEngine::EVENT_LET;
} // processEvent
// -----------------------------------------------------------------------------

View File

@ -1,53 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_PLAYERINFO_DIALOG_HPP
#define HEADER_PLAYERINFO_DIALOG_HPP
#include "guiengine/modaldialog.hpp"
class PlayerProfile;
namespace GUIEngine
{
class TextBoxWidget;
}
/**
* \brief Dialog that allows renaming and deleting players
* \ingroup states_screens
*/
class PlayerInfoDialog : public GUIEngine::ModalDialog
{
GUIEngine::TextBoxWidget* textCtrl;
PlayerProfile* m_player;
void showRegularDialog();
void showConfirmDialog();
public:
PlayerInfoDialog(PlayerProfile* PlayerInfoDialog,
const float percentWidth, const float percentHeight);
virtual ~PlayerInfoDialog();
void onEnterPressedInternal();
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
};
#endif

View File

@ -1,78 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/guest_login_screen.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "states_screens/login_screen.hpp"
#include "states_screens/register_screen.hpp"
#include "states_screens/state_manager.hpp"
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( GuestLoginScreen );
// -----------------------------------------------------------------------------
GuestLoginScreen::GuestLoginScreen() : Screen("online/guest_login.stkgui")
{
} // GuestLoginScreen
// -----------------------------------------------------------------------------
/** Make sure this tab is actually selected.
*/
void GuestLoginScreen::init()
{
Screen::init();
RibbonWidget* tabs = this->getWidget<RibbonWidget>("login_tabs");
if (tabs) tabs->select( "tab_guest_login", PLAYER_ID_GAME_MASTER );
} // init
// -----------------------------------------------------------------------------
void GuestLoginScreen::eventCallback(Widget* widget, const std::string& name,
const int playerID)
{
if (name == "login_tabs")
{
const std::string selection =
((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (selection == "tab_login")
StateManager::get()->replaceTopMostScreen(LoginScreen::getInstance());
else if (selection == "tab_register")
StateManager::get()->replaceTopMostScreen(RegisterScreen::getInstance());
}
else if (name=="options")
{
const std::string button =
getWidget<RibbonWidget>("options")
->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if(button=="sign_in")
{
// FIXME TODO: guest login
}
else if(button=="cancel")
StateManager::get()->escapePressed();
}
else if (name == "back")
{
StateManager::get()->escapePressed();
}
} // eventCallback
// -----------------------------------------------------------------------------

View File

@ -1,48 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_GUEST_LOGIN_SCREEN_HPP
#define HEADER_GUEST_LOGIN_SCREEN_HPP
#include "guiengine/screen.hpp"
namespace GUIEngine { class Widget; }
/**
* \brief Gest-Login screen.
* \ingroup states_screens
*/
class GuestLoginScreen : public GUIEngine::Screen,
public GUIEngine::ScreenSingleton<GuestLoginScreen>
{
friend class GUIEngine::ScreenSingleton<GuestLoginScreen>;
GuestLoginScreen();
public:
virtual void init() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE {};
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget,
const std::string& name,
const int playerID) OVERRIDE;
}; // GuestLoginScreen
#endif

View File

@ -1,189 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/login_screen.hpp"
#include "audio/sfx_manager.hpp"
#include "config/player_manager.hpp"
#include "guiengine/widgets/check_box_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
#include "guiengine/widgets/check_box_widget.hpp"
#include "online/messages.hpp"
#include "states_screens/guest_login_screen.hpp"
#include "states_screens/online_screen.hpp"
#include "states_screens/register_screen.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/dialogs/recovery_dialog.hpp"
#include "utils/log.hpp"
#include "utils/translation.hpp"
#include <irrString.h>
using namespace GUIEngine;
using namespace irr;
DEFINE_SCREEN_SINGLETON( LoginScreen );
// -----------------------------------------------------------------------------
LoginScreen::LoginScreen() : Screen("online/login.stkgui")
{
} // LoginScreen
// -----------------------------------------------------------------------------
void LoginScreen::init()
{
Screen::init();
// Make sure this tab is actually focused.
RibbonWidget* tabs = this->getWidget<RibbonWidget>("login_tabs");
if (tabs) tabs->select( "tab_login", PLAYER_ID_GAME_MASTER );
TextBoxWidget *password_widget = getWidget<TextBoxWidget>("password");
password_widget->setPasswordBox(true,L'*');
m_options_widget = getWidget<RibbonWidget>("options");
assert(m_options_widget);
m_options_widget->setActivated();
m_info_widget = getWidget<LabelWidget>("info");
assert(m_info_widget != NULL);
m_success = false;
// As default don't select 'remember'
getWidget<CheckBoxWidget>("remember")->setState(false);
} // init
// -----------------------------------------------------------------------------
/** Collects the data entered into the gui and submits a login request.
* The login request is processes asynchronously b the ReqeustManager.
*/
void LoginScreen::login()
{
// Reset any potential error message shown.
LabelWidget *info_widget = getWidget<LabelWidget>("info");
info_widget->setDefaultColor();
info_widget->setText("", false);
const core::stringw username = getWidget<TextBoxWidget>("username")
->getText().trim();
const core::stringw password = getWidget<TextBoxWidget>("password")
->getText().trim();
if (username.size() < 4 || username.size() > 30 ||
password.size() < 8 || password.size() > 30 )
{
sfx_manager->quickSound("anvil");
info_widget->setErrorColor();
info_widget->setText(_("Username and/or password too short or too long."),
false);
}
else
{
m_options_widget->setDeactivated();
info_widget->setDefaultColor();
bool remember = getWidget<CheckBoxWidget>("remember")->getState();
PlayerManager::requestSignIn(username, password, remember);
}
} // login
// -----------------------------------------------------------------------------
/** Called from the login request when it was successfully exected.
*/
void LoginScreen::loginSuccessful()
{
// The callback is done from the main thread, so no need to sync
// access to m_success
m_success = true;
} // loginSuccessful
// -----------------------------------------------------------------------------
/** Called from the login request when the login was not successful.
* \param error_message The error message from the server (or curl).
*/
void LoginScreen::loginError(const irr::core::stringw & error_message)
{
sfx_manager->quickSound("anvil");
LabelWidget *info_widget = getWidget<LabelWidget>("info");
info_widget->setErrorColor();
info_widget->setText(error_message, false);
m_options_widget->setActivated();
} // loginError
// -----------------------------------------------------------------------------
/** Called in each frame. If a successful login is detected, the online screen
* will be displayed.
*/
void LoginScreen::onUpdate(float dt)
{
if(!m_options_widget->isActivated())
m_info_widget->setText(Online::Messages::signingIn(), false);
// Login was successful, so put the online main menu on the screen
if(m_success)
{
StateManager::get()->replaceTopMostScreen(OnlineScreen::getInstance());
}
} // onUpdate
// -----------------------------------------------------------------------------
/** Called when the user clicks on a widget.
* \param widget that was clicked on.
* \param name Name of the widget.
* \param playerID The id of the player who clicked the item.
*/
void LoginScreen::eventCallback(Widget* widget, const std::string& name,
const int playerID)
{
if (name == "login_tabs")
{
StateManager *sm = StateManager::get();
const std::string selection =
((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (selection == "tab_guest_login")
sm->replaceTopMostScreen(GuestLoginScreen::getInstance());
else if (selection == "tab_register")
sm->replaceTopMostScreen(RegisterScreen::getInstance());
}
else if (name=="options")
{
const std::string button =
getWidget<RibbonWidget>("options")
->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if(button=="sign_in")
{
login();
}
else if(button=="recovery")
{
new RecoveryDialog();
}
else if(button=="cancel")
StateManager::get()->escapePressed();
}
else if (name == "back")
{
StateManager::get()->escapePressed();
}
} // eventCallback
// -----------------------------------------------------------------------------

View File

@ -1,63 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_LOGIN_SCREEN_HPP
#define HEADER_LOGIN_SCREEN_HPP
#include "guiengine/screen.hpp"
namespace GUIEngine { class LabelWidget;
class RibbonWidget;
class Widget; }
/**
* \brief Login screen.
* \ingroup states_screens
*/
class LoginScreen : public GUIEngine::Screen,
public GUIEngine::ScreenSingleton<LoginScreen>
{
private:
friend class GUIEngine::ScreenSingleton<LoginScreen>;
LoginScreen();
void login();
/** Store a pointer to the options buttons. */
GUIEngine::RibbonWidget *m_options_widget;
GUIEngine::LabelWidget * m_info_widget;
bool m_success;
public:
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE {};
virtual void init() OVERRIDE;
virtual void onUpdate(float dt) OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget,
const std::string& name,
const int playerID) OVERRIDE;
void loginSuccessful();
void loginError(const irr::core::stringw & error_message);
}; // class LoginScreen
#endif

View File

@ -41,11 +41,11 @@
#include "states_screens/credits.hpp"
#include "states_screens/grand_prix_editor_screen.hpp"
#include "states_screens/help_screen_1.hpp"
#include "states_screens/login_screen.hpp"
#include "states_screens/offline_kart_selection.hpp"
#include "states_screens/online_screen.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#if DEBUG_MENU_ITEM
#include "states_screens/feature_unlocked.hpp"
#include "states_screens/grand_prix_lose.hpp"
@ -424,7 +424,10 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
if (PlayerManager::getCurrentOnlineId())
StateManager::get()->pushScreen(OnlineScreen::getInstance());
else
StateManager::get()->pushScreen(LoginScreen::getInstance());
{
BaseUserScreen *login = UserScreen::getInstance();
StateManager::get()->pushScreen(login);
}
}
else if (selection == "addons")
{

View File

@ -28,10 +28,10 @@
#include "guiengine/widget.hpp"
#include "io/file_manager.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/options_screen_ui.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "utils/translation.hpp"
#include <iostream>
@ -107,7 +107,7 @@ void OptionsScreenAudio::eventCallback(Widget* widget, const std::string& name,
if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance());
else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(OptionsScreenPlayers::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(TabbedUserScreen::getInstance());
else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance());
else if (selection == "tab_ui") StateManager::get()->replaceTopMostScreen(OptionsScreenUI::getInstance());
}

View File

@ -29,11 +29,11 @@
#include "io/file_manager.hpp"
#include "states_screens/options_screen_input2.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/options_screen_ui.hpp"
#include "states_screens/dialogs/add_device_dialog.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
@ -188,7 +188,7 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance());
else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(OptionsScreenPlayers::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(TabbedUserScreen::getInstance());
else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance());
else if (selection == "tab_ui") StateManager::get()->replaceTopMostScreen(OptionsScreenUI::getInstance());
}

View File

@ -32,10 +32,10 @@
#include "states_screens/dialogs/press_a_key_dialog.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/options_screen_ui.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "utils/translation.hpp"
#include <iostream>
@ -442,7 +442,7 @@ void OptionsScreenInput2::eventCallback(Widget* widget,
else if (selection == "tab_video")
sm->replaceTopMostScreen(OptionsScreenVideo::getInstance());
else if (selection == "tab_players")
sm->replaceTopMostScreen(OptionsScreenPlayers::getInstance());
sm->replaceTopMostScreen(UserScreen::getInstance());
else if (selection == "tab_ui")
sm->replaceTopMostScreen(OptionsScreenUI::getInstance());
else if (selection == "tab_controls") {}

View File

@ -1,228 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/options_screen_players.hpp"
#include "challenges/unlock_manager.hpp"
#include "config/device_config.hpp"
#include "config/player_manager.hpp"
#include "config/player_profile.hpp"
#include "config/user_config.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "states_screens/dialogs/enter_player_name_dialog.hpp"
#include "states_screens/dialogs/player_info_dialog.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/options_screen_ui.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/story_mode_lobby.hpp"
#include <IGUIButton.h>
#include <iostream>
#include <sstream>
using namespace GUIEngine;
using namespace irr::core;
using namespace irr::gui;
DEFINE_SCREEN_SINGLETON( OptionsScreenPlayers );
// -----------------------------------------------------------------------------
OptionsScreenPlayers::OptionsScreenPlayers() : Screen("options_players.stkgui")
{
} // OptionsScreenPlayers
// -----------------------------------------------------------------------------
void OptionsScreenPlayers::loadedFromFile()
{
} // loadedFromFile
// -----------------------------------------------------------------------------
void OptionsScreenPlayers::init()
{
Screen::init();
RibbonWidget* tabBar = this->getWidget<RibbonWidget>("options_choice");
if (tabBar != NULL) tabBar->select( "tab_players", PLAYER_ID_GAME_MASTER );
tabBar->getRibbonChildren()[0].setTooltip( _("Graphics") );
tabBar->getRibbonChildren()[1].setTooltip( _("Audio") );
tabBar->getRibbonChildren()[2].setTooltip( _("User Interface") );
tabBar->getRibbonChildren()[4].setTooltip( _("Controls") );
ListWidget* players = this->getWidget<ListWidget>("players");
assert(players != NULL);
refreshPlayerList();
ButtonWidget* you = getWidget<ButtonWidget>("playername");
unsigned int playerID = PlayerManager::getCurrentPlayer()->getUniqueID();
core::stringw player_name = L"-";
const PlayerProfile* curr = PlayerManager::get()->getPlayerById(playerID);
if(curr)
player_name = curr->getName();
you->setText( player_name );
((gui::IGUIButton*)you->getIrrlichtElement())->setOverrideFont( GUIEngine::getSmallFont() );
if (StateManager::get()->getGameState() == GUIEngine::INGAME_MENU)
{
players->setDeactivated();
you->setDeactivated();
}
else
{
players->setActivated();
you->setActivated();
}
} // init
// -----------------------------------------------------------------------------
bool OptionsScreenPlayers::renamePlayer(const stringw& newName, PlayerProfile* player)
{
player->setName( newName );
refreshPlayerList();
return true;
} // renamePlayer
// -----------------------------------------------------------------------------
void OptionsScreenPlayers::onNewPlayerWithName(const stringw& newName)
{
ListWidget* players = this->getWidget<ListWidget>("players");
if (players != NULL)
{
core::stringc newNameC(newName.c_str());
players->addItem( newNameC.c_str(), translations->fribidize(newName) );
}
}
// -----------------------------------------------------------------------------
void OptionsScreenPlayers::deletePlayer(PlayerProfile* player)
{
PlayerManager::get()->deletePlayer(player);
refreshPlayerList();
} // deletePlayer
// -----------------------------------------------------------------------------
void OptionsScreenPlayers::tearDown()
{
Screen::tearDown();
user_config->saveConfig();
} // tearDown
// -----------------------------------------------------------------------------
void OptionsScreenPlayers::eventCallback(Widget* widget, const std::string& name, const int playerID)
{
if (name == "options_choice")
{
std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str();
if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance());
else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(OptionsScreenPlayers::getInstance());
else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance());
else if (selection == "tab_ui") StateManager::get()->replaceTopMostScreen(OptionsScreenUI::getInstance());
}
else if (name == "back")
{
StateManager::get()->escapePressed();
}
else if (name == "addplayer")
{
new EnterPlayerNameDialog(this, 0.5f, 0.4f);
}
else if (name == "players")
{
// Find which player in the list was clicked
ListWidget* players = this->getWidget<ListWidget>("players");
assert(players != NULL);
core::stringw selectedPlayer = players->getSelectionLabel();
const int player_amount = PlayerManager::get()->getNumPlayers();
for (int i=0; i<player_amount; i++)
{
PlayerProfile *player = PlayerManager::get()->getPlayer(i);
if (selectedPlayer == translations->fribidize(player->getName()))
{
if (!(player->isGuestAccount()))
{
new PlayerInfoDialog( player, 0.5f, 0.6f );
}
return;
}
} // end for
}
else if (name == "playername")
{
race_manager->clearKartLastPositionOnOverworld();
PlayerManager::get()->setCurrentPlayer(NULL,false);
StateManager::get()->pushScreen(StoryModeLobbyScreen::getInstance());
}
} // eventCallback
// -----------------------------------------------------------------------------
void OptionsScreenPlayers::selectPlayer(const irr::core::stringw& name)
{
ListWidget* players = this->getWidget<ListWidget>("players");
assert(players != NULL);
players->selectItemWithLabel(name);
players->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
}
// ----------------------------------------------------------------------------
/** Refreshes the list of players.
*/
bool OptionsScreenPlayers::refreshPlayerList()
{
ListWidget* players = this->getWidget<ListWidget>("players");
if (players == NULL) return false;
// Get rid of previous
players->clear();
// Rebuild it
const int player_amount = PlayerManager::get()->getNumPlayers();
for (int i = 0; i < player_amount; i++)
{
// FIXME: Using a truncated ASCII string for internal ID. Let's cross
// our fingers and hope no one enters two player names that,
// when stripped down to ASCII, give the same identifier...
const PlayerProfile *player = PlayerManager::get()->getPlayer(i);
players->addItem(
core::stringc(player->getName().c_str()).c_str(),
translations->fribidize(player->getName()));
}
return true;
}

View File

@ -1,71 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __HEADER_OPTIONS_SCREEN_PLAYERS_HPP__
#define __HEADER_OPTIONS_SCREEN_PLAYERS_HPP__
#include <string>
#include <irrString.h>
#include "guiengine/screen.hpp"
#include "states_screens/dialogs/enter_player_name_dialog.hpp"
namespace GUIEngine { class Widget; }
struct Input;
class PlayerProfile;
/**
* \brief Player management options screen
* \ingroup states_screens
*/
class OptionsScreenPlayers : public GUIEngine::Screen, public EnterPlayerNameDialog::INewPlayerListener,
public GUIEngine::ScreenSingleton<OptionsScreenPlayers>
{
private:
OptionsScreenPlayers();
bool refreshPlayerList();
public:
friend class GUIEngine::ScreenSingleton<OptionsScreenPlayers>;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name,
const int playerID) OVERRIDE;
/**
* \brief Adds a new player (if 'player' is NULL) or renames an existing player (if 'player' is not NULL)
* \return whether adding was successful (can fail e.g. if trying to add a duplicate)
*/
bool renamePlayer(const irr::core::stringw& newName, PlayerProfile* player=NULL);
void deletePlayer(PlayerProfile* player);
void selectPlayer(const irr::core::stringw& name);
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void tearDown() OVERRIDE;
/** \brief implement callback from EnterPlayerNameDialog::INewPlayerListener */
virtual void onNewPlayerWithName(const irr::core::stringw& newName);
};
#endif

View File

@ -35,9 +35,9 @@
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "utils/log.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
@ -131,6 +131,10 @@ void OptionsScreenUI::init()
news->setState( UserConfigParams::m_internet_status
==RequestManager::IPERM_ALLOWED );
CheckBoxWidget* remember_me = getWidget<CheckBoxWidget>("remember-me");
assert( remember_me!= NULL );
remember_me->setState( UserConfigParams::m_remember_user);
// --- select the right skin in the spinner
bool currSkinFound = false;
const int skinCount = m_skins.size();
@ -206,7 +210,7 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance());
else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(OptionsScreenPlayers::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(TabbedUserScreen::getInstance());
else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance());
}
else if(name == "back")
@ -241,6 +245,12 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
if(internet->getState())
NewsManager::get()->init(false);
}
else if (name=="remember-me")
{
CheckBoxWidget* remember_me = getWidget<CheckBoxWidget>("remember-me");
assert( remember_me != NULL );
UserConfigParams::m_remember_user = remember_me->getState();
}
else if (name == "language")
{
ListWidget* list_widget = getWidget<ListWidget>("language");

View File

@ -32,9 +32,9 @@
#include "states_screens/dialogs/custom_video_settings.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/options_screen_ui.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
@ -464,7 +464,7 @@ void OptionsScreenVideo::eventCallback(Widget* widget, const std::string& name,
else if (selection == "tab_video")
screen = OptionsScreenVideo::getInstance();
else if (selection == "tab_players")
screen = OptionsScreenPlayers::getInstance();
screen = TabbedUserScreen::getInstance();
else if (selection == "tab_controls")
screen = OptionsScreenInput::getInstance();
else if (selection == "tab_ui")

View File

@ -17,7 +17,9 @@
#include "states_screens/register_screen.hpp"
#include "config/player_manager.hpp"
#include "audio/sfx_manager.hpp"
#include "guiengine/widgets/check_box_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
@ -25,15 +27,16 @@
#include "online/xml_request.hpp"
#include "states_screens/dialogs/registration_dialog.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/guest_login_screen.hpp"
#include "states_screens/login_screen.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "utils/log.hpp"
#include "utils/translation.hpp"
using namespace GUIEngine;
using namespace Online;
using namespace irr;
using namespace core;
DEFINE_SCREEN_SINGLETON( RegisterScreen );
@ -41,15 +44,32 @@ DEFINE_SCREEN_SINGLETON( RegisterScreen );
RegisterScreen::RegisterScreen() : Screen("online/register.stkgui")
{
m_existing_player = NULL;
} // RegisterScreen
// -----------------------------------------------------------------------------
void RegisterScreen::init()
{
Screen::init();
// Make sure this tab is actually focused.
RibbonWidget* tabs = this->getWidget<RibbonWidget>("login_tabs");
if (tabs) tabs->select( "tab_register", PLAYER_ID_GAME_MASTER );
// If there is no player (i.e. first start of STK), try to pick
// a good default name
stringw username = "";
if(m_existing_player)
{
username = m_existing_player->getName();
}
else if (PlayerManager::get()->getNumPlayers() == 0)
{
if (getenv("USERNAME") != NULL) // for windows
username = getenv("USERNAME");
else if (getenv("USER") != NULL) // Linux, Macs
username = getenv("USER");
else if (getenv("LOGNAME") != NULL) // Linux, Macs
username = getenv("LOGNAME");
}
getWidget<TextBoxWidget>("local_username")->setText(username);
TextBoxWidget *password_widget = getWidget<TextBoxWidget>("password");
password_widget->setPasswordBox(true,L'*');
@ -63,21 +83,110 @@ void RegisterScreen::init()
m_signup_request = NULL;
m_info_message_shown = false;
makeEntryFieldsVisible(true);
} // init
// -----------------------------------------------------------------------------
void RegisterScreen::setRename(PlayerProfile *player)
{
m_existing_player = player;
} // setRename
// -----------------------------------------------------------------------------
/** Shows or hides the entry fields for online registration, depending on
* online mode.
* \param online True if an online account should be created.
*/
void RegisterScreen::makeEntryFieldsVisible(bool online)
{
// In case of a rename, hide all other fields.
if(m_existing_player)
{
m_info_widget->setVisible(false);
getWidget<CheckBoxWidget>("online")->setVisible(false);
online = false;
}
getWidget<TextBoxWidget>("username")->setVisible(online);
getWidget<LabelWidget >("label_username")->setVisible(online);
getWidget<TextBoxWidget>("password")->setVisible(online);
getWidget<LabelWidget >("label_password")->setVisible(online);
getWidget<TextBoxWidget>("password_confirm")->setVisible(online);
getWidget<LabelWidget >("label_password_confirm")->setVisible(online);
getWidget<TextBoxWidget>("email")->setVisible(online);
getWidget<LabelWidget >("label_email")->setVisible(online);
getWidget<TextBoxWidget>("email_confirm")->setVisible(online);
getWidget<LabelWidget >("label_email_confirm")->setVisible(online);
} // makeEntryFieldsVisible
// -----------------------------------------------------------------------------
/** If necessary creates the local user.
* \param local_name Name of the local user.
*/
void RegisterScreen::handleLocalName(const stringw &local_name)
{
if (local_name.size()==0)
return;
// If a local player with that name does not exist, create one
if(!PlayerManager::get()->getPlayer(local_name))
{
PlayerProfile *player;
// If it's a rename, change the name of the player
if(m_existing_player && local_name.size()>0)
{
m_existing_player->setName(local_name);
player = m_existing_player;
}
else
{
player = PlayerManager::get()->addNewPlayer(local_name);
}
PlayerManager::get()->save();
if (player)
{
PlayerManager::get()->setCurrentPlayer(player);
}
else
{
m_info_widget->setErrorColor();
m_info_widget->setText(_("Could not create player '%s'.", local_name),
false);
}
}
else
{
m_info_widget->setErrorColor();
m_info_widget->setText(_("Could not create player '%s'.", local_name),
false);
}
} // handleLocalName
// -----------------------------------------------------------------------------
/** Handles the actual registration process. It does some tests on id, password
* and email address, then submits a corresponding request.
*/
void RegisterScreen::doRegister()
{
core::stringw username = getWidget<TextBoxWidget>("username")->getText().trim();
core::stringw password = getWidget<TextBoxWidget>("password")->getText().trim();
core::stringw password_confirm = getWidget<TextBoxWidget>("password_confirm")
->getText().trim();
core::stringw email = getWidget<TextBoxWidget>("email")->getText().trim();
core::stringw email_confirm = getWidget<TextBoxWidget>("email_confirm")
->getText().trim();
stringw local_name = getWidget<TextBoxWidget>("local_username")
->getText().trim();
handleLocalName(local_name);
// If no online account is requested, don't register
if(!getWidget<CheckBoxWidget>("online")->getState() || m_existing_player)
{
StateManager::get()->popMenu();
m_existing_player = NULL;
return;
}
stringw username = getWidget<TextBoxWidget>("username")->getText().trim();
stringw password = getWidget<TextBoxWidget>("password")->getText().trim();
stringw password_confirm = getWidget<TextBoxWidget>("password_confirm")
->getText().trim();
stringw email = getWidget<TextBoxWidget>("email")->getText().trim();
stringw email_confirm = getWidget<TextBoxWidget>("email_confirm")
->getText().trim();
m_info_widget->setErrorColor();
@ -89,7 +198,7 @@ void RegisterScreen::doRegister()
{
m_info_widget->setText(_("Emails don't match!"), false);
}
else if (username.size() < 4 || username.size() > 30)
else if (username.size() < 3 || username.size() > 30)
{
m_info_widget->setText(_("Username has to be between 4 and 30 characters long!"), false);
}
@ -115,7 +224,12 @@ void RegisterScreen::doRegister()
}
sfx_manager->quickSound( "anvil" );
if(local_name.size()>0)
{
PlayerProfile *player = PlayerManager::get()->getPlayer(local_name);
if (player)
player->setLastOnlineName(username);
}
} // doRegister
// -----------------------------------------------------------------------------
@ -186,15 +300,9 @@ void RegisterScreen::onUpdate(float dt)
void RegisterScreen::eventCallback(Widget* widget, const std::string& name,
const int playerID)
{
if (name == "login_tabs")
if (name == "online")
{
const std::string selection =
((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER);
StateManager *sm = StateManager::get();
if (selection == "tab_login")
sm->replaceTopMostScreen(LoginScreen::getInstance());
else if (selection == "tab_guest_login")
sm->replaceTopMostScreen(GuestLoginScreen::getInstance());
makeEntryFieldsVisible(getWidget<CheckBoxWidget>("online")->getState());
}
else if (name=="options")
{
@ -205,13 +313,34 @@ void RegisterScreen::eventCallback(Widget* widget, const std::string& name,
doRegister();
}
else if(button=="cancel")
StateManager::get()->escapePressed();
{
// We poop this menu, onEscapePress will handle the special case
// of e.g. a fresh start of stk that is aborted.
StateManager::get()->popMenu();
onEscapePressed();
}
}
else if (name == "back")
{
m_existing_player = NULL;
StateManager::get()->escapePressed();
}
} // eventCallback
// -----------------------------------------------------------------------------
bool RegisterScreen::onEscapePressed()
{
m_existing_player = NULL;
if (PlayerManager::get()->getNumPlayers() == 0)
{
// Must be first time start, and player cancelled player creation
// so quit stk. At this stage there are two menus on the stack:
// 1) The UserScreen, 2) RegisterStreen
// Popping them both will trigger STK to close.
StateManager::get()->popMenu();
return true;
}
return true;
} // onEscapePressed

View File

@ -23,6 +23,9 @@
namespace GUIEngine { class Widget; class LabelWidget;
class RibbonWidget; }
namespace Online { class XMLRequest; }
class PlayerProfile;
/**
* \brief Screen to register an online account.
* \ingroup states_screens
@ -33,6 +36,8 @@ class RegisterScreen : public GUIEngine::Screen,
private:
friend class GUIEngine::ScreenSingleton<RegisterScreen>;
void makeEntryFieldsVisible(bool online);
void handleLocalName(const irr::core::stringw &local_name);
void doRegister();
void init();
RegisterScreen();
@ -46,6 +51,10 @@ private:
/** The XML request to the server. */
Online::XMLRequest *m_signup_request;
/** Pointer to an existing player if the screen is doing a rename,
* NULL otherwise. */
PlayerProfile *m_existing_player;
/** True if the info message (email was sent...) is shown. */
bool m_info_message_shown;
@ -54,6 +63,8 @@ public:
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE {};
virtual void onUpdate(float dt) OVERRIDE;
virtual bool onEscapePressed() OVERRIDE;
void setRename(PlayerProfile *player);
void acceptTerms();
/** \brief implement callback from parent class GUIEngine::Screen */

View File

@ -1,157 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/story_mode_lobby.hpp"
#include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "guiengine/widgets/check_box_widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "states_screens/dialogs/enter_player_name_dialog.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/state_manager.hpp"
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( StoryModeLobbyScreen );
// ----------------------------------------------------------------------------
StoryModeLobbyScreen::StoryModeLobbyScreen() : Screen("story_mode_lobby.stkgui")
{
} // StoryModeLobbyScreen
// ----------------------------------------------------------------------------
void StoryModeLobbyScreen::loadedFromFile()
{
} // loadedFromFile
// ----------------------------------------------------------------------------
void StoryModeLobbyScreen::init()
{
Screen::init();
CheckBoxWidget* cb = getWidget<CheckBoxWidget>("rememberme");
cb->setState(false);
ListWidget* list = getWidget<ListWidget>("gameslots");
list->clear();
PlayerProfile *player = PlayerManager::getCurrentPlayer();
if(player)
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
return;
}
for (unsigned int n=0; n<PlayerManager::get()->getNumPlayers(); n++)
{
const PlayerProfile *player = PlayerManager::get()->getPlayer(n);
if (player->isGuestAccount()) continue;
// FIXME: we're using a trunacted ascii version of the player name as
// identifier, let's hope this causes no issues...
list->addItem(core::stringc(player->getName().c_str()).c_str(),
player->getName() );
}
list->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
list->setSelectionID(0);
} // init
// ----------------------------------------------------------------------------
void StoryModeLobbyScreen::tearDown()
{
Screen::tearDown();
} // tearDown
// ----------------------------------------------------------------------------
void StoryModeLobbyScreen::eventCallback(Widget* widget,
const std::string& name,
const int player_id)
{
if (name == "back")
{
StateManager::get()->escapePressed();
}
else if (name == "creategame")
{
new EnterPlayerNameDialog(this, 0.5f, 0.4f);
}
else if (name == "gameslots")
{
ListWidget* list = getWidget<ListWidget>("gameslots");
PlayerProfile *player = PlayerManager::get()
->getPlayer(list->getSelectionLabel());
if(player)
{
player->computeActive();
CheckBoxWidget* cb = getWidget<CheckBoxWidget>("rememberme");
PlayerManager::get()->setCurrentPlayer(player,cb->getState());
}
else
{
Log::error("StoryModeLobby",
"Cannot find player corresponding to slot '%s'.",
core::stringc(list->getSelectionLabel().c_str()).c_str());
}
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
// Since only now the current player is defined, we have to request
// a login (if an online login was saved). If the current player was
// saved, this request will be started much earlier in the startup
// sequence from the RequestManager.
PlayerManager::resumeSavedSession();
}
} // eventCallback
// ----------------------------------------------------------------------------
void StoryModeLobbyScreen::unloaded()
{
} // unloaded
// ----------------------------------------------------------------------------
void StoryModeLobbyScreen::onNewPlayerWithName(const stringw& new_name)
{
PlayerProfile *player = PlayerManager::get()->getPlayer(new_name);
if(player)
{
PlayerManager::get()->setCurrentPlayer(player,false);
player->computeActive();
}
else
{
Log::error("StoryModeLobbyScreen",
"Cannot find player corresponding to slot '%s'.",
core::stringc(new_name.c_str()).c_str());
}
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
} // onNewPlayerWithName
// -----------------------------------------------------------------------------

View File

@ -1,61 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __HEADER_STORY_MODE_LOBBY_HPP__
#define __HEADER_STORY_MODE_LOBBY_HPP__
#include <string>
#include "guiengine/screen.hpp"
#include "states_screens/dialogs/enter_player_name_dialog.hpp"
namespace GUIEngine { class Widget; }
/**
* \brief Audio options screen
* \ingroup states_screens
*/
class StoryModeLobbyScreen : public GUIEngine::Screen, public EnterPlayerNameDialog::INewPlayerListener,
public GUIEngine::ScreenSingleton<StoryModeLobbyScreen>
{
StoryModeLobbyScreen();
public:
friend class GUIEngine::ScreenSingleton<StoryModeLobbyScreen>;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID);
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void tearDown();
/** \brief implement optional callback from parent class GUIEngine::Screen */
virtual void unloaded();
/** \brief implement callback from EnterPlayerNameDialog::INewPlayerListener */
virtual void onNewPlayerWithName(const irr::core::stringw& newName);
};
#endif

View File

@ -0,0 +1,609 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/user_screen.hpp"
#include "audio/sfx_manager.hpp"
#include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "guiengine/widgets/check_box_widget.hpp"
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
#include "online/messages.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_ui.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/register_screen.hpp"
#include "states_screens/state_manager.hpp"
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( UserScreen );
DEFINE_SCREEN_SINGLETON( TabbedUserScreen );
// ----------------------------------------------------------------------------
BaseUserScreen::BaseUserScreen(const std::string &name) : Screen(name.c_str())
{
} // BaseUserScreen
// ----------------------------------------------------------------------------
void BaseUserScreen::loadedFromFile()
{
} // loadedFromFile
// ----------------------------------------------------------------------------
void BaseUserScreen::init()
{
m_online_cb = getWidget<CheckBoxWidget>("online");
assert(m_online_cb);
m_username_tb = getWidget<TextBoxWidget >("username");
assert(m_username_tb);
m_password_tb = getWidget<TextBoxWidget >("password");
assert(m_password_tb);
m_password_tb->setPasswordBox(true, L'*');
m_players = getWidget<DynamicRibbonWidget>("players");
assert(m_players);
m_options_widget = getWidget<RibbonWidget>("options");
assert(m_options_widget);
m_info_widget = getWidget<LabelWidget>("message");
assert(m_info_widget);
m_sign_out_name = "";
m_sign_in_name = "";
// It should always be activated ... but just in case
m_options_widget->setActivated();
// Clean any error message still shown
m_info_widget->setText("", true);
m_info_widget->setErrorColor();
Screen::init();
m_players->clearItems();
std::string current_player_index="";
for (unsigned int n=0; n<PlayerManager::get()->getNumPlayers(); n++)
{
const PlayerProfile *player = PlayerManager::get()->getPlayer(n);
if (player->isGuestAccount()) continue;
std::string s = StringUtils::toString(n);
m_players->addItem(player->getName(), s, player->getIconFilename(), 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
if(player==PlayerManager::getCurrentPlayer())
current_player_index = s;
}
m_players->updateItemDisplay();
// Select the current player. That can only be done after
// updateItemDisplay is called.
if(current_player_index.size()>0)
{
m_players->setSelection(current_player_index, PLAYER_ID_GAME_MASTER,
/*focus*/ true);
PlayerProfile *player = PlayerManager::getCurrentPlayer();
const stringw &online_name = player->getLastOnlineName();
m_username_tb->setText(online_name);
// Select 'online
m_online_cb->setState(player->wasOnlineLastTime() ||
player->isLoggedIn() );
makeEntryFieldsVisible();
}
else // no current player found
{
// The first player is the most frequently used, so select it
if (PlayerManager::get()->getNumPlayers() > 0)
selectUser(0);
}
} // init
// ----------------------------------------------------------------------------
PlayerProfile* BaseUserScreen::getSelectedPlayer()
{
const std::string &s_id = m_players
->getSelectionIDString(PLAYER_ID_GAME_MASTER);
unsigned int n_id;
StringUtils::fromString(s_id, n_id);
return PlayerManager::get()->getPlayer(n_id);
} // getSelectedPlayer
// ----------------------------------------------------------------------------
void BaseUserScreen::tearDown()
{
Screen::tearDown();
} // tearDown
// ----------------------------------------------------------------------------
/** Called when a user is selected. It updates the online checkbox and
* entrye fields.
*/
void BaseUserScreen::selectUser(int index)
{
PlayerProfile *profile = PlayerManager::get()->getPlayer(index);
assert(profile);
getWidget<TextBoxWidget >("username")->setText(profile
->getLastOnlineName());
m_players->setSelection(StringUtils::toString(index), 0, /*focusIt*/true);
// Last game was not online, so make the offline settings the default
// (i.e. unckeck online checkbox, and make entry fields invisible).
if (!profile->wasOnlineLastTime() || profile->getLastOnlineName() == "")
{
m_online_cb->setState(false);
makeEntryFieldsVisible();
return;
}
// Now last use was with online --> Display the saved data
m_online_cb->setState(true);
makeEntryFieldsVisible();
m_username_tb->setText(profile->getLastOnlineName());
// And make the password invisible if the session is saved (i.e
// the user does not need to enter a password).
if (profile->hasSavedSession())
{
m_password_tb->setVisible(false);
getWidget<LabelWidget>("label_password")->setVisible(false);
}
} // selectUser
// ----------------------------------------------------------------------------
/** Make the entry fields either visible or invisible.
* \param online Online state, which dicates if the entry fields are
* visible (true) or not.
*/
void BaseUserScreen::makeEntryFieldsVisible()
{
#ifdef GUEST_ACCOUNTS_ENABLED
getWidget<LabelWidget>("label_guest")->setVisible(online);
getWidget<CheckBoxWidget>("guest")->setVisible(online);
#endif
bool online = m_online_cb->getState();
getWidget<LabelWidget>("label_username")->setVisible(online);
m_username_tb->setVisible(online);
PlayerProfile *player = getSelectedPlayer();
if(player && player->hasSavedSession() && online)
{
// If we show the online login fields, but the player has a
// saved session, don't show the password field.
getWidget<LabelWidget>("label_password")->setVisible(false);
m_password_tb->setVisible(false);
}
else
{
getWidget<LabelWidget>("label_password")->setVisible(online);
m_password_tb->setVisible(online);
}
} // makeEntryFieldsVisible
// ----------------------------------------------------------------------------
/** Called when the user selects anything on the screen.
*/
void BaseUserScreen::eventCallback(Widget* widget,
const std::string& name,
const int player_id)
{
// Clean any error message still shown
m_info_widget->setText("", true);
m_info_widget->setErrorColor();
if (name == "players")
{
// Clicked on a name --> Find the corresponding online data
// and display them
const std::string &s_index = getWidget<DynamicRibbonWidget>("players")
->getSelectionIDString(player_id);
if (s_index == "") return; // can happen if the list is empty
unsigned int id;
if (StringUtils::fromString(s_index, id))
selectUser(id);
}
else if (name == "online")
{
// If online access is not allowed, do not accept an online account
// but advice the user where to enable this option.
if (m_online_cb->getState() && UserConfigParams::m_internet_status ==
Online::RequestManager::IPERM_NOT_ALLOWED)
{
m_info_widget->setText(
"Internet access is disabled, please enable it in the options",
true);
sfx_manager->quickSound( "anvil" );
m_online_cb->setState(false);
}
makeEntryFieldsVisible();
}
else if (name == "options")
{
const std::string &button =
m_options_widget->getSelectionIDString(player_id);
if (button == "ok")
{
login();
} // button==ok
else if (button == "new_user")
{
StateManager::get()->pushScreen(RegisterScreen::getInstance());
}
else if (button == "cancel")
{
StateManager::get()->popMenu();
onEscapePressed();
}
else if (button == "rename")
{
PlayerProfile *cp = getSelectedPlayer();
RegisterScreen::getInstance()->setRename(cp);
StateManager::get()->pushScreen(RegisterScreen::getInstance());
// Init will automatically be called, which
// refreshes the player list
}
else if (button == "delete")
{
deletePlayer();
}
} // options
return;
} // eventCallback
// ----------------------------------------------------------------------------
/** Closes the BaseUserScreen, and makes sure that the right screen is displayed
* next.
*/
void BaseUserScreen::closeScreen()
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
} // closeScreen
// ----------------------------------------------------------------------------
/** Called when OK or OK-and-save is clicked.
* This will trigger the actual login (if requested) etc.
* \param remember_me True if the login details should be remembered,
* so that next time this menu can be skipped.
*/
void BaseUserScreen::login()
{
// If an error occurs, the callback informing this screen about the
// problem will activate the widget again.
m_options_widget->setDeactivated();
m_state = STATE_NONE;
PlayerProfile *player = getSelectedPlayer();
PlayerProfile *current = PlayerManager::getCurrentPlayer();
core::stringw new_username = m_username_tb->getText();
// If a different player is connecting, or the same local player with
// a different online account, log out the current player.
if(current && current->isLoggedIn() &&
(player!=current || current->getLastOnlineName()!=new_username) )
{
m_sign_out_name = current->getLastOnlineName();
current->requestSignOut();
m_state = (UserScreenState)(m_state | STATE_LOGOUT);
// If the online user name was changed, reset the save data
// for this user (otherwise later the saved session will be
// resumed, not logging the user with the new account).
if(current->getLastOnlineName()!=new_username)
current->clearSession();
}
PlayerManager::get()->setCurrentPlayer(player);
assert(player);
// If no online login requested, log the player out (if necessary)
// and go to the main menu screen (though logout needs to finish first)
if(!m_online_cb->getState())
{
if(player->isLoggedIn())
{
m_sign_out_name =player->getLastOnlineName();
player->requestSignOut();
m_state =(UserScreenState)(m_state| STATE_LOGOUT);
}
player->setWasOnlineLastTime(false);
if(m_state==STATE_NONE)
{
closeScreen();
}
return;
}
// Player wants to be online, and is already online - nothing to do
if(player->isLoggedIn())
{
player->setWasOnlineLastTime(true);
closeScreen();
return;
}
m_state = (UserScreenState) (m_state | STATE_LOGIN);
// Now we need to start a login request to the server
// This implies that this screen will wait till the server responds, so
// that error messages ('invalid password') can be shown, and the user
// can decide what to do about them.
if (player->hasSavedSession())
{
m_sign_in_name = player->getLastOnlineName();
// Online login with saved token
player->requestSavedSession();
}
else
{
// Online login with password --> we need a valid password
if (m_password_tb->getText() == "")
{
m_info_widget->setText(_("You need to enter a password."), true);
sfx_manager->quickSound("anvil");
m_options_widget->setActivated();
return;
}
m_sign_in_name = m_username_tb->getText();
player->requestSignIn(m_username_tb->getText(),
m_password_tb->getText());
} // !hasSavedSession
} // login
// ----------------------------------------------------------------------------
/** Called once every frame. It will replace this screen with the main menu
* screen if a successful login happened.
*/
void BaseUserScreen::onUpdate(float dt)
{
if (!m_options_widget->isActivated())
{
core::stringw message = (m_state & STATE_LOGOUT)
? _(L"Signing out '%s'",m_sign_out_name.c_str())
: _(L"Signing in '%s'", m_sign_in_name.c_str());
m_info_widget->setText(Online::Messages::loadingDots(message.c_str()),
false );
}
PlayerProfile *player = getSelectedPlayer();
if(player)
{
// If the player changes the online name, clear the saved session
// flag, and make the password field visible again.
if (m_username_tb->getText()!=player->getLastOnlineName())
{
player->clearSession();
makeEntryFieldsVisible();
}
}
} // onUpdate
// ----------------------------------------------------------------------------
/** Callback from player profile if login was successful.
*/
void BaseUserScreen::loginSuccessful()
{
PlayerProfile *player = getSelectedPlayer();
player->setWasOnlineLastTime(true);
m_options_widget->setActivated();
// Clean any error message still shown
m_info_widget->setText("", true);
m_info_widget->setErrorColor();
// The callback is done from the main thread, so no need to sync
// access to m_success. OnUpdate will check this flag
closeScreen();
} // loginSuccessful
// ----------------------------------------------------------------------------
/** Callback from player profile if login was unsuccessful.
* \param error_message Contains the error message.
*/
void BaseUserScreen::loginError(const irr::core::stringw & error_message)
{
m_state = (UserScreenState) (m_state & ~STATE_LOGIN);
PlayerProfile *player = getSelectedPlayer();
// Clear information about saved session in case of a problem,
// which allows the player to enter a new password.
if(player && player->hasSavedSession())
player->clearSession();
makeEntryFieldsVisible();
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
m_info_widget->setText(error_message, false);
m_options_widget->setActivated();
} // loginError
// ----------------------------------------------------------------------------
/** Callback from player profile if logout was successful.
*/
void BaseUserScreen::logoutSuccessful()
{
m_state = (UserScreenState) (m_state & ~STATE_LOGOUT);
if(m_state==STATE_NONE)
closeScreen();
// Otherwise the screen still has to wait for a login request to finish.
} // loginSuccessful
// ----------------------------------------------------------------------------
/** Callback from player profile if login was unsuccessful.
* \param error_message Contains the error message.
*/
void BaseUserScreen::logoutError(const irr::core::stringw & error_message)
{
m_state = (UserScreenState) (m_state & ~STATE_LOGOUT);
PlayerProfile *player = getSelectedPlayer();
// Clear information about saved session in case of a problem,
// which allows the player to enter a new password.
if(player && player->hasSavedSession())
player->clearSession();
makeEntryFieldsVisible();
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
m_info_widget->setText(error_message, false);
m_options_widget->setActivated();
} // logoutError
// ----------------------------------------------------------------------------
/** Called when a player will be deleted.
*/
void BaseUserScreen::deletePlayer()
{
// Check that there is at least one player left: we need to have a
// valid current player, so the last player can not be deleted.
if(PlayerManager::get()->getNumNonGuestPlayers()==1)
{
m_info_widget->setText("You can't delete the only player.", true);
m_info_widget->setErrorColor();
return;
}
PlayerProfile *player = getSelectedPlayer();
irr::core::stringw message =
//I18N: In the player info dialog (when deleting)
_("Do you really want to delete player '%s' ?", player->getName());
class ConfirmServer : public MessageDialog::IConfirmDialogListener
{
BaseUserScreen *m_parent_screen;
public:
virtual void onConfirm()
{
m_parent_screen->doDeletePlayer();
} // onConfirm
// ------------------------------------------------------------
ConfirmServer(BaseUserScreen *parent)
{
m_parent_screen = parent;
}
}; // ConfirmServer
new MessageDialog(message, MessageDialog::MESSAGE_DIALOG_CONFIRM,
new ConfirmServer(this), true);
} // deletePlayer
// ----------------------------------------------------------------------------
/** Callback when the user confirms to delete a player. This function actually
* deletes the player, discards the dialog, and re-initialised the BaseUserScreen
* to display only the available players.
*/
void BaseUserScreen::doDeletePlayer()
{
PlayerProfile *player = getSelectedPlayer();
PlayerManager::get()->deletePlayer(player);
GUIEngine::ModalDialog::dismiss();
// Special case: the current player was deleted. We have to make sure
// that there is still a current player (all of STK depends on that).
if(!PlayerManager::getCurrentPlayer())
{
for(unsigned int i=0; i<PlayerManager::get()->getNumPlayers(); i++)
{
PlayerProfile *player = PlayerManager::get()->getPlayer(i);
if(!player->isGuestAccount())
{
PlayerManager::get()->setCurrentPlayer(player);
break;
}
}
}
init();
} // doDeletePlayer
// ----------------------------------------------------------------------------
void BaseUserScreen::unloaded()
{
} // unloaded
// ----------------------------------------------------------------------------
/** Gets called when a dialog closes. At a first time start of STK the
* internet dialog is shown first. Only when this dialog closes is it possible
* to open the next dialog, which is the one to create a new player (which
* is conventient on a first start).
*/
void BaseUserScreen::onDialogClose()
{
return;
// To allow players to exit the game without creating a player, we count
// how often this function was called. The first time is after the
// internet allowed dialog, the 2nd time
static int number_of_calls = 0;
number_of_calls++;
if(PlayerManager::get()->getNumPlayers() == 0)
{
// Still 0 players after the enter player dialog was shown
// --> User wanted to abort, so pop this menu, which will
// trigger the end of STK.
if (number_of_calls > 1)
{
StateManager::get()->popMenu();
return;
}
StateManager::get()->pushScreen(RegisterScreen::getInstance());
} // getNumPlayers == 0
} // onDialogClose
// ============================================================================
/** In the tab version, make sure the right tab is selected.
*/
void TabbedUserScreen::init()
{
RibbonWidget* tab_bar = this->getWidget<RibbonWidget>("options_choice");
if (tab_bar != NULL) tab_bar->select("tab_players", PLAYER_ID_GAME_MASTER);
tab_bar->getRibbonChildren()[0].setTooltip( _("Graphics") );
tab_bar->getRibbonChildren()[1].setTooltip( _("Audio") );
tab_bar->getRibbonChildren()[2].setTooltip(_("User Interface"));
tab_bar->getRibbonChildren()[4].setTooltip( _("Controls") );
BaseUserScreen::init();
} // init
// ----------------------------------------------------------------------------
/** Switch to the correct tab.
*/
void TabbedUserScreen::eventCallback(GUIEngine::Widget* widget,
const std::string& name,
const int player_id)
{
if (name == "options_choice")
{
const std::string &selection =
((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER);
Screen *s;
if (selection=="tab_audio" ) s = OptionsScreenAudio::getInstance();
else if (selection=="tab_video" ) s = OptionsScreenVideo::getInstance();
else if (selection=="tab_players" ) s = TabbedUserScreen::getInstance();
else if (selection=="tab_controls") s = OptionsScreenInput::getInstance();
else if (selection=="tab_ui" ) s = OptionsScreenUI::getInstance();
assert(s);
StateManager::get()->replaceTopMostScreen(s);
}
else
BaseUserScreen::eventCallback(widget, name, player_id);
} // eventCallback

View File

@ -0,0 +1,145 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __HEADER_USER_SCREEN_HPP__
#define __HEADER_USER_SCREEN_HPP__
#include <string>
#include "guiengine/screen.hpp"
namespace GUIEngine
{
class CheckBoxWidget;
class LabelWidget;
class RibbonWidget;
class TextBoxWidget;
class Widget;
}
class PlayerProfile;
/**
* \brief The user management screen. The screen cames in two variations:
* either as a stand-alone screen before the main menu (on first time STK
* is started, or it the user is not remembered), but also as tab in the
* options menu. To implement this, we use one common base class that
* implements nearly all functionality, and derive to classes - one for
* the stand alone version, one for the version with tabs.
* \ingroup states_screens.
*/
class BaseUserScreen : public GUIEngine::Screen
{
protected:
BaseUserScreen(const std::string &name);
private:
/** The state of the user screen. Note that this is a bit mask, since the
* current user can be logged out, and the new one logged in at the
* same time. */
enum UserScreenState { STATE_NONE=0, STATE_LOGIN=1, STATE_LOGOUT=2} m_state;
/** The user name that is currently being logged out. Used to
* display more meaningful sign-out message. */
irr::core::stringw m_sign_out_name;
/** The user name that is currently being logged out. Used to
* display more meaningful sign-out message. */
irr::core::stringw m_sign_in_name;
/** Online check box. */
GUIEngine::CheckBoxWidget *m_online_cb;
/** User name entry field. */
GUIEngine::TextBoxWidget *m_username_tb;
/** Password widget. */
GUIEngine::TextBoxWidget *m_password_tb;
/** Label field for warning and error messages. */
GUIEngine::LabelWidget * m_info_widget;
/** The ribbon with all buttons. */
GUIEngine::RibbonWidget *m_options_widget;
/** The dynamic ribbon containing all players. */
GUIEngine::DynamicRibbonWidget* m_players;
void selectUser(int index);
void makeEntryFieldsVisible();
void login();
void closeScreen();
void deletePlayer();
void doDeletePlayer();
PlayerProfile* getSelectedPlayer();
virtual void onDialogClose();
virtual void onUpdate(float dt) OVERRIDE;
public:
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget,
const std::string& name, const int playerID);
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void tearDown();
/** \brief implement optional callback from parent class GUIEngine::Screen */
virtual void unloaded();
void loginSuccessful();
void loginError(const irr::core::stringw &error_message);
void logoutSuccessful();
void logoutError(const irr::core::stringw &error_message);
}; // class BaseUserScreen
// ============================================================================
class UserScreen : public BaseUserScreen,
public GUIEngine::ScreenSingleton<UserScreen>
{
private:
UserScreen() : BaseUserScreen("user_screen.stkgui")
{};
public:
friend class GUIEngine::ScreenSingleton<UserScreen>;
}; // class UserScreenTabed
// ============================================================================
class TabbedUserScreen : public BaseUserScreen,
public GUIEngine::ScreenSingleton<TabbedUserScreen>
{
private:
TabbedUserScreen() : BaseUserScreen("user_screen_tab.stkgui")
{}
public:
friend class GUIEngine::ScreenSingleton<TabbedUserScreen>;
virtual void init();
virtual void eventCallback(GUIEngine::Widget* widget,
const std::string& name, const int playerID);
}; // class TabbedUserScreen
#endif

View File

@ -362,7 +362,7 @@ void Track::cleanup()
void Track::loadTrackInfo()
{
irr_driver->setLwhite(1.);
irr_driver->setExposure(0.09);
irr_driver->setExposure(0.09f);
// Default values
m_use_fog = false;
m_fog_max = 1.0f;

View File

@ -699,7 +699,7 @@ TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_no
m_energy = 1.0f;
xml_node.get("energy", &m_energy);
m_distance = 20. * m_energy;
m_distance = 20.f * m_energy;
xml_node.get("distance", &m_distance);
if (irr_driver->isGLSL())

View File

@ -15,7 +15,7 @@
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "debug.hpp"
#include "config/user_config.hpp"
#include "karts/controller/controller.hpp"
@ -36,13 +36,13 @@
#include <IGUIContextMenu.h>
using namespace irr;
using namespace gui;
namespace Debug {
/** This is to let mouse input events go through when the debug menu is visible, otherwise
GUI events would be blocked while in a race... */
static bool g_debug_menu_visible = false;
// -----------------------------------------------------------------------------
// Commands for the debug menu
enum DebugMenuCommand
@ -83,7 +83,7 @@ enum DebugMenuCommand
DEBUG_TWEAK_SHADER_EXPOSURE,
DEBUG_TWEAK_SHADER_LWHITE
};
// -----------------------------------------------------------------------------
// Add powerup selected from debug menu for all player karts
void addPowerup(PowerupManager::PowerupType powerup)
@ -96,7 +96,7 @@ void addPowerup(PowerupManager::PowerupType powerup)
kart->setPowerup(powerup, 10000);
}
}
void addAttachment(Attachment::AttachmentType type)
{
@ -136,7 +136,7 @@ bool onEvent(const SEvent &event)
// Only activated in artist debug mode
if(!UserConfigParams::m_artist_debug_mode)
return true; // keep handling the events
if(event.EventType == EET_MOUSE_INPUT_EVENT)
{
// Create the menu (only one menu at a time)
@ -147,10 +147,10 @@ bool onEvent(const SEvent &event)
IGUIContextMenu* mnu = guienv->addContextMenu(
core::rect<s32>(event.MouseInput.X, event.MouseInput.Y, event.MouseInput.Y+100, event.MouseInput.Y+100),NULL);
int graphicsMenuIndex = mnu->addItem(L"Graphics >",-1,true,true);
// graphics menu
IGUIContextMenu* sub = mnu->getSubMenu(graphicsMenuIndex);
sub->addItem(L"Reload shaders", DEBUG_GRAPHICS_RELOAD_SHADERS );
sub->addItem(L"Reset debug views", DEBUG_GRAPHICS_RESET );
sub->addItem(L"Wireframe", DEBUG_GRAPHICS_WIREFRAME );
@ -162,7 +162,7 @@ bool onEvent(const SEvent &event)
sub->addItem(L"Distort viz", DEBUG_GRAPHICS_DISTORT_VIZ );
sub->addItem(L"Physics debug", DEBUG_GRAPHICS_BULLET_1);
sub->addItem(L"Physics debug (no kart)", DEBUG_GRAPHICS_BULLET_2);
mnu->addItem(L"Items >",-1,true,true);
sub = mnu->getSubMenu(1);
sub->addItem(L"Basketball", DEBUG_POWERUP_RUBBERBALL );
@ -175,7 +175,7 @@ bool onEvent(const SEvent &event)
sub->addItem(L"Switch", DEBUG_POWERUP_SWITCH );
sub->addItem(L"Zipper", DEBUG_POWERUP_ZIPPER );
sub->addItem(L"Nitro", DEBUG_POWERUP_NITRO );
mnu->addItem(L"Attachments >",-1,true, true);
sub = mnu->getSubMenu(2);
sub->addItem(L"Bomb", DEBUG_ATTACHMENT_BOMB);
@ -183,8 +183,8 @@ bool onEvent(const SEvent &event)
sub->addItem(L"Parachute", DEBUG_ATTACHMENT_PARACHUTE);
//mnu->addItem(L"Adjust shaders >", -1, true, true);
//sub = mnu->getSubMenu(3);
//sub->addItem(L"Exposure", DEBUG_TWEAK_SHADER_EXPOSURE);
//sub = mnu->getSubMenu(3);
//sub->addItem(L"Exposure", DEBUG_TWEAK_SHADER_EXPOSURE);
//sub->addItem(L"LWhite", DEBUG_TWEAK_SHADER_LWHITE);
mnu->addItem(L"Profiler",DEBUG_PROFILER);
@ -196,29 +196,29 @@ bool onEvent(const SEvent &event)
mnu->addItem(L"Save history", DEBUG_SAVE_HISTORY);
mnu->addItem(L"Toggle GUI", DEBUG_TOGGLE_GUI);
mnu->addItem(L"Hide karts", DEBUG_HIDE_KARTS);
g_debug_menu_visible = true;
irr_driver->showPointer();
}
// Let Irrlicht handle the event while the menu is visible - otherwise in a race the GUI events won't be generated
if(g_debug_menu_visible)
return false;
}
if (event.EventType == EET_GUI_EVENT)
{
if (event.GUIEvent.Caller != NULL && event.GUIEvent.Caller->getType() == EGUIET_CONTEXT_MENU )
{
IGUIContextMenu *menu = (IGUIContextMenu*)event.GUIEvent.Caller;
s32 cmdID = menu->getItemCommandId(menu->getSelectedItem());
if(event.GUIEvent.EventType == EGET_ELEMENT_CLOSED)
{
g_debug_menu_visible = false;
}
if (event.GUIEvent.EventType == gui::EGET_MENU_ITEM_SELECTED)
{
if(cmdID == DEBUG_GRAPHICS_RELOAD_SHADERS)
@ -230,14 +230,14 @@ bool onEvent(const SEvent &event)
{
World* world = World::getWorld();
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
irr_driver->resetDebugModes();
}
else if (cmdID == DEBUG_GRAPHICS_WIREFRAME)
{
World* world = World::getWorld();
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
irr_driver->resetDebugModes();
irr_driver->toggleWireframe();
}
@ -245,7 +245,7 @@ bool onEvent(const SEvent &event)
{
World* world = World::getWorld();
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
irr_driver->resetDebugModes();
irr_driver->toggleMipVisualization();
}
@ -253,7 +253,7 @@ bool onEvent(const SEvent &event)
{
World* world = World::getWorld();
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
irr_driver->resetDebugModes();
irr_driver->toggleNormals();
}
@ -261,7 +261,7 @@ bool onEvent(const SEvent &event)
{
World* world = World::getWorld();
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
irr_driver->resetDebugModes();
irr_driver->toggleSSAOViz();
}
@ -269,7 +269,7 @@ bool onEvent(const SEvent &event)
{
World* world = World::getWorld();
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
irr_driver->resetDebugModes();
irr_driver->toggleShadowViz();
}
@ -277,7 +277,7 @@ bool onEvent(const SEvent &event)
{
World* world = World::getWorld();
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
irr_driver->resetDebugModes();
irr_driver->toggleLightViz();
}
@ -285,14 +285,14 @@ bool onEvent(const SEvent &event)
{
World* world = World::getWorld();
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
irr_driver->resetDebugModes();
irr_driver->toggleDistortViz();
}
else if (cmdID == DEBUG_GRAPHICS_BULLET_1)
{
irr_driver->resetDebugModes();
World* world = World::getWorld();
if (world == NULL) return false;
world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_KARTS_PHYSICS);
@ -300,7 +300,7 @@ bool onEvent(const SEvent &event)
else if (cmdID == DEBUG_GRAPHICS_BULLET_2)
{
irr_driver->resetDebugModes();
World* world = World::getWorld();
if (world == NULL) return false;
world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NO_KARTS_GRAPHICS);
@ -417,13 +417,13 @@ bool onEvent(const SEvent &event)
new DebugSliderDialog("lwhite", "LWhite");
}
}
return false; // event has been handled
}
}
return true; // continue event handling
}
bool isOpen()
{
return g_debug_menu_visible;

View File

@ -320,7 +320,7 @@ void Profiler::draw()
long hovered_gpu_marker_elapsed = 0;
if (hovered_markers.size() == 0)
{
int gpu_y = y_offset + nb_thread_infos*line_height + line_height/2;
int gpu_y = int(y_offset + nb_thread_infos*line_height + line_height/2);
float total = 0;
for (unsigned i = 0; i < Q_LAST; i++)
{
@ -341,7 +341,7 @@ void Profiler::draw()
{
//Log::info("GPU Perf", "Phase %d : %d us\n", i, irr_driver->getGPUTimer(i).elapsedTimeus());
float elapsed = irr_driver->getGPUTimer(i).elapsedTimeus();
float elapsed = float(irr_driver->getGPUTimer(i).elapsedTimeus());
core::rect<s32> pos((s32)(x_offset + (curr_val / total)*profiler_width),
(s32)(y_offset + gpu_y),
(s32)(x_offset + ((curr_val + elapsed) / total)*profiler_width),