Merge branch 'master' of https://github.com/supertuxkart/stk-code into ScriptEngine
This commit is contained in:
commit
3cb24f55d5
@ -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>
|
||||
|
@ -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>
|
@ -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>
|
||||
|
@ -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 ************ -->
|
||||
|
@ -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>
|
@ -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>
|
60
data/gui/user_screen.stkgui
Normal file
60
data/gui/user_screen.stkgui
Normal 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>
|
69
data/gui/user_screen_tab.stkgui
Normal file
69
data/gui/user_screen_tab.stkgui
Normal 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>
|
@ -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 |
@ -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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
91
src/main.cpp
91
src/main.cpp
@ -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();
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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 ();
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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
|
@ -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
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -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
|
@ -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
|
||||
|
||||
// -----------------------------------------------------------------------------
|
@ -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
|
@ -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
|
||||
|
||||
// -----------------------------------------------------------------------------
|
@ -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
|
@ -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")
|
||||
{
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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") {}
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
@ -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");
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -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
|
609
src/states_screens/user_screen.cpp
Normal file
609
src/states_screens/user_screen.cpp
Normal 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
|
145
src/states_screens/user_screen.hpp
Normal file
145
src/states_screens/user_screen.hpp
Normal 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
|
@ -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;
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user