Merge branch 'master' into NewRTTWidget
This commit is contained in:
commit
7e9252e5b3
data
gfx
gui
enter_player_name_dialog.stkgui
online
options_ui.stkguistory_mode_lobby.stkguistory_mode_new.stkguiuser_screen.stkguiuser_screen_tab.stkguimodels
shaders
gi.fraggrass_pass2.fragrh.fragrhdebug.fragrhdebug.vertrhpassthrough.geomrsm.fragrsm.vertslicedscreenquad.vert
skins
lib/irrlicht/source/Irrlicht
src
addons
config
graphics
glwrap.cppglwrap.hppgpuparticles.hppirr_driver.cppirr_driver.hppmaterial.cpppost_processing.cpppost_processing.hpprender.cpprtts.cpprtts.hppshaders.cppshaders.hppstkmesh.cppstkmesh.hppstkmeshscenenode.cpp
guiengine
input
io
karts
main.cpponline
messages.cppmessages.hpponline_player_profile.cpponline_player_profile.hpprequest_manager.cppserver.hpp
race
states_screens
dialogs
add_device_dialog.cppdebug_slider.cppenter_player_name_dialog.cppenter_player_name_dialog.hppplayer_info_dialog.cppplayer_info_dialog.hppselect_challenge.cpp
guest_login_screen.cppguest_login_screen.hpplogin_screen.cpplogin_screen.hppmain_menu_screen.cppoptions_screen_audio.cppoptions_screen_input.cppoptions_screen_input2.cppoptions_screen_players.cppoptions_screen_players.hppoptions_screen_ui.cppoptions_screen_video.cppregister_screen.cppregister_screen.hppstory_mode_lobby.cppstory_mode_lobby.hpptracks_screen.cppuser_screen.cppuser_screen.hpptracks
utils
35
data/gfx/gfx_fallingLeaf_a.xml
Normal file
35
data/gfx/gfx_fallingLeaf_a.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- For sky particles, the size of the box is ignored -->
|
||||
<particles emitter="box" box_x="10.0" box_y="0.5" box_z="10.0">
|
||||
|
||||
<spreading angle="3" />
|
||||
|
||||
<velocity x="-0.00"
|
||||
y="-0.002"
|
||||
z="-0.00" />
|
||||
|
||||
<material file="gfx_leaf_a.png" clampu="Y" clampv="Y" />
|
||||
|
||||
<!-- Amount of particles emitted per second -->
|
||||
<rate min="2"
|
||||
max="5" />
|
||||
|
||||
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
|
||||
<lifetime min="30000"
|
||||
max="30000" />
|
||||
|
||||
<!-- Size of the particles -->
|
||||
<size min="0.40"
|
||||
max="0.60" />
|
||||
|
||||
<color min="40 40 255"
|
||||
max="255 255 255" />
|
||||
|
||||
<!-- How much time in milliseconds before the particle is fully faded out -->
|
||||
<fadeout time="100" />
|
||||
|
||||
<wind speed="0.16"
|
||||
flips="Y" />
|
||||
|
||||
</particles>
|
@ -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="show-login"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Always show login screen"/>
|
||||
</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>
|
65
data/gui/user_screen.stkgui
Normal file
65
data/gui/user_screen.stkgui
Normal file
@ -0,0 +1,65 @@
|
||||
<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>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_remember" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Remember password"/>
|
||||
<checkbox id="remember-user" 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>
|
74
data/gui/user_screen_tab.stkgui
Normal file
74
data/gui/user_screen_tab.stkgui
Normal file
@ -0,0 +1,74 @@
|
||||
<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>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_remember" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Remember password"/>
|
||||
<checkbox id="remember-user" 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
|
||||
|
@ -2,34 +2,22 @@
|
||||
<materials>
|
||||
<material name="banana.png"/>
|
||||
<material name="gift-box.png"/>
|
||||
<material name="gift-loop.png" sphere="Y"/>
|
||||
<material name="gold.png" light="Y" smooth-reflection="Y"/>
|
||||
<material name="silver.png" light="Y" smooth-reflection="Y"/>
|
||||
<material name="bronze.png" light="Y" smooth-reflection="Y"/>
|
||||
<material name="gift-loop.png" shader="spheremap"/>
|
||||
<material name="gold.png" light="Y" shader="spheremap"/>
|
||||
<material name="silver.png" light="Y" shader="spheremap"/>
|
||||
<material name="bronze.png" light="Y" shader="spheremap"/>
|
||||
|
||||
<material name="stk_mod_nitroBarrel.png" />
|
||||
<material name="stk_mod_nitroBottle.png" />
|
||||
<material name="stk_mod_nitroLogo.png" compositing="additive" light="N" disable-z-write="Y" />
|
||||
<material name="stk_mod_nitroLogo.png" shader="additive" disable-z-write="Y" />
|
||||
|
||||
<material name="traffic_light_green.jpg" light="N"/>
|
||||
<material name="traffic_light_yellow.jpg" light="N"/>
|
||||
<material name="traffic_light_red.jpg" light="N"/>
|
||||
<material name="traffic_light_green.jpg" shader="unlit"/>
|
||||
<material name="traffic_light_yellow.jpg" shader="unlit"/>
|
||||
<material name="traffic_light_red.jpg" shader="unlit"/>
|
||||
|
||||
<material name="bubblegum_shield.png" compositing="blend" disable-z-write="Y"/>
|
||||
<material name="bubblegum_shield_nolok.png" compositing="blend" disable-z-write="Y"/>
|
||||
<material name="bubblegum_shield.png" shader="alphablend" disable-z-write="Y"/>
|
||||
<material name="bubblegum_shield_nolok.png" shader="alphablend" disable-z-write="Y"/>
|
||||
<material name="parachute.png" backface-culling="n" ignore="Y"/>
|
||||
<material name="zipper.png" light="N" zipper="Y"/>
|
||||
<material name="zipper_collect.png" light="N" zipper="Y"/>
|
||||
<material name="bowling-icon.png" transparency="Y" light="N"/>
|
||||
<material name="bubblegum-icon.png" transparency="Y" light="N"/>
|
||||
<material name="cake-icon.png" transparency="Y" light="N" />
|
||||
<material name="anchor-icon.png" clampU="Y" clampV="Y" transparency="Y" light="N" ignore="Y"/>
|
||||
<material name="plunger-icon.png" transparency="Y" light="N"/>
|
||||
<material name="parachute-icon.png" clampU="Y" clampV="Y" ignore="Y"/>
|
||||
<material name="anchor-attach-icon.png" clampU="Y" clampV="Y" transparency="Y" light="N" ignore="Y"/>
|
||||
<material name="parachute-attach-icon.png" clampU="Y" clampV="Y" ignore="Y"/>
|
||||
<material name="bomb-attach-icon.png" clampU="Y" clampV="Y" ignore="Y"/>
|
||||
|
||||
<material name="balldimpleddark.jpg"/>
|
||||
<material name="zipper.png" shader="unlit" zipper="Y"/>
|
||||
</materials>
|
||||
|
||||
|
Binary file not shown.
Before (image error) Size: 12 KiB After (image error) Size: 7.0 KiB |
101
data/shaders/gi.frag
Normal file
101
data/shaders/gi.frag
Normal file
@ -0,0 +1,101 @@
|
||||
// From http://graphics.cs.aueb.gr/graphics/research_illumination.html
|
||||
// "Real-Time Diffuse Global Illumination Using Radiance Hints"
|
||||
// paper and shader code
|
||||
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D dtex;
|
||||
|
||||
uniform sampler3D SHR;
|
||||
uniform sampler3D SHG;
|
||||
uniform sampler3D SHB;
|
||||
|
||||
uniform float R_wcs = 10.;
|
||||
uniform vec3 extents;
|
||||
uniform mat4 RHMatrix;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
vec4 SHBasis (const in vec3 dir)
|
||||
{
|
||||
float L00 = 0.282095;
|
||||
float L1_1 = 0.488603 * dir.y;
|
||||
float L10 = 0.488603 * dir.z;
|
||||
float L11 = 0.488603 * dir.x;
|
||||
return vec4 (L11, L1_1, L10, L00);
|
||||
}
|
||||
|
||||
vec3 SH2RGB (in vec4 sh_r, in vec4 sh_g, in vec4 sh_b, in vec3 dir)
|
||||
{
|
||||
vec4 Y = vec4(1.023326*dir.x, 1.023326*dir.y, 1.023326*dir.z, 0.886226);
|
||||
return vec3 (dot(Y,sh_r), dot(Y,sh_g), dot(Y,sh_b));
|
||||
}
|
||||
|
||||
in vec2 uv;
|
||||
layout (location = 0) out vec4 Diffuse;
|
||||
layout (location = 1) out vec4 Specular;
|
||||
|
||||
vec3 DecodeNormal(vec2 n);
|
||||
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
|
||||
|
||||
vec3 resolution = vec3(32, 16, 32);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 GI = vec3(0.);
|
||||
|
||||
float depth = texture2D(dtex, uv).x;
|
||||
// Discard background fragments
|
||||
if (depth==1.0) discard;
|
||||
|
||||
vec4 pos_screen_space = getPosFromUVDepth(vec3(uv, depth), InverseProjectionMatrix);
|
||||
vec4 tmp = (inverse(RHMatrix) * InverseViewMatrix * pos_screen_space);
|
||||
vec3 pos = tmp.xyz / tmp.w;
|
||||
vec3 normal_screen_space = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
|
||||
vec3 normal = (transpose(ViewMatrix) * vec4(normal_screen_space, 0.)).xyz;
|
||||
|
||||
// Convert to grid coordinates
|
||||
vec3 uvw = .5 + 0.5 * pos / extents;
|
||||
if (uvw.x < 0. || uvw.x > 1. || uvw.y < 0. || uvw.y > 1. || uvw.z < 0. || uvw.z > 1.) discard;
|
||||
|
||||
// Sample the RH volume at 4 locations, one directly above the shaded point,
|
||||
// three on a ring 80degs away from the normal direction.
|
||||
vec3 rnd = vec3(0,0,0);
|
||||
|
||||
// Generate the sample locations
|
||||
vec3 v_rand = vec3(0.5);
|
||||
vec3 tangent = normalize(cross(normal, v_rand));
|
||||
vec3 bitangent = cross(normal, tangent);
|
||||
vec3 D[4];
|
||||
D[0] = vec3(1.0,0.0,0.0);
|
||||
int i;
|
||||
for (i=1; i<4; i++)
|
||||
{
|
||||
D[i] = vec3(0.1, 0.8*cos((rnd.x*1.5+i)*6.2832/3.0), 0.8*sin((rnd.x*1.5+i)*6.2832/3.0));
|
||||
D[i] = normalize(D[i]);
|
||||
}
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
vec3 SampleDir = normal * D[i].x + tangent * D[i].y + bitangent *D[i].z;
|
||||
vec3 SampleOffset = (0.5 * normal + SampleDir) / resolution;
|
||||
vec3 uvw_new = uvw + SampleOffset;
|
||||
|
||||
vec4 IncidentSHR = texture(SHR, uvw_new);
|
||||
vec4 IncidentSHG = texture(SHG, uvw_new);
|
||||
vec4 IncidentSHB = texture(SHB, uvw_new);
|
||||
|
||||
GI += SH2RGB(IncidentSHR, IncidentSHG, IncidentSHB, -normal);
|
||||
}
|
||||
GI /= 4;
|
||||
|
||||
Diffuse = max(16. * vec4(GI, 1.), vec4(0.));
|
||||
Specular = vec4(0.);
|
||||
}
|
@ -29,6 +29,6 @@ void main(void)
|
||||
|
||||
vec4 color = texture(Albedo, uv);
|
||||
if (color.a < 0.5) discard;
|
||||
vec3 LightFactor = scattering + getLightFactor(1.);
|
||||
vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.);
|
||||
FragColor = vec4(color.xyz * LightFactor, 1.);
|
||||
}
|
||||
|
96
data/shaders/rh.frag
Normal file
96
data/shaders/rh.frag
Normal file
@ -0,0 +1,96 @@
|
||||
// From http://graphics.cs.aueb.gr/graphics/research_illumination.html
|
||||
// "Real-Time Diffuse Global Illumination Using Radiance Hints"
|
||||
// paper and shader code
|
||||
|
||||
uniform float R_wcs = 10.; // Rmax: maximum sampling distance (in WCS units)
|
||||
uniform vec3 extents;
|
||||
uniform mat4 RHMatrix;
|
||||
uniform mat4 RSMMatrix;
|
||||
uniform sampler2D dtex;
|
||||
uniform sampler2D ctex;
|
||||
uniform sampler2D ntex;
|
||||
|
||||
flat in int slice;
|
||||
layout (location = 0) out vec4 SHRed;
|
||||
layout (location = 1) out vec4 SHGreen;
|
||||
layout (location = 2) out vec4 SHBlue;
|
||||
|
||||
vec3 resolution = vec3(32, 16, 32);
|
||||
#define SAMPLES 16
|
||||
|
||||
vec4 SHBasis (const in vec3 dir)
|
||||
{
|
||||
float L00 = 0.282095;
|
||||
float L1_1 = 0.488603 * dir.y;
|
||||
float L10 = 0.488603 * dir.z;
|
||||
float L11 = 0.488603 * dir.x;
|
||||
return vec4 (L11, L1_1, L10, L00);
|
||||
}
|
||||
|
||||
vec4 DirToSh(vec3 dir, float flux)
|
||||
{
|
||||
return SHBasis (dir) * flux;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
||||
vec3 normalizedRHCenter = 2. * vec3(gl_FragCoord.xy, slice) / resolution - 1.;
|
||||
vec3 RHcenter = (RHMatrix * vec4(normalizedRHCenter * extents, 1.)).xyz;
|
||||
|
||||
vec4 ShadowProjectedRH = RSMMatrix * vec4(RHcenter, 1.);
|
||||
|
||||
vec3 RHCellSize = extents / resolution;
|
||||
vec2 RHuv = .5 * ShadowProjectedRH.xy / ShadowProjectedRH.w + .5;
|
||||
float RHdepth = .5 * ShadowProjectedRH.z / ShadowProjectedRH.w + .5;
|
||||
|
||||
vec4 SHr = vec4(0.);
|
||||
vec4 SHg = vec4(0.);
|
||||
vec4 SHb = vec4(0.);
|
||||
|
||||
int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y);
|
||||
float phi = 30. * (x ^ y) + 10. * x * y;
|
||||
|
||||
for (int i = 0; i < SAMPLES; i++)
|
||||
{
|
||||
// produce a new sample location on the RSM texture
|
||||
float alpha = (i + .5) / SAMPLES;
|
||||
float theta = 2. * 3.14 * 7. * alpha;
|
||||
float h = alpha;
|
||||
vec2 offset = h * vec2(cos(theta), sin(theta));
|
||||
vec2 uv = RHuv + offset * 0.01;
|
||||
|
||||
// Get world position and normal from the RSM sample
|
||||
float depth = texture2D(dtex, uv).z;
|
||||
vec4 RSMPos = inverse(RSMMatrix) * (2. * vec4(uv, depth, 1.) - 1.);
|
||||
RSMPos /= RSMPos.w;
|
||||
vec3 RSMAlbedo = texture(ctex, uv).xyz;
|
||||
vec3 normal = normalize(2. * texture(ntex, uv).xyz - 1.);
|
||||
|
||||
// Sampled location inside the RH cell
|
||||
vec3 offset3d = vec3(uv, 0);
|
||||
vec3 SamplePos = RHcenter + .5 * offset3d.xzy * RHCellSize;
|
||||
|
||||
// Normalize distance to RSM sample
|
||||
float dist = distance(SamplePos, RSMPos.xyz) / R_wcs;
|
||||
// Determine the incident direction.
|
||||
// Avoid very close samples (and numerical instability problems)
|
||||
vec3 RSM_to_RH_dir = (dist <= 0.00) ? vec3(0.) : normalize(SamplePos - RSMPos.xyz);
|
||||
float dotprod = max(dot(RSM_to_RH_dir, normal.xyz), 0.);
|
||||
float factor = dotprod / (0.1 + dist * dist);
|
||||
|
||||
vec3 color = RSMAlbedo.rgb * factor;
|
||||
|
||||
SHr += DirToSh(RSM_to_RH_dir, color.r);
|
||||
SHg += DirToSh(RSM_to_RH_dir, color.g);
|
||||
SHb += DirToSh(RSM_to_RH_dir, color.b);
|
||||
}
|
||||
|
||||
SHr /= 3.14159 * SAMPLES;
|
||||
SHg /= 3.14159 * SAMPLES;
|
||||
SHb /= 3.14159 * SAMPLES;
|
||||
|
||||
SHRed = SHr;
|
||||
SHGreen = SHg;
|
||||
SHBlue = SHb;
|
||||
}
|
14
data/shaders/rhdebug.frag
Normal file
14
data/shaders/rhdebug.frag
Normal file
@ -0,0 +1,14 @@
|
||||
uniform sampler3D SHR;
|
||||
uniform sampler3D SHG;
|
||||
uniform sampler3D SHB;
|
||||
|
||||
in vec3 uvw;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float r = texture(SHR, uvw).w;
|
||||
float g = texture(SHG, uvw).w;
|
||||
float b = texture(SHB, uvw).w;
|
||||
FragColor = max(vec4(r, g, b, 1.0), vec4(0.));
|
||||
}
|
30
data/shaders/rhdebug.vert
Normal file
30
data/shaders/rhdebug.vert
Normal file
@ -0,0 +1,30 @@
|
||||
uniform vec3 extents;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
uniform mat4 RHMatrix;
|
||||
|
||||
ivec3 resolution = ivec3(32, 16, 32);
|
||||
|
||||
out vec3 uvw;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// Determine the RH center
|
||||
float gx = int(gl_VertexID) & (resolution.x - 1);
|
||||
float gy = int(gl_VertexID >> 5) & (resolution.y - 1);
|
||||
float gz = int(gl_VertexID >> 9) & (resolution.z - 1);
|
||||
uvw = vec3(gx, gy, gz) / vec3(resolution);
|
||||
vec3 WorldPos = (2. * uvw - 1.) * extents;
|
||||
gl_Position = ProjectionMatrix * ViewMatrix * RHMatrix * vec4(WorldPos, 1.);
|
||||
gl_PointSize = 100. / gl_Position.w;
|
||||
|
||||
}
|
20
data/shaders/rhpassthrough.geom
Normal file
20
data/shaders/rhpassthrough.geom
Normal file
@ -0,0 +1,20 @@
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices=3) out;
|
||||
|
||||
in int layer[3];
|
||||
in vec2 uv_in[3];
|
||||
flat out int slice;
|
||||
out vec2 uv;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Layer = layer[0];
|
||||
for(int i=0; i<3; i++)
|
||||
{
|
||||
slice = layer[0];
|
||||
uv = uv_in[i];
|
||||
gl_Position = gl_in[i].gl_Position;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
12
data/shaders/rsm.frag
Normal file
12
data/shaders/rsm.frag
Normal file
@ -0,0 +1,12 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 uv;
|
||||
in vec3 nor;
|
||||
layout (location = 0) out vec3 RSMColor;
|
||||
layout (location = 1) out vec3 RSMNormals;
|
||||
|
||||
void main()
|
||||
{
|
||||
RSMColor = texture(tex, uv).xyz;
|
||||
RSMNormals = .5 * normalize(nor) + .5;
|
||||
}
|
26
data/shaders/rsm.vert
Normal file
26
data/shaders/rsm.vert
Normal file
@ -0,0 +1,26 @@
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform mat4 InverseModelMatrix;
|
||||
uniform mat4 RSMMatrix;
|
||||
|
||||
uniform mat4 TextureMatrix =
|
||||
mat4(1., 0., 0., 0.,
|
||||
0., 1., 0., 0.,
|
||||
0., 0., 1., 0.,
|
||||
0., 0., 0., 1.);
|
||||
|
||||
|
||||
in vec3 Position;
|
||||
in vec2 Texcoord;
|
||||
in vec3 Normal;
|
||||
out vec3 nor;
|
||||
out vec2 uv;
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
mat4 ModelViewProjectionMatrix = RSMMatrix * ModelMatrix;
|
||||
mat4 TransposeInverseModel = transpose(InverseModelMatrix);
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
|
||||
nor = (vec4(Normal, 0.)).xyz;
|
||||
uv = (TextureMatrix * vec4(Texcoord, 1., 1.)).xy;
|
||||
}
|
24
data/shaders/slicedscreenquad.vert
Normal file
24
data/shaders/slicedscreenquad.vert
Normal file
@ -0,0 +1,24 @@
|
||||
in vec2 Position;
|
||||
in vec2 Texcoord;
|
||||
|
||||
#ifndef VSLayer
|
||||
out int layer;
|
||||
out vec2 uv_in;
|
||||
#else
|
||||
out vec2 uv;
|
||||
flat out int slice;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void main() {
|
||||
#ifdef VSLayer
|
||||
gl_Layer = gl_InstanceID;
|
||||
uv = Texcoord;
|
||||
slice = gl_InstanceID;
|
||||
#else
|
||||
layer = gl_InstanceID;
|
||||
uv_in = Texcoord;
|
||||
#endif
|
||||
gl_Position = vec4(Position, 0., 1.);
|
||||
}
|
@ -25,6 +25,8 @@ Note that checkboxes are an exception and have the following styles :
|
||||
"neutral+checked"
|
||||
"focused+unchecked"
|
||||
"focused+checked"
|
||||
"deactivated+unchecked"
|
||||
"deactivated+checked"
|
||||
|
||||
"Advanced stretching" images are split this way :
|
||||
|
||||
@ -66,11 +68,15 @@ when the border that intersect at this corner are enabled.
|
||||
<!-- Stateless -->
|
||||
<element type="background" image="ocean/background.jpg" />
|
||||
|
||||
<element type="button" state="neutral" image="ocean/glassbutton.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
<element type="button" state="focused" image="ocean/glassbutton_focused.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
<element type="button" state="neutral" image="ocean/glassbutton.png"
|
||||
<element type="button" state="deactivated" image="ocean/glassbutton_deactivated.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
@ -131,6 +137,10 @@ when the border that intersect at this corner are enabled.
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner" state="deactivated" image="ocean/glassspinner_deactivated.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<!-- player name spinner color in multiplayer-->
|
||||
<element type="spinner1" state="neutral" image="ocean/glass_square1.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
@ -157,6 +167,8 @@ when the border that intersect at this corner are enabled.
|
||||
<element type="checkbox" state="neutral+checked" image="ocean/glasscheckbox_checked.png"/>
|
||||
<element type="checkbox" state="focused+unchecked" image="ocean/glasscheckbox_focus.png"/>
|
||||
<element type="checkbox" state="focused+checked" image="ocean/glasscheckbox_checked_focus.png"/>
|
||||
<element type="checkbox" state="deactivated+unchecked" image="ocean/glasscheckbox_deactivated.png"/>
|
||||
<element type="checkbox" state="deactivated+checked" image="ocean/glasscheckbox_checked_deactivated.png"/>
|
||||
|
||||
<!-- are always in neutral state for now. No splitting into 9 areas is done; the image is just stretched.
|
||||
Note: the body of a guage is the same as for for spinners. -->
|
||||
|
@ -25,6 +25,8 @@ Note that checkboxes are an exception and have the following styles :
|
||||
"neutral+checked"
|
||||
"focused+unchecked"
|
||||
"focused+checked"
|
||||
"deactivated+unchecked"
|
||||
"deactivated+checked"
|
||||
|
||||
"Advanced stretching" images are split this way :
|
||||
|
||||
@ -66,11 +68,15 @@ when the border that intersect at this corner are enabled.
|
||||
<!-- Stateless -->
|
||||
<element type="background" image="peach/background.jpg" />
|
||||
|
||||
<element type="button" state="neutral" image="peach/glassbutton.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
<element type="button" state="focused" image="peach/glassbutton_focused.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
<element type="button" state="neutral" image="peach/glassbutton.png"
|
||||
<element type="button" state="deactivated" image="peach/glassbutton_deactivated.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
@ -132,6 +138,10 @@ when the border that intersect at this corner are enabled.
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner" state="deactivated" image="peach/glassspinner_deactivated.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner1" state="neutral" image="peach/glass_square1.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
@ -156,6 +166,8 @@ when the border that intersect at this corner are enabled.
|
||||
<element type="checkbox" state="neutral+checked" image="peach/glasscheckbox_checked.png"/>
|
||||
<element type="checkbox" state="focused+unchecked" image="peach/glasscheckbox_focus.png"/>
|
||||
<element type="checkbox" state="focused+checked" image="peach/glasscheckbox_checked_focus.png"/>
|
||||
<element type="checkbox" state="deactivated+unchecked" image="peach/glasscheckbox_deactivated.png"/>
|
||||
<element type="checkbox" state="deactivated+checked" image="peach/glasscheckbox_checked_deactivated.png"/>
|
||||
|
||||
<!-- are always in neutral state for now. No splitting into 9 areas is done; the image is just stretched.
|
||||
Note: the body of a guage is the same as for for spinners. -->
|
||||
|
BIN
data/skins/ocean/glassbutton_deactivated.png
Normal file
BIN
data/skins/ocean/glassbutton_deactivated.png
Normal file
Binary file not shown.
After (image error) Size: 7.4 KiB |
BIN
data/skins/ocean/glasscheckbox_checked_deactivated.png
Normal file
BIN
data/skins/ocean/glasscheckbox_checked_deactivated.png
Normal file
Binary file not shown.
After (image error) Size: 2.3 KiB |
BIN
data/skins/ocean/glasscheckbox_deactivated.png
Normal file
BIN
data/skins/ocean/glasscheckbox_deactivated.png
Normal file
Binary file not shown.
After (image error) Size: 2.0 KiB |
BIN
data/skins/ocean/glassspinner_deactivated.png
Normal file
BIN
data/skins/ocean/glassspinner_deactivated.png
Normal file
Binary file not shown.
After (image error) Size: 9.6 KiB |
BIN
data/skins/peach/glassbutton_deactivated.png
Normal file
BIN
data/skins/peach/glassbutton_deactivated.png
Normal file
Binary file not shown.
After (image error) Size: 7.4 KiB |
BIN
data/skins/peach/glasscheckbox_checked_deactivated.png
Normal file
BIN
data/skins/peach/glasscheckbox_checked_deactivated.png
Normal file
Binary file not shown.
After (image error) Size: 2.3 KiB |
BIN
data/skins/peach/glasscheckbox_deactivated.png
Normal file
BIN
data/skins/peach/glasscheckbox_deactivated.png
Normal file
Binary file not shown.
After (image error) Size: 2.0 KiB |
BIN
data/skins/peach/glassspinner_deactivated.png
Normal file
BIN
data/skins/peach/glassspinner_deactivated.png
Normal file
Binary file not shown.
After (image error) Size: 9.6 KiB |
@ -273,7 +273,7 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
|
||||
{
|
||||
if (bestMode==-1 && modes[i]->hdisplay >= Width && modes[i]->vdisplay >= Height)
|
||||
{
|
||||
float pixels_per_second = modes[i]->dotclock * 1000.0;
|
||||
float pixels_per_second = modes[i]->dotclock * 1000.0;
|
||||
float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal;
|
||||
refresh_rate = pixels_per_second / pixels_per_frame;
|
||||
bestMode = i;
|
||||
@ -282,15 +282,15 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
|
||||
modes[i]->hdisplay == modes[bestMode]->hdisplay &&
|
||||
modes[i]->vdisplay == modes[bestMode]->vdisplay)
|
||||
{
|
||||
float pixels_per_second = modes[i]->dotclock * 1000.0;
|
||||
float pixels_per_second = modes[i]->dotclock * 1000.0;
|
||||
float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal;
|
||||
float refresh_rate_tmp = pixels_per_second / pixels_per_frame;
|
||||
|
||||
|
||||
if (refresh_rate_tmp > refresh_rate)
|
||||
{
|
||||
refresh_rate = refresh_rate_tmp;
|
||||
bestMode = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bestMode!=-1 &&
|
||||
modes[i]->hdisplay >= Width &&
|
||||
@ -298,7 +298,7 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
|
||||
modes[i]->hdisplay <= modes[bestMode]->hdisplay &&
|
||||
modes[i]->vdisplay <= modes[bestMode]->vdisplay)
|
||||
{
|
||||
float pixels_per_second = modes[i]->dotclock * 1000.0;
|
||||
float pixels_per_second = modes[i]->dotclock * 1000.0;
|
||||
float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal;
|
||||
refresh_rate = pixels_per_second / pixels_per_frame;
|
||||
bestMode = i;
|
||||
@ -746,8 +746,21 @@ bool CIrrDeviceLinux::createWindow()
|
||||
|
||||
if (!CreationParams.WindowId)
|
||||
{
|
||||
Atom *list;
|
||||
Atom type;
|
||||
int form;
|
||||
unsigned long remain, len;
|
||||
|
||||
Atom WMCheck = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", false);
|
||||
Status s = XGetWindowProperty(display, DefaultRootWindow(display),
|
||||
WMCheck, 0L, 1L, False, XA_WINDOW,
|
||||
&type, &form, &len, &remain,
|
||||
(unsigned char **)&list);
|
||||
|
||||
bool netWM = (s == Success) && len;
|
||||
attributes.override_redirect = !netWM && CreationParams.Fullscreen;
|
||||
|
||||
// create new Window
|
||||
attributes.override_redirect = false;
|
||||
window = XCreateWindow(display,
|
||||
RootWindow(display, visual->screen),
|
||||
0, 0, Width, Height, 0, visual->depth,
|
||||
@ -762,31 +775,45 @@ bool CIrrDeviceLinux::createWindow()
|
||||
|
||||
if (CreationParams.Fullscreen)
|
||||
{
|
||||
// Workaround for Gnome which sometimes creates window smaller than display
|
||||
XSizeHints *hints = XAllocSizeHints();
|
||||
hints->flags=PMinSize;
|
||||
hints->min_width=Width;
|
||||
hints->min_height=Height;
|
||||
XSetWMNormalHints(display, window, hints);
|
||||
XFree(hints);
|
||||
if (netWM)
|
||||
{
|
||||
// Workaround for Gnome which sometimes creates window smaller than display
|
||||
XSizeHints *hints = XAllocSizeHints();
|
||||
hints->flags=PMinSize;
|
||||
hints->min_width=Width;
|
||||
hints->min_height=Height;
|
||||
XSetWMNormalHints(display, window, hints);
|
||||
XFree(hints);
|
||||
|
||||
// Set the fullscreen mode via the window manager. This allows alt-tabing, volume hot keys & others.
|
||||
// Get the needed atom from there freedesktop names
|
||||
Atom WMStateAtom = XInternAtom(display, "_NET_WM_STATE", true);
|
||||
Atom WMFullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true);
|
||||
// Set the fullscreen property
|
||||
XChangeProperty(display, window, WMStateAtom, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(& WMFullscreenAtom), 1);
|
||||
|
||||
// Notify the root window
|
||||
XEvent xev = {0}; // The event should be filled with zeros before setting its attributes
|
||||
|
||||
xev.type = ClientMessage;
|
||||
xev.xclient.window = window;
|
||||
xev.xclient.message_type = WMStateAtom;
|
||||
xev.xclient.format = 32;
|
||||
xev.xclient.data.l[0] = 1;
|
||||
xev.xclient.data.l[1] = WMFullscreenAtom;
|
||||
XSendEvent(display, DefaultRootWindow(display), false, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
|
||||
// Set the fullscreen mode via the window manager. This allows alt-tabing, volume hot keys & others.
|
||||
// Get the needed atom from there freedesktop names
|
||||
Atom WMStateAtom = XInternAtom(display, "_NET_WM_STATE", true);
|
||||
Atom WMFullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true);
|
||||
// Set the fullscreen property
|
||||
XChangeProperty(display, window, WMStateAtom, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(& WMFullscreenAtom), 1);
|
||||
|
||||
// Notify the root window
|
||||
XEvent xev = {0}; // The event should be filled with zeros before setting its attributes
|
||||
|
||||
xev.type = ClientMessage;
|
||||
xev.xclient.window = window;
|
||||
xev.xclient.message_type = WMStateAtom;
|
||||
xev.xclient.format = 32;
|
||||
xev.xclient.data.l[0] = 1;
|
||||
xev.xclient.data.l[1] = WMFullscreenAtom;
|
||||
XSendEvent(display, DefaultRootWindow(display), false, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
|
||||
}
|
||||
else
|
||||
{
|
||||
XSetInputFocus(display, window, RevertToParent, CurrentTime);
|
||||
int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync,
|
||||
GrabModeAsync, CurrentTime);
|
||||
IrrPrintXGrabError(grabKb, "XGrabKeyboard");
|
||||
int grabPointer = XGrabPointer(display, window, True, ButtonPressMask,
|
||||
GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
|
||||
IrrPrintXGrabError(grabPointer, "XGrabPointer");
|
||||
XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -297,33 +297,6 @@ public:
|
||||
return true;
|
||||
} // operator<
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Compares two addons according to the sort order currently defined.
|
||||
* Comparison is done for sorting in descending order.
|
||||
* \param a The addon to compare this addon to.
|
||||
*/
|
||||
bool operator>(const Addon &a) const
|
||||
{
|
||||
switch(m_sort_order)
|
||||
{
|
||||
case SO_DEFAULT:
|
||||
if(testStatus(AS_FEATURED) &&
|
||||
!a.testStatus(AS_FEATURED)) return true;
|
||||
if(!testStatus(AS_FEATURED) &&
|
||||
a.testStatus(AS_FEATURED)) return false;
|
||||
// Otherwise fall through to name comparison!
|
||||
case SO_NAME:
|
||||
// m_id is the lower case name
|
||||
return m_id > a.m_id;
|
||||
break;
|
||||
case SO_DATE:
|
||||
return m_date < a.m_date;
|
||||
break;
|
||||
} // switch
|
||||
// Fix compiler warning.
|
||||
return true;
|
||||
} // operator>
|
||||
|
||||
}; // Addon
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -173,7 +166,18 @@ PlayerManager::PlayerManager()
|
||||
*/
|
||||
PlayerManager::~PlayerManager()
|
||||
{
|
||||
// If the passwords should not be remembered, clear all saved sessions.
|
||||
if(!UserConfigParams::m_remember_user)
|
||||
{
|
||||
PlayerProfile *player;
|
||||
for_in(player, m_all_players)
|
||||
{
|
||||
player->clearSession();
|
||||
}
|
||||
|
||||
}
|
||||
save();
|
||||
|
||||
} // ~PlayerManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -197,14 +201,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 +229,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 +243,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 +266,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 +293,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 +306,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 +342,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 +377,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 +440,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,63 @@ void PlayerProfile::initRemainingData()
|
||||
m_story_mode_status = unlock_manager->createStoryModeStatus();
|
||||
m_achievements_status =
|
||||
AchievementsManager::get()->createAchievementsStatus();
|
||||
|
||||
addIcon();
|
||||
} // initRemainingData
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** Creates an icon for a player if non exist so far. 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()
|
||||
{
|
||||
if (m_icon_filename.size() > 0)
|
||||
return;
|
||||
|
||||
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 +195,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);
|
||||
@ -202,11 +266,4 @@ bool PlayerProfile::operator<(const PlayerProfile &other)
|
||||
} // operator<
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** \brief Needed for toggling sort order **/
|
||||
bool PlayerProfile::operator>(const PlayerProfile &other)
|
||||
{
|
||||
return m_use_frequency > other.m_use_frequency;
|
||||
} // operator>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
@ -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;
|
||||
|
||||
@ -110,29 +116,28 @@ public:
|
||||
void initRemainingData();
|
||||
void incrementUseFrequency();
|
||||
bool operator<(const PlayerProfile &other);
|
||||
bool operator>(const PlayerProfile &other);
|
||||
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 +165,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 +262,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
|
||||
|
@ -464,6 +464,9 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX BoolUserConfigParam m_dof
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_dof",
|
||||
&m_video_group, "Enable Depth of Field"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_gi
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_gi",
|
||||
&m_video_group, "Enable Global Illumination"));
|
||||
|
||||
// ---- Debug - not saved to config file
|
||||
/** If gamepad debugging is enabled. */
|
||||
@ -677,6 +680,15 @@ 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"));
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_always_show_login_screen
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "always_show_login_screen",
|
||||
"Always show the login screen even if last player's session was saved."));
|
||||
// ---- Online gameplay related
|
||||
|
||||
PARAM_PREFIX GroupUserConfigParam m_online_group
|
||||
|
@ -353,10 +353,10 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha)
|
||||
{
|
||||
float alpha = data[4 * i + 3];
|
||||
if (alpha > 0.)
|
||||
alpha = pow(alpha / 255., 1. / 2.2);
|
||||
data[4 * i] *= alpha;
|
||||
data[4 * i + 1] *= alpha;
|
||||
data[4 * i + 2] *= alpha;
|
||||
alpha = pow(alpha / 255.f, 1.f / 2.2f);
|
||||
data[4 * i ] = (unsigned char)(data[4 * i ] * alpha);
|
||||
data[4 * i + 1] = (unsigned char)(data[4 * i + 1] * alpha);
|
||||
data[4 * i + 2] = (unsigned char)(data[4 * i + 2] * alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@ -518,13 +518,21 @@ unsigned GPUTimer::elapsedTimeus()
|
||||
|
||||
FrameBuffer::FrameBuffer() {}
|
||||
|
||||
FrameBuffer::FrameBuffer(const std::vector<GLuint> &RTTs, size_t w, size_t h) :
|
||||
FrameBuffer::FrameBuffer(const std::vector<GLuint> &RTTs, size_t w, size_t h, bool layered) :
|
||||
DepthTexture(0), RenderTargets(RTTs), width(w), height(h)
|
||||
{
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
for (unsigned i = 0; i < RTTs.size(); i++)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, RTTs[i], 0);
|
||||
if (layered)
|
||||
{
|
||||
for (unsigned i = 0; i < RTTs.size(); i++)
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, RTTs[i], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned i = 0; i < RTTs.size(); i++)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, RTTs[i], 0);
|
||||
}
|
||||
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
assert(result == GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||
}
|
||||
@ -560,7 +568,7 @@ void FrameBuffer::Bind()
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glViewport(0, 0, width, height);
|
||||
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver*)irr_driver->getDevice()->getVideoDriver();
|
||||
GLenum bufs[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
|
||||
GLenum bufs[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
|
||||
gl_driver->extGlDrawBuffers(RenderTargets.size(), bufs);
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ private:
|
||||
size_t width, height;
|
||||
public:
|
||||
FrameBuffer();
|
||||
FrameBuffer(const std::vector <GLuint> &RTTs, size_t w, size_t h);
|
||||
FrameBuffer(const std::vector <GLuint> &RTTs, size_t w, size_t h, bool layered = false);
|
||||
FrameBuffer(const std::vector <GLuint> &RTTs, GLuint DS, size_t w, size_t h, bool layered = false);
|
||||
~FrameBuffer();
|
||||
void Bind();
|
||||
|
@ -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
|
||||
|
@ -110,7 +110,7 @@ IrrDriver::IrrDriver()
|
||||
m_post_processing = NULL;
|
||||
m_wind = new Wind();
|
||||
m_mipviz = m_wireframe = m_normals = m_ssaoviz = \
|
||||
m_lightviz = m_shadowviz = m_distortviz = 0;
|
||||
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = 0;
|
||||
SkyboxCubeMap = 0;
|
||||
} // IrrDriver
|
||||
|
||||
|
@ -203,6 +203,9 @@ private:
|
||||
/** RTTs. */
|
||||
RTT *m_rtts;
|
||||
std::vector<core::matrix4> sun_ortho_matrix;
|
||||
core::vector3df rh_extend;
|
||||
core::matrix4 rh_matrix;
|
||||
core::matrix4 rsm_matrix;
|
||||
|
||||
/** Additional details to be shown in case that a texture is not found.
|
||||
* This is used to specify details like: "while loading kart '...'" */
|
||||
@ -233,7 +236,7 @@ private:
|
||||
RES_CHANGE_CANCEL} m_resolution_changing;
|
||||
|
||||
public:
|
||||
GLuint SkyboxCubeMap, FakeSkybox;
|
||||
GLuint SkyboxCubeMap;
|
||||
/** A simple class to store video resolutions. */
|
||||
class VideoMode
|
||||
{
|
||||
@ -312,6 +315,9 @@ private:
|
||||
bool m_mipviz;
|
||||
bool m_normals;
|
||||
bool m_ssaoviz;
|
||||
bool m_rsm;
|
||||
bool m_rh;
|
||||
bool m_gi;
|
||||
bool m_shadowviz;
|
||||
bool m_lightviz;
|
||||
bool m_distortviz;
|
||||
@ -573,6 +579,9 @@ public:
|
||||
m_mipviz = false;
|
||||
m_normals = false;
|
||||
m_ssaoviz = false;
|
||||
m_rsm = false;
|
||||
m_rh = false;
|
||||
m_gi = false;
|
||||
m_shadowviz = false;
|
||||
m_lightviz = false;
|
||||
m_distortviz = false;
|
||||
@ -594,6 +603,18 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
bool getSSAOViz() { return m_ssaoviz; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleRSM() { m_rsm = !m_rsm; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getRSM() { return m_rsm; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleRH() { m_rh = !m_rh; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getRH() { return m_rh; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleGI() { m_gi = !m_gi; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getGI() { return m_gi; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleShadowViz() { m_shadowviz = !m_shadowviz; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getShadowViz() { return m_shadowviz; }
|
||||
|
@ -243,6 +243,17 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
if (b)
|
||||
m_shader_type = SHADERTYPE_SPHERE_MAP;
|
||||
|
||||
|
||||
if (node->get("compositing", &s))
|
||||
{
|
||||
if (s == "blend") m_shader_type = SHADERTYPE_ALPHA_BLEND;
|
||||
else if (s == "test") m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
else if (s == "additive") m_shader_type = SHADERTYPE_ADDITIVE;
|
||||
else if (s == "coverage") m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
else if (s != "none")
|
||||
Log::warn("material", "Unknown compositing mode '%s'", s.c_str());
|
||||
}
|
||||
|
||||
s = "";
|
||||
node->get("graphical-effect", &s);
|
||||
|
||||
@ -294,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);
|
||||
@ -322,16 +329,6 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
m_shader_type = SHADERTYPE_SPHERE_MAP;
|
||||
}
|
||||
|
||||
if (node->get("compositing", &s))
|
||||
{
|
||||
if (s == "blend") m_shader_type = SHADERTYPE_ALPHA_BLEND;
|
||||
else if (s == "test") m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
else if (s == "additive") m_shader_type = SHADERTYPE_ADDITIVE;
|
||||
else if (s == "coverage") m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
else if (s != "none")
|
||||
Log::warn("material", "Unknown compositing mode '%s'", s.c_str());
|
||||
}
|
||||
|
||||
bool water_shader = false;
|
||||
node->get("water-shader", &water_shader);
|
||||
if (water_shader)
|
||||
@ -697,12 +694,17 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SOLID_UNLIT)
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
|
||||
|
||||
m->AmbientColor = video::SColor(255, 255, 255, 255);
|
||||
m->DiffuseColor = video::SColor(255, 255, 255, 255);
|
||||
m->EmissiveColor = video::SColor(255, 255, 255, 255);
|
||||
m->SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->AmbientColor = video::SColor(255, 255, 255, 255);
|
||||
m->DiffuseColor = video::SColor(255, 255, 255, 255);
|
||||
m->EmissiveColor = video::SColor(255, 255, 255, 255);
|
||||
m->SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_ALPHA_TEST)
|
||||
|
@ -264,6 +264,35 @@ void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSH
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3df &rh_extend, GLuint shr, GLuint shg, GLuint shb)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glUseProgram(FullScreenShader::GlobalIlluminationReconstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::GlobalIlluminationReconstructionShader::vao);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_3D, shr);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, shg);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_3D, shb);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
setTexture(3, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(4, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::GlobalIlluminationReconstructionShader::setUniforms(RHMatrix, rh_extend, 3, 4, 0, 1, 2);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void PostProcessing::renderSunlight()
|
||||
{
|
||||
SunLightProvider * const cb = (SunLightProvider *) irr_driver->getCallback(ES_SUNLIGHT);
|
||||
@ -476,7 +505,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);
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
void renderFog();
|
||||
void renderSSAO();
|
||||
void renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff);
|
||||
void renderGI(const core::matrix4 &RHMatrix, const core::vector3df &rh_extend, unsigned shr, unsigned shg, unsigned shb);
|
||||
|
||||
/** Blur the in texture */
|
||||
void renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary);
|
||||
|
@ -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]);
|
||||
@ -195,6 +195,12 @@ void IrrDriver::renderGLSL(float dt)
|
||||
irr_driver->getFBO(FBO_NORMAL_AND_DEPTHS).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
|
||||
else if (irr_driver->getSSAOViz())
|
||||
irr_driver->getFBO(FBO_SSAO).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
|
||||
else if (irr_driver->getRSM())
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
|
||||
m_post_processing->renderPassThrough(m_rtts->getRSM().getRTT()[0]);
|
||||
}
|
||||
else
|
||||
fbo->BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
|
||||
|
||||
@ -314,9 +320,32 @@ 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();
|
||||
|
||||
if (getRH())
|
||||
{
|
||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||
m_rtts->getFBO(FBO_COLORS).Bind();
|
||||
glUseProgram(FullScreenShader::RHDebug::Program);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[0]);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[1]);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[2]);
|
||||
FullScreenShader::RHDebug::setUniforms(rh_matrix, rh_extend, 0, 1, 2);
|
||||
glDrawArrays(GL_POINTS, 0, 32 * 16 * 32);
|
||||
glDisable(GL_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
|
||||
if (getGI())
|
||||
{
|
||||
m_rtts->getFBO(FBO_COLORS).Bind();
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00);
|
||||
// Render anything glowing.
|
||||
if (!m_mipviz && !m_wireframe && UserConfigParams::m_glow)
|
||||
@ -501,17 +530,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -613,6 +669,8 @@ void IrrDriver::renderParticles()
|
||||
|
||||
void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, size_t width, size_t height)
|
||||
{
|
||||
static int tick = 0;
|
||||
tick++;
|
||||
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
|
||||
irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
|
||||
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||
@ -701,6 +759,13 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
|
||||
|
||||
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||
}
|
||||
if (!(tick % 100))
|
||||
rsm_matrix = sun_ortho_matrix[3];
|
||||
rh_extend = core::vector3df(128, 64, 128);
|
||||
core::vector3df campos = camnode->getAbsolutePosition();
|
||||
core::vector3df translation(8 * floor(campos.X / 8), 8 * floor(campos.Y / 8), 8 * floor(campos.Z / 8));
|
||||
rh_matrix.setTranslation(translation);
|
||||
|
||||
assert(sun_ortho_matrix.size() == 4);
|
||||
camnode->setNearValue(oldnear);
|
||||
camnode->setFarValue(oldfar);
|
||||
@ -708,10 +773,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);
|
||||
@ -747,7 +810,22 @@ void IrrDriver::renderShadows()
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
if (!UserConfigParams::m_gi)
|
||||
return;
|
||||
|
||||
m_rtts->getRSM().Bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glUseProgram(MeshShader::RSMShader::Program);
|
||||
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
|
||||
{
|
||||
const GLMesh mesh = *GroupedFPSM<FPSM_DEFAULT>::MeshSet[i];
|
||||
if (!mesh.textures[0])
|
||||
continue;
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
draw<MeshShader::RSMShader>(mesh, mesh.vao_rsm_pass, rsm_matrix, GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -837,6 +915,19 @@ static void renderPointLights(unsigned count)
|
||||
|
||||
void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
{
|
||||
//RH
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
m_rtts->getRH().Bind();
|
||||
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::RadianceHintsConstructionShader::vao);
|
||||
setTexture(0, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(1, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(2, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::RadianceHintsConstructionShader::setUniforms(rsm_matrix, rh_matrix, rh_extend, 0, 1, 2);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
|
||||
sun_ortho_matrix[i] *= getInvViewMatrix();
|
||||
@ -845,10 +936,10 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
glClearColor(.5, .5, .5, .5);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
{
|
||||
//gl_driver->extGlDrawBuffers(1, bufs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_gi)
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
|
||||
if (SkyboxCubeMap)
|
||||
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
||||
@ -929,7 +1020,6 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
renderPointLights(MIN2(lightnum, MAXLIGHT));
|
||||
if (SkyboxCubeMap)
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
// gl_driver->extGlDrawBuffers(1, bufs);
|
||||
}
|
||||
|
||||
void IrrDriver::renderSSAO()
|
||||
@ -1395,20 +1485,6 @@ void IrrDriver::generateSkyboxCubemap()
|
||||
|
||||
void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
|
||||
{
|
||||
if (SkyboxTextures.empty() && FakeSkybox)
|
||||
{
|
||||
glGenTextures(1, &FakeSkybox);
|
||||
|
||||
unsigned w = 1, h = 1;
|
||||
|
||||
char *rgba[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
rgba[i] = new char[w * h * 4];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_COMPRESSED_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SkyboxCubeMap)
|
||||
generateSkyboxCubemap();
|
||||
glBindVertexArray(MeshShader::SkyboxShader::cubevao);
|
||||
|
@ -54,7 +54,7 @@ static GLuint generateFBO(GLuint ColorAttachement, GLuint DepthAttachement)
|
||||
RTT::RTT(size_t width, size_t height)
|
||||
{
|
||||
m_shadow_FBO = NULL;
|
||||
initGL();
|
||||
m_RSM = NULL;
|
||||
using namespace video;
|
||||
using namespace core;
|
||||
|
||||
@ -199,6 +199,38 @@ RTT::RTT(size_t width, size_t height)
|
||||
somevector.clear();
|
||||
somevector.push_back(shadowColorTex);
|
||||
m_shadow_FBO = new FrameBuffer(somevector, shadowDepthTex, 1024, 1024, true);
|
||||
|
||||
//Todo : use "normal" shadowtex
|
||||
glGenTextures(1, &RSM_Color);
|
||||
glBindTexture(GL_TEXTURE_2D, RSM_Color);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||
glGenTextures(1, &RSM_Normal);
|
||||
glBindTexture(GL_TEXTURE_2D, RSM_Normal);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, 0);
|
||||
glGenTextures(1, &RSM_Depth);
|
||||
glBindTexture(GL_TEXTURE_2D, RSM_Depth);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, 1024, 1024, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
|
||||
|
||||
somevector.clear();
|
||||
somevector.push_back(RSM_Color);
|
||||
somevector.push_back(RSM_Normal);
|
||||
m_RSM = new FrameBuffer(somevector, RSM_Depth, 1024, 1024, true);
|
||||
|
||||
glGenTextures(1, &RH_Red);
|
||||
glBindTexture(GL_TEXTURE_3D, RH_Red);
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, 32, 16, 32, 0, GL_RGBA, GL_FLOAT, 0);
|
||||
glGenTextures(1, &RH_Green);
|
||||
glBindTexture(GL_TEXTURE_3D, RH_Green);
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, 32, 16, 32, 0, GL_RGBA, GL_FLOAT, 0);
|
||||
glGenTextures(1, &RH_Blue);
|
||||
glBindTexture(GL_TEXTURE_3D, RH_Blue);
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, 32, 16, 32, 0, GL_RGBA, GL_FLOAT, 0);
|
||||
|
||||
somevector.clear();
|
||||
somevector.push_back(RH_Red);
|
||||
somevector.push_back(RH_Green);
|
||||
somevector.push_back(RH_Blue);
|
||||
m_RH_FBO = new FrameBuffer(somevector, 32, 16, true);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
@ -206,11 +238,19 @@ RTT::RTT(size_t width, size_t height)
|
||||
RTT::~RTT()
|
||||
{
|
||||
delete m_shadow_FBO;
|
||||
delete m_RH_FBO;
|
||||
delete m_RSM;
|
||||
glDeleteTextures(RTT_COUNT, RenderTargetTextures);
|
||||
glDeleteTextures(1, &DepthStencilTexture);
|
||||
if (irr_driver->getGLSLVersion() >= 150)
|
||||
{
|
||||
glDeleteTextures(1, &shadowColorTex);
|
||||
glDeleteTextures(1, &shadowDepthTex);
|
||||
glDeleteTextures(1, &RSM_Color);
|
||||
glDeleteTextures(1, &RSM_Normal);
|
||||
glDeleteTextures(1, &RSM_Depth);
|
||||
glDeleteTextures(1, &RH_Red);
|
||||
glDeleteTextures(1, &RH_Green);
|
||||
glDeleteTextures(1, &RH_Blue);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ public:
|
||||
~RTT();
|
||||
|
||||
FrameBuffer &getShadowFBO() { return *m_shadow_FBO; }
|
||||
FrameBuffer &getRH() { return *m_RH_FBO; }
|
||||
FrameBuffer &getRSM() { return *m_RSM; }
|
||||
unsigned getShadowDepthTex() const { return shadowDepthTex; }
|
||||
|
||||
unsigned getDepthStencilTexture() const { return DepthStencilTexture; }
|
||||
@ -48,8 +50,10 @@ private:
|
||||
PtrVector<FrameBuffer> FrameBuffers;
|
||||
unsigned DepthStencilTexture;
|
||||
|
||||
unsigned shadowColorTex, shadowDepthTex;
|
||||
FrameBuffer* m_shadow_FBO;
|
||||
unsigned shadowColorTex, shadowNormalTex, shadowDepthTex;
|
||||
unsigned RSM_Color, RSM_Normal, RSM_Depth;
|
||||
unsigned RH_Red, RH_Green, RH_Blue;
|
||||
FrameBuffer* m_shadow_FBO, *m_RSM, *m_RH_FBO;
|
||||
|
||||
LEAK_CHECK();
|
||||
};
|
||||
|
@ -281,6 +281,9 @@ void Shaders::loadShaders()
|
||||
FullScreenShader::DiffuseEnvMapShader::init();
|
||||
FullScreenShader::ShadowedSunLightShader::init();
|
||||
FullScreenShader::ShadowedSunLightDebugShader::init();
|
||||
FullScreenShader::RadianceHintsConstructionShader::init();
|
||||
FullScreenShader::RHDebug::init();
|
||||
FullScreenShader::GlobalIlluminationReconstructionShader::init();
|
||||
FullScreenShader::MotionBlurShader::init();
|
||||
FullScreenShader::GodFadeShader::init();
|
||||
FullScreenShader::GodRayShader::init();
|
||||
@ -317,6 +320,7 @@ void Shaders::loadShaders()
|
||||
MeshShader::DisplaceShader::init();
|
||||
MeshShader::DisplaceMaskShader::init();
|
||||
MeshShader::ShadowShader::init();
|
||||
MeshShader::RSMShader::init();
|
||||
MeshShader::InstancedShadowShader::init();
|
||||
MeshShader::RefShadowShader::init();
|
||||
MeshShader::InstancedRefShadowShader::init();
|
||||
@ -1487,6 +1491,36 @@ namespace MeshShader
|
||||
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
|
||||
}
|
||||
|
||||
GLuint RSMShader::Program;
|
||||
GLuint RSMShader::attrib_position;
|
||||
GLuint RSMShader::attrib_texcoord;
|
||||
GLuint RSMShader::attrib_normal;
|
||||
GLuint RSMShader::uniform_MM;
|
||||
GLuint RSMShader::uniform_tex;
|
||||
GLuint RSMShader::uniform_RSMMatrix;
|
||||
|
||||
void RSMShader::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/rsm.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/rsm.frag").c_str());
|
||||
attrib_position = glGetAttribLocation(Program, "Position");
|
||||
uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
|
||||
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
||||
attrib_normal = glGetAttribLocation(Program, "Normal");
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_RSMMatrix = glGetUniformLocation(Program, "RSMMatrix");
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void RSMShader::setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &ModelMatrix, unsigned TU_tex)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_RSMMatrix, 1, GL_FALSE, RSMMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
|
||||
GLuint InstancedShadowShader::Program;
|
||||
GLuint InstancedShadowShader::attrib_position;
|
||||
GLuint InstancedShadowShader::attrib_origin;
|
||||
@ -2273,6 +2307,122 @@ namespace FullScreenShader
|
||||
glUniform1i(uniform_shadowtex, TU_shadowtex);
|
||||
}
|
||||
|
||||
GLuint RadianceHintsConstructionShader::Program;
|
||||
GLuint RadianceHintsConstructionShader::uniform_ctex;
|
||||
GLuint RadianceHintsConstructionShader::uniform_ntex;
|
||||
GLuint RadianceHintsConstructionShader::uniform_dtex;
|
||||
GLuint RadianceHintsConstructionShader::uniform_extents;
|
||||
GLuint RadianceHintsConstructionShader::uniform_RHMatrix;
|
||||
GLuint RadianceHintsConstructionShader::uniform_RSMMatrix;
|
||||
GLuint RadianceHintsConstructionShader::vao;
|
||||
|
||||
void RadianceHintsConstructionShader::init()
|
||||
{
|
||||
if (irr_driver->hasVSLayerExtension())
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/slicedscreenquad.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/rh.frag").c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/slicedscreenquad.vert").c_str(),
|
||||
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/rhpassthrough.geom").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/rh.frag").c_str());
|
||||
}
|
||||
|
||||
uniform_ctex = glGetUniformLocation(Program, "ctex");
|
||||
uniform_ntex = glGetUniformLocation(Program, "ntex");
|
||||
uniform_dtex = glGetUniformLocation(Program, "dtex");
|
||||
uniform_extents = glGetUniformLocation(Program, "extents");
|
||||
uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix");
|
||||
uniform_RSMMatrix = glGetUniformLocation(Program, "RSMMatrix");
|
||||
vao = createVAO(Program);
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void RadianceHintsConstructionShader::setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ctex, unsigned TU_ntex, unsigned TU_dtex)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_RSMMatrix, 1, GL_FALSE, RSMMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_RHMatrix, 1, GL_FALSE, RHMatrix.pointer());
|
||||
glUniform1i(uniform_ctex, TU_ctex);
|
||||
glUniform1i(uniform_ntex, TU_ntex);
|
||||
glUniform1i(uniform_dtex, TU_dtex);
|
||||
glUniform3f(uniform_extents, extents.X, extents.Y, extents.Z);
|
||||
}
|
||||
|
||||
GLuint RHDebug::Program;
|
||||
GLuint RHDebug::uniform_extents;
|
||||
GLuint RHDebug::uniform_SHR;
|
||||
GLuint RHDebug::uniform_SHG;
|
||||
GLuint RHDebug::uniform_SHB;
|
||||
GLuint RHDebug::uniform_RHMatrix;
|
||||
|
||||
void RHDebug::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/rhdebug.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/rhdebug.frag").c_str());
|
||||
uniform_extents = glGetUniformLocation(Program, "extents");
|
||||
uniform_SHR = glGetUniformLocation(Program, "SHR");
|
||||
uniform_SHG = glGetUniformLocation(Program, "SHG");
|
||||
uniform_SHB = glGetUniformLocation(Program, "SHB");
|
||||
uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix");
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void RHDebug::setUniforms(const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_RHMatrix, 1, GL_FALSE, RHMatrix.pointer());
|
||||
glUniform3f(uniform_extents, extents.X, extents.Y, extents.Z);
|
||||
glUniform1i(uniform_SHR, TU_SHR);
|
||||
glUniform1i(uniform_SHG, TU_SHG);
|
||||
glUniform1i(uniform_SHB, TU_SHB);
|
||||
}
|
||||
|
||||
GLuint GlobalIlluminationReconstructionShader::Program;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_ntex;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_dtex;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_SHR;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_SHG;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_SHB;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_extents;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_RHMatrix;
|
||||
GLuint GlobalIlluminationReconstructionShader::vao;
|
||||
|
||||
void GlobalIlluminationReconstructionShader::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gi.frag").c_str());
|
||||
uniform_ntex = glGetUniformLocation(Program, "ntex");
|
||||
uniform_dtex = glGetUniformLocation(Program, "dtex");
|
||||
uniform_SHR = glGetUniformLocation(Program, "SHR");
|
||||
uniform_SHG = glGetUniformLocation(Program, "SHG");
|
||||
uniform_SHB = glGetUniformLocation(Program, "SHB");
|
||||
uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix");
|
||||
uniform_extents = glGetUniformLocation(Program, "extents");
|
||||
vao = createVAO(Program);
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void GlobalIlluminationReconstructionShader::setUniforms(const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_RHMatrix, 1, GL_FALSE, RHMatrix.pointer());
|
||||
glUniform1i(uniform_ntex, TU_ntex);
|
||||
glUniform1i(uniform_dtex, TU_dtex);
|
||||
glUniform1i(uniform_SHR, TU_SHR);
|
||||
glUniform1i(uniform_SHG, TU_SHG);
|
||||
glUniform1i(uniform_SHB, TU_SHB);
|
||||
glUniform3f(uniform_extents, extents.X, extents.Y, extents.Z);
|
||||
}
|
||||
|
||||
GLuint Gaussian17TapHShader::Program;
|
||||
GLuint Gaussian17TapHShader::uniform_tex;
|
||||
GLuint Gaussian17TapHShader::uniform_pixel;
|
||||
|
@ -336,6 +336,17 @@ public:
|
||||
static void setUniforms(const core::matrix4 &ModelMatrix);
|
||||
};
|
||||
|
||||
class RSMShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint attrib_position, attrib_texcoord, attrib_normal;
|
||||
static GLuint uniform_MM, uniform_tex, uniform_RSMMatrix;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &ModelMatrix, unsigned TU_tex);
|
||||
};
|
||||
|
||||
class InstancedShadowShader
|
||||
{
|
||||
public:
|
||||
@ -598,6 +609,38 @@ public:
|
||||
static void setUniforms(const core::vector3df &direction, float r, float g, float b, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_shadowtex);
|
||||
};
|
||||
|
||||
class RadianceHintsConstructionShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_ctex, uniform_ntex, uniform_dtex, uniform_extents, uniform_RHMatrix, uniform_RSMMatrix;
|
||||
static GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ctex, unsigned TU_ntex, unsigned TU_dtex);
|
||||
};
|
||||
|
||||
class RHDebug
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_extents, uniform_SHR, uniform_SHG, uniform_SHB, uniform_RHMatrix;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB);
|
||||
};
|
||||
|
||||
class GlobalIlluminationReconstructionShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_ntex, uniform_dtex, uniform_extents, uniform_SHR, uniform_SHG, uniform_SHB, uniform_RHMatrix;
|
||||
static GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB);
|
||||
};
|
||||
|
||||
class Gaussian17TapHShader
|
||||
{
|
||||
public:
|
||||
|
@ -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();
|
||||
@ -730,6 +659,7 @@ void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedM
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectPass1Shader::attrib_position, MeshShader::ObjectPass1Shader::attrib_texcoord, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
mesh.vao_rsm_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::RSMShader::attrib_position, MeshShader::RSMShader::attrib_texcoord, -1, MeshShader::RSMShader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case FPSM_ALPHA_REF_TEXTURE:
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
|
@ -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
|
||||
@ -45,6 +47,7 @@ struct GLMesh {
|
||||
GLuint vao_glow_pass;
|
||||
GLuint vao_displace_pass;
|
||||
GLuint vao_displace_mask_pass;
|
||||
GLuint vao_rsm_pass;
|
||||
GLuint vao_shadow_pass;
|
||||
GLuint vertex_buffer;
|
||||
GLuint index_buffer;
|
||||
@ -89,9 +92,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");
|
||||
}
|
||||
|
@ -714,7 +714,13 @@ void Skin::drawButton(Widget* w, const core::recti &rect,
|
||||
center.Y + (int)(((int)rect.LowerRightCorner.Y
|
||||
- (int)center.Y)*texture_size);
|
||||
|
||||
if (focused)
|
||||
if (w->m_deactivated)
|
||||
{
|
||||
drawBoxFromStretchableTexture(w, sized_rect,
|
||||
SkinConfig::m_render_params["button::deactivated"],
|
||||
w->m_deactivated);
|
||||
}
|
||||
else if (focused)
|
||||
{
|
||||
drawBoxFromStretchableTexture(w, sized_rect,
|
||||
SkinConfig::m_render_params["button::focused"],
|
||||
@ -725,11 +731,17 @@ void Skin::drawButton(Widget* w, const core::recti &rect,
|
||||
drawBoxFromStretchableTexture(w, sized_rect,
|
||||
SkinConfig::m_render_params["button::neutral"],
|
||||
w->m_deactivated);
|
||||
}
|
||||
} // if not deactivated or focused
|
||||
}
|
||||
else // not within an appearing dialog
|
||||
{
|
||||
if (focused)
|
||||
if (w->m_deactivated)
|
||||
{
|
||||
drawBoxFromStretchableTexture(w, rect,
|
||||
SkinConfig::m_render_params["button::deactivated"],
|
||||
w->m_deactivated);
|
||||
}
|
||||
else if (focused)
|
||||
{
|
||||
drawBoxFromStretchableTexture(w, rect,
|
||||
SkinConfig::m_render_params["button::focused"],
|
||||
@ -740,7 +752,7 @@ void Skin::drawButton(Widget* w, const core::recti &rect,
|
||||
drawBoxFromStretchableTexture(w, rect,
|
||||
SkinConfig::m_render_params["button::neutral"],
|
||||
w->m_deactivated);
|
||||
} // if not focused
|
||||
} // if not deactivated or focused
|
||||
} // not within an appearing dialog
|
||||
} // drawButton
|
||||
|
||||
@ -818,7 +830,7 @@ void Skin::drawRatingBar(Widget *w, const core::recti &rect,
|
||||
const int texture_w = texture->getSize().Width / 4;
|
||||
const int texture_h = texture->getSize().Height;
|
||||
const float aspect_ratio = 1.0f;
|
||||
|
||||
|
||||
const int star_number = ratingBar->getStarNumber();
|
||||
|
||||
int star_h = rect.getHeight();
|
||||
@ -830,7 +842,7 @@ void Skin::drawRatingBar(Widget *w, const core::recti &rect,
|
||||
star_w = (int)(star_w * scale_factor);
|
||||
star_h = (int)(star_h * scale_factor);
|
||||
}
|
||||
|
||||
|
||||
// center horizontally and vertically
|
||||
const int x_from = rect.UpperLeftCorner.X;
|
||||
const int y_from = rect.UpperLeftCorner.Y;
|
||||
@ -853,9 +865,9 @@ void Skin::drawRatingBar(Widget *w, const core::recti &rect,
|
||||
star_rect.UpperLeftCorner.Y = y_from;
|
||||
star_rect.LowerRightCorner.X = x_from + (i + 1) * star_w;
|
||||
star_rect.LowerRightCorner.Y = y_from + star_h;
|
||||
|
||||
|
||||
int step = ratingBar->getStepsOfStar(i);
|
||||
|
||||
|
||||
const core::recti source_area(texture_w * step, 0,
|
||||
texture_w * (step + 1), texture_h);
|
||||
|
||||
@ -1236,7 +1248,11 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget,
|
||||
else if(player_id==3)
|
||||
params=&SkinConfig::m_render_params["spinner4::neutral"];
|
||||
}
|
||||
else if (focused|| pressed)
|
||||
else if (widget->m_deactivated)
|
||||
{
|
||||
params=&SkinConfig::m_render_params["spinner::deactivated"];
|
||||
}
|
||||
else if (focused || pressed)
|
||||
{
|
||||
params=&SkinConfig::m_render_params["spinner::focused"];
|
||||
}
|
||||
@ -1253,7 +1269,7 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget,
|
||||
rect2.LowerRightCorner.Y += 5;
|
||||
drawBoxFromStretchableTexture(widget, rect2,
|
||||
SkinConfig::m_render_params["squareFocusHalo::neutral"]);
|
||||
|
||||
|
||||
|
||||
}
|
||||
else if (widget->isFocusedForPlayer(1))
|
||||
@ -1314,7 +1330,7 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget,
|
||||
|
||||
// ---- If this spinner is of "gauge" type, draw filling
|
||||
const SpinnerWidget* w = dynamic_cast<const SpinnerWidget*>(widget);
|
||||
|
||||
|
||||
if (w->isGauge() && !w->m_deactivated)
|
||||
{
|
||||
const int handle_size = (int)( widget->m_h*params->m_left_border
|
||||
@ -1361,7 +1377,7 @@ void Skin::drawSpinnerChild(const core::recti &rect, Widget* widget,
|
||||
{
|
||||
if (!widget->isVisible()) return;
|
||||
|
||||
if (pressed)
|
||||
if (!widget->m_deactivated && pressed)
|
||||
{
|
||||
Widget* spinner = widget->m_event_handler;
|
||||
int areas = 0;
|
||||
@ -1516,19 +1532,39 @@ void Skin::drawCheckBox(const core::recti &rect, Widget* widget, bool focused)
|
||||
|
||||
if (w->getState() == true)
|
||||
{
|
||||
texture = focused
|
||||
? SkinConfig::m_render_params["checkbox::focused+checked"]
|
||||
.getImage()
|
||||
: SkinConfig::m_render_params["checkbox::neutral+checked"]
|
||||
.getImage();
|
||||
if (w->m_deactivated)
|
||||
{
|
||||
texture = SkinConfig::m_render_params["checkbox::deactivated+checked"]
|
||||
.getImage();
|
||||
}
|
||||
else if(focused)
|
||||
{
|
||||
texture = SkinConfig::m_render_params["checkbox::focused+checked"]
|
||||
.getImage();
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = SkinConfig::m_render_params["checkbox::neutral+checked"]
|
||||
.getImage();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = focused
|
||||
? SkinConfig::m_render_params["checkbox::focused+unchecked"]
|
||||
.getImage()
|
||||
: SkinConfig::m_render_params["checkbox::neutral+unchecked"]
|
||||
.getImage();
|
||||
if (w->m_deactivated)
|
||||
{
|
||||
texture = SkinConfig::m_render_params["checkbox::deactivated+unchecked"]
|
||||
.getImage();
|
||||
}
|
||||
else if(focused)
|
||||
{
|
||||
texture = SkinConfig::m_render_params["checkbox::focused+unchecked"]
|
||||
.getImage();
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = SkinConfig::m_render_params["checkbox::neutral+unchecked"]
|
||||
.getImage();
|
||||
}
|
||||
}
|
||||
|
||||
const int texture_w = texture->getSize().Width;
|
||||
@ -1651,7 +1687,7 @@ void Skin::renderSections(PtrVector<Widget>* within_vector)
|
||||
drawBoxFromStretchableTexture(&widget, rect,
|
||||
SkinConfig::m_render_params["section::neutral"]);
|
||||
}
|
||||
|
||||
|
||||
renderSections( &widget.m_children );
|
||||
}
|
||||
else if (widget.isBottomBar())
|
||||
|
@ -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
|
||||
|
@ -1213,7 +1213,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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
95
src/main.cpp
95
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,24 @@ 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 (unless it was requested
|
||||
// to always show the login screen). Otherwise show the login
|
||||
// screen first.
|
||||
if(PlayerManager::getCurrentPlayer() && !
|
||||
UserConfigParams::m_always_show_login_screen)
|
||||
{
|
||||
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 +1317,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,26 @@ 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 ? "true"
|
||||
: "false");
|
||||
request->queue();
|
||||
m_online_state = OS_SIGNING_IN;
|
||||
return request;
|
||||
} // requestSignIn
|
||||
|
||||
@ -143,7 +139,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 +183,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 +208,81 @@ 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, which have the highest priority (same as
|
||||
* quit-stk request). This allows the final logout request at
|
||||
* the end of STK to be handled, even if a quit request gets
|
||||
* added (otherwise if quit has higher priority, the quit can
|
||||
* be executed before signout, resulting in players not being
|
||||
* logged out properly). It also guarantees that the logout
|
||||
* happens before a following logout.
|
||||
*/
|
||||
SignOutRequest(PlayerProfile *player)
|
||||
: XMLRequest(true,/*priority*/RequestManager::HTTP_MAX_PRIORITY)
|
||||
{
|
||||
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 +293,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 +433,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);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "online/request_manager.hpp"
|
||||
|
||||
#include "config/player_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
|
||||
#include <iostream>
|
||||
@ -130,8 +131,12 @@ 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() &&
|
||||
!UserConfigParams::m_always_show_login_screen)
|
||||
{
|
||||
PlayerManager::resumeSavedSession();
|
||||
}
|
||||
} // startNetworkThread
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -100,7 +100,7 @@ namespace Online{
|
||||
break;
|
||||
case SO_NAME:
|
||||
// m_id is the lower case name
|
||||
return m_name < server.getName();
|
||||
return m_lower_case_name < server.m_lower_case_name;
|
||||
break;
|
||||
case SO_PLAYERS:
|
||||
return m_current_players < server.getCurrentPlayers();
|
||||
@ -109,28 +109,6 @@ namespace Online{
|
||||
return true;
|
||||
} // operator<
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Compares two addons according to the sort order currently defined.
|
||||
* Comparison is done for sorting in descending order.
|
||||
* \param a The addon to compare this addon to.
|
||||
*/
|
||||
bool operator>(const Server &server) const
|
||||
{
|
||||
switch(m_sort_order)
|
||||
{
|
||||
case SO_SCORE:
|
||||
return m_satisfaction_score > server.getScore();
|
||||
break;
|
||||
case SO_NAME:
|
||||
return m_lower_case_name > server.getLowerCaseName();
|
||||
break;
|
||||
case SO_PLAYERS:
|
||||
return m_current_players > server.getCurrentPlayers();
|
||||
break;
|
||||
} // switch
|
||||
return true;
|
||||
} // operator>
|
||||
|
||||
}; // Server
|
||||
} // namespace Online
|
||||
|
||||
|
@ -555,13 +555,6 @@ namespace computeGPRanksData
|
||||
(m_score == a.m_score && m_race_time < a.m_race_time) );
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
bool operator>(const SortData &a)
|
||||
{
|
||||
return ( (m_score < a.m_score) ||
|
||||
(m_score == a.m_score && m_race_time > a.m_race_time) );
|
||||
}
|
||||
|
||||
}; // SortData
|
||||
} // namespace
|
||||
|
||||
|
@ -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
|
@ -135,7 +135,8 @@ SelectChallengeDialog::SelectChallengeDialog(const float percentWidth,
|
||||
}
|
||||
else
|
||||
{
|
||||
const wchar_t* track_name = track_manager->getTrack(c->getData()->getTrackId())->getName();
|
||||
const core::stringw track_name =
|
||||
track_manager->getTrack(c->getData()->getTrackId())->getName();
|
||||
getWidget<LabelWidget>("title")->setText( track_name, true );
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
@ -320,7 +320,7 @@ void OptionsScreenInput2::updateInputButtons()
|
||||
getWidget<GUIEngine::LabelWidget>("conflict");
|
||||
if (conflicts)
|
||||
conflict_label->setText(
|
||||
_("* A blue item means a conflict with another configuration") );
|
||||
_("* A red item means a conflict with another configuration") );
|
||||
else
|
||||
conflict_label->setText("");
|
||||
|
||||
@ -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") {}
|
||||
@ -453,7 +453,7 @@ void OptionsScreenInput2::eventCallback(Widget* widget,
|
||||
}
|
||||
else if (name == "back")
|
||||
{
|
||||
sm->popMenu();
|
||||
sm->replaceTopMostScreen(OptionsScreenInput::getInstance());
|
||||
}
|
||||
else if (name == "actions")
|
||||
{
|
||||
|
@ -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* show_login = getWidget<CheckBoxWidget>("show-login");
|
||||
assert( show_login!= NULL );
|
||||
show_login->setState( UserConfigParams::m_always_show_login_screen);
|
||||
|
||||
// --- 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=="show-login")
|
||||
{
|
||||
CheckBoxWidget* show_login = getWidget<CheckBoxWidget>("show-login");
|
||||
assert( show_login != NULL );
|
||||
UserConfigParams::m_always_show_login_screen = show_login->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,111 @@ 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);
|
||||
getWidget<LabelWidget>("label_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 +199,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);
|
||||
}
|
||||
@ -101,6 +211,12 @@ void RegisterScreen::doRegister()
|
||||
{
|
||||
m_info_widget->setText(_("Email has to be between 4 and 50 characters long!"), false);
|
||||
}
|
||||
else if ( email.find(L"@")== -1 || email.find(L".")== -1 ||
|
||||
(email.findLast(L'.') - email.findLast(L'@') <= 2 ) ||
|
||||
email.findLast(L'@')==0 )
|
||||
{
|
||||
m_info_widget->setText(_("Email is invalid!"), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info_widget->setDefaultColor();
|
||||
@ -109,7 +225,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
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -180,15 +301,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")
|
||||
{
|
||||
@ -199,13 +314,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
|
@ -48,87 +48,91 @@ DEFINE_SCREEN_SINGLETON( TracksScreen );
|
||||
|
||||
TracksScreen::TracksScreen() : Screen("tracks.stkgui")
|
||||
{
|
||||
}
|
||||
} // TracksScreen
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TracksScreen::loadedFromFile()
|
||||
{
|
||||
}
|
||||
} // loadedFromFile
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TracksScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
|
||||
void TracksScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
const int playerID )
|
||||
{
|
||||
// -- track selection screen
|
||||
if (name == "tracks")
|
||||
{
|
||||
DynamicRibbonWidget* w2 = dynamic_cast<DynamicRibbonWidget*>(widget);
|
||||
if (w2 != NULL)
|
||||
if(!w2) return;
|
||||
|
||||
const std::string &selection =
|
||||
w2->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
if (UserConfigParams::logGUI())
|
||||
{
|
||||
const std::string selection = w2->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
if(UserConfigParams::logGUI())
|
||||
std::cout << "Clicked on track " << selection.c_str()
|
||||
<< std::endl;
|
||||
Log::info("TracksScreen", "Clicked on track '%s'.",
|
||||
selection.c_str());
|
||||
}
|
||||
|
||||
UserConfigParams::m_last_track = selection;
|
||||
UserConfigParams::m_last_track = selection;
|
||||
|
||||
if (selection == "random_track")
|
||||
if (selection == "random_track")
|
||||
{
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("trackgroups");
|
||||
assert(tabs);
|
||||
|
||||
if (m_random_track_list.empty()) return;
|
||||
|
||||
std::string track = m_random_track_list.front();
|
||||
m_random_track_list.pop_front();
|
||||
m_random_track_list.push_back(track);
|
||||
Track* clicked_track = track_manager->getTrack(track);
|
||||
|
||||
|
||||
if (clicked_track)
|
||||
{
|
||||
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs != NULL );
|
||||
ITexture* screenshot =
|
||||
irr_driver->getTexture(clicked_track->getScreenshotFile(),
|
||||
"While loading screenshot for track '%s':",
|
||||
clicked_track->getFilename() );
|
||||
|
||||
if (m_random_track_list.empty()) return;
|
||||
new TrackInfoDialog(selection, clicked_track->getIdent(),
|
||||
translations->fribidize(clicked_track->getName()),
|
||||
screenshot, 0.8f, 0.7f);
|
||||
} // if clicked_track
|
||||
|
||||
std::string track = m_random_track_list.front();
|
||||
m_random_track_list.pop_front();
|
||||
m_random_track_list.push_back(track);
|
||||
Track* clickedTrack = track_manager->getTrack( track );
|
||||
|
||||
|
||||
if (clickedTrack != NULL)
|
||||
{
|
||||
ITexture* screenshot =
|
||||
irr_driver->getTexture( clickedTrack->getScreenshotFile(),
|
||||
"While loading screenshot for track '%s':",
|
||||
clickedTrack->getFilename() );
|
||||
|
||||
new TrackInfoDialog(selection, clickedTrack->getIdent(),
|
||||
translations->fribidize(clickedTrack->getName()),
|
||||
screenshot, 0.8f, 0.7f);
|
||||
}
|
||||
|
||||
}
|
||||
else if (selection == "locked")
|
||||
} // selection=="random_track"
|
||||
else if (selection == "locked")
|
||||
{
|
||||
unlock_manager->playLockSound();
|
||||
}
|
||||
else if (selection == RibbonWidget::NO_ITEM_ID)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
Track* clicked_track = track_manager->getTrack(selection);
|
||||
if (clicked_track)
|
||||
{
|
||||
unlock_manager->playLockSound();
|
||||
}
|
||||
else if (selection == RibbonWidget::NO_ITEM_ID)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
Track* clickedTrack = track_manager->getTrack(selection);
|
||||
if (clickedTrack != NULL)
|
||||
{
|
||||
ITexture* screenshot =
|
||||
irr_driver->getTexture( clickedTrack->getScreenshotFile(),
|
||||
"While loading screenshot for track '%s'",
|
||||
clickedTrack->getFilename());
|
||||
ITexture* screenshot =
|
||||
irr_driver->getTexture(clicked_track->getScreenshotFile(),
|
||||
"While loading screenshot for track '%s'",
|
||||
clicked_track->getFilename());
|
||||
|
||||
new TrackInfoDialog(selection, clickedTrack->getIdent(),
|
||||
translations->fribidize(clickedTrack->getName()),
|
||||
screenshot, 0.8f, 0.7f);
|
||||
}
|
||||
new TrackInfoDialog(selection, clicked_track->getIdent(),
|
||||
translations->fribidize(clicked_track->getName()),
|
||||
screenshot, 0.8f, 0.7f);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // name=="tracks"
|
||||
else if (name == "gps")
|
||||
{
|
||||
DynamicRibbonWidget* gps_widget = dynamic_cast<DynamicRibbonWidget*>(widget);
|
||||
if (gps_widget != NULL)
|
||||
if (gps_widget)
|
||||
{
|
||||
std::string selection = gps_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
const std::string &selection =
|
||||
gps_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
if (selection == "locked")
|
||||
{
|
||||
@ -143,11 +147,11 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name, const
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
} // name=="gps"
|
||||
else if (name == "trackgroups")
|
||||
{
|
||||
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs != NULL );
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs );
|
||||
UserConfigParams::m_last_used_track_group = tabs->getSelectionIDString(0);
|
||||
buildTrackList();
|
||||
}
|
||||
@ -155,7 +159,7 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name, const
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
}
|
||||
}
|
||||
} // eventCallback
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@ -163,8 +167,8 @@ void TracksScreen::beforeAddingWidget()
|
||||
{
|
||||
Screen::init();
|
||||
// Dynamically add tabs
|
||||
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs != NULL );
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs );
|
||||
|
||||
tabs->clearAllChildren();
|
||||
|
||||
@ -191,20 +195,20 @@ void TracksScreen::beforeAddingWidget()
|
||||
tabs->addTextChild( _(groups[n].c_str()), groups[n] );
|
||||
}
|
||||
|
||||
DynamicRibbonWidget* tracks_widget = this->getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget != NULL );
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget );
|
||||
tracks_widget->setItemCountHint( track_manager->getNumberOfTracks()+1 );
|
||||
}
|
||||
} // beforeAddingWidget
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TracksScreen::init()
|
||||
{
|
||||
DynamicRibbonWidget* gps_widget = this->getWidget<DynamicRibbonWidget>("gps");
|
||||
assert( gps_widget != NULL );
|
||||
DynamicRibbonWidget* gps_widget = getWidget<DynamicRibbonWidget>("gps");
|
||||
assert( gps_widget );
|
||||
|
||||
DynamicRibbonWidget* tracks_widget = this->getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget != NULL );
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget );
|
||||
|
||||
// Reset GP list everytime (accounts for locking changes, etc.)
|
||||
gps_widget->clearItems();
|
||||
@ -221,10 +225,11 @@ void TracksScreen::init()
|
||||
for (unsigned int t=0; t<tracks.size(); t++)
|
||||
{
|
||||
Track* curr = track_manager->getTrack(tracks[t]);
|
||||
if (curr == NULL)
|
||||
if (!curr )
|
||||
{
|
||||
std::cerr << "/!\\ WARNING: Grand Prix '" << gp->getId() << "' refers to track '"
|
||||
<< tracks[t] << "', which does not exist.\n";
|
||||
Log::warn("TracksScreen", "Grand Prix '%s' refers to track '%s',"
|
||||
"which does not exist.",
|
||||
gp->getId().c_str(), tracks[t].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -233,20 +238,23 @@ void TracksScreen::init()
|
||||
}
|
||||
if (sshot_files.size() == 0)
|
||||
{
|
||||
std::cerr << "/!\\ WARNING: Grand Prix '" << gp->getId()
|
||||
<< "' does not contain any valid track.\n";
|
||||
Log::warn("TracksScreen",
|
||||
"Grand Prix '%s' does not contain any valid track.",
|
||||
gp->getId().c_str());
|
||||
sshot_files.push_back("gui/main_help.png");
|
||||
}
|
||||
|
||||
if (PlayerManager::getCurrentPlayer()->isLocked(gp->getId()))
|
||||
{
|
||||
gps_widget->addAnimatedItem(_("Locked!"),
|
||||
"locked", sshot_files, 1.5f, LOCKED_BADGE | TROPHY_BADGE,
|
||||
"locked", sshot_files, 1.5f,
|
||||
LOCKED_BADGE | TROPHY_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gps_widget->addAnimatedItem(translations->fribidize(gp->getName()), gp->getId(),
|
||||
gps_widget->addAnimatedItem(translations->fribidize(gp->getName()),
|
||||
gp->getId(),
|
||||
sshot_files, 1.5f, TROPHY_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
|
||||
}
|
||||
@ -254,8 +262,8 @@ void TracksScreen::init()
|
||||
gps_widget->updateItemDisplay();
|
||||
|
||||
|
||||
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs != NULL );
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs );
|
||||
tabs->select(UserConfigParams::m_last_used_track_group, PLAYER_ID_GAME_MASTER);
|
||||
|
||||
|
||||
@ -271,113 +279,95 @@ void TracksScreen::init()
|
||||
tracks_widget->setSelection(0, PLAYER_ID_GAME_MASTER, true);
|
||||
}
|
||||
irr_driver->unsetTextureErrorMessage();
|
||||
}
|
||||
} // init
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/** Rebuild the list of tracks and GPs. This need to be recomputed e.g. to
|
||||
* take unlocked tracks into account.
|
||||
*/
|
||||
void TracksScreen::buildTrackList()
|
||||
{
|
||||
DynamicRibbonWidget* tracks_widget = this->getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget != NULL );
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget);
|
||||
|
||||
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs != NULL );
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs );
|
||||
|
||||
// Reset track list everytime (accounts for locking changes, etc.)
|
||||
tracks_widget->clearItems();
|
||||
m_random_track_list.clear();
|
||||
|
||||
const std::string curr_group_name = tabs->getSelectionIDString(0);
|
||||
const std::string& curr_group_name = tabs->getSelectionIDString(0);
|
||||
|
||||
// Build track list
|
||||
if (curr_group_name == ALL_TRACK_GROUPS_ID)
|
||||
const int track_amount = track_manager->getNumberOfTracks();
|
||||
|
||||
// First build a list of all tracks to be displayed
|
||||
// (e.g. exclude arenas, ...)
|
||||
PtrVector<Track, REF> tracks;
|
||||
for (int n = 0; n < track_amount; n++)
|
||||
{
|
||||
const int trackAmount = track_manager->getNumberOfTracks();
|
||||
Track* curr = track_manager->getTrack(n);
|
||||
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_EASTER_EGG
|
||||
&& !curr->hasEasterEggs())
|
||||
continue;
|
||||
if (curr->isArena() || curr->isSoccer()||curr->isInternal()) continue;
|
||||
if (curr_group_name != ALL_TRACK_GROUPS_ID &&
|
||||
!curr->isInGroup(curr_group_name)) continue;
|
||||
|
||||
for (int n=0; n<trackAmount; n++)
|
||||
tracks.push_back(curr);
|
||||
} // for n<track_amount
|
||||
|
||||
tracks.insertionSort();
|
||||
for (unsigned int i = 0; i < tracks.size(); i++)
|
||||
{
|
||||
Track *curr = tracks.get(i);
|
||||
if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
|
||||
{
|
||||
Track* curr = track_manager->getTrack( n );
|
||||
if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_EASTER_EGG
|
||||
&& !curr->hasEasterEggs())
|
||||
continue;
|
||||
if (curr->isArena() || curr->isSoccer()) continue;
|
||||
if (curr->isInternal()) continue;
|
||||
|
||||
if(PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
|
||||
{
|
||||
tracks_widget->addItem( _("Locked : solve active challenges to gain access to more!"),
|
||||
"locked", curr->getScreenshotFile(), LOCKED_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
tracks_widget->addItem(translations->fribidize(curr->getName()), curr->getIdent(),
|
||||
curr->getScreenshotFile(), 0,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
|
||||
m_random_track_list.push_back(curr->getIdent());
|
||||
}
|
||||
tracks_widget->addItem(
|
||||
_("Locked : solve active challenges to gain access to more!"),
|
||||
"locked", curr->getScreenshotFile(), LOCKED_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::vector<int>& curr_group = track_manager->getTracksInGroup( curr_group_name );
|
||||
const int trackAmount = curr_group.size();
|
||||
|
||||
for (int n=0; n<trackAmount; n++)
|
||||
else
|
||||
{
|
||||
Track* curr = track_manager->getTrack( curr_group[n] );
|
||||
if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_EASTER_EGG
|
||||
&& !curr->hasEasterEggs())
|
||||
continue;
|
||||
if (curr->isArena()) continue;
|
||||
if (curr->isSoccer()) continue;
|
||||
if (curr->isInternal()) continue;
|
||||
|
||||
if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
|
||||
{
|
||||
tracks_widget->addItem( _("Locked : solve active challenges to gain access to more!"),
|
||||
"locked", curr->getScreenshotFile(), LOCKED_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
tracks_widget->addItem(translations->fribidize(curr->getName()), curr->getIdent(),
|
||||
curr->getScreenshotFile(), 0 /* no badge */,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
|
||||
m_random_track_list.push_back(curr->getIdent());
|
||||
}
|
||||
tracks_widget->addItem(translations->fribidize(curr->getName()),
|
||||
curr->getIdent(),
|
||||
curr->getScreenshotFile(), 0,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
m_random_track_list.push_back(curr->getIdent());
|
||||
}
|
||||
}
|
||||
|
||||
tracks_widget->addItem(_("Random Track"), "random_track", "/gui/track_random.png",
|
||||
0 /* no badge */, IconButtonWidget::ICON_PATH_TYPE_RELATIVE);
|
||||
tracks_widget->addItem(_("Random Track"), "random_track",
|
||||
"/gui/track_random.png", 0 /* no badge */,
|
||||
IconButtonWidget::ICON_PATH_TYPE_RELATIVE);
|
||||
|
||||
tracks_widget->updateItemDisplay();
|
||||
std::random_shuffle( m_random_track_list.begin(), m_random_track_list.end() );
|
||||
}
|
||||
} // buildTrackList
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TracksScreen::setFocusOnTrack(const std::string& trackName)
|
||||
{
|
||||
DynamicRibbonWidget* tracks_widget = this->getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget != NULL );
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget);
|
||||
|
||||
// only the game master can select tracks, so it's safe to use 'PLAYER_ID_GAME_MASTER'
|
||||
// only the game master can select tracks,
|
||||
// so it's safe to use 'PLAYER_ID_GAME_MASTER'
|
||||
tracks_widget->setSelection(trackName, PLAYER_ID_GAME_MASTER, true);
|
||||
}
|
||||
} // setFocusOnTrack
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TracksScreen::setFocusOnGP(const std::string& gpName)
|
||||
{
|
||||
DynamicRibbonWidget* gps_widget = this->getWidget<DynamicRibbonWidget>("gps");
|
||||
assert( gps_widget != NULL );
|
||||
DynamicRibbonWidget* gps_widget = getWidget<DynamicRibbonWidget>("gps");
|
||||
assert( gps_widget );
|
||||
|
||||
// only the game master can select tracks/GPs, so it's safe to use 'PLAYER_ID_GAME_MASTER'
|
||||
// only the game master can select tracks/GPs,
|
||||
// so it's safe to use 'PLAYER_ID_GAME_MASTER'
|
||||
gps_widget->setSelection(gpName, PLAYER_ID_GAME_MASTER, true);
|
||||
}
|
||||
} // setFocusOnGP
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
618
src/states_screens/user_screen.cpp
Normal file
618
src/states_screens/user_screen.cpp
Normal file
@ -0,0 +1,618 @@
|
||||
// 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);
|
||||
|
||||
getWidget<CheckBoxWidget>("remember-user")
|
||||
->setState(UserConfigParams::m_always_show_login_screen);
|
||||
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);
|
||||
getWidget<LabelWidget>("label_remember")->setVisible(online);
|
||||
getWidget<CheckBoxWidget>("remember-user")->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 == "remember-user")
|
||||
{
|
||||
UserConfigParams::m_remember_user =
|
||||
getWidget<CheckBoxWidget>("remember-user")->getState();
|
||||
}
|
||||
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
|
@ -73,6 +73,7 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <wchar.h>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
@ -152,6 +153,69 @@ Track::~Track()
|
||||
#endif
|
||||
} // ~Track
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** A < comparison of tracks. This is used to sort the tracks when displaying
|
||||
* them in the gui.
|
||||
*/
|
||||
bool Track::operator<(const Track &other) const
|
||||
{
|
||||
PlayerProfile *p = PlayerManager::getCurrentPlayer();
|
||||
bool this_is_locked = p->isLocked(getIdent());
|
||||
bool other_is_locked = p->isLocked(other.getIdent());
|
||||
if(this_is_locked == other_is_locked)
|
||||
{
|
||||
return getSortName() < other.getSortName();
|
||||
}
|
||||
else
|
||||
return other_is_locked;
|
||||
} // operator<
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the name of the track, which is e.g. displayed on the screen.
|
||||
\note this is the LTR name, invoke fribidi as needed. */
|
||||
core::stringw Track::getName() const
|
||||
{
|
||||
core::stringw translated = translations->w_gettext(m_name.c_str());
|
||||
int index = translated.find("|");
|
||||
if(index>-1)
|
||||
{
|
||||
translated = translated.subString(0, index);
|
||||
}
|
||||
return translated;
|
||||
} // getName
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the name of the track used to sort the tracks alphabetically.
|
||||
* This can be used to e.g. sort 'The Island' as 'Island,The'; or
|
||||
* to replace certain language-specific characters (e.g. German 'ae' with 'a')
|
||||
* The sort name can be specified by setting the name of a track to:
|
||||
* "normal name|sort name"
|
||||
*/
|
||||
core::stringw Track::getSortName() const
|
||||
{
|
||||
core::stringw translated = translations->w_gettext(m_name.c_str());
|
||||
translated.make_lower();
|
||||
int index = translated.find("|");
|
||||
if(index>-1)
|
||||
{
|
||||
translated = translated.subString(index+1, translated.size());
|
||||
}
|
||||
return translated;
|
||||
} // getSortName
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns true if this track belongs to the specified track group.
|
||||
* \param group_name Group name to test for.
|
||||
*/
|
||||
bool Track::isInGroup(const std::string &group_name)
|
||||
{
|
||||
for(unsigned int i=0; i<m_groups.size(); i++)
|
||||
{
|
||||
if(m_groups[i]==group_name) return true;
|
||||
}
|
||||
return false;
|
||||
} // isInGroup
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns number of completed challenges */
|
||||
unsigned int Track::getNumOfCompletedChallenges()
|
||||
@ -362,7 +426,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;
|
||||
|
@ -350,6 +350,9 @@ private:
|
||||
/** Name of the track to display. */
|
||||
std::string m_name;
|
||||
|
||||
/** The name used in sorting the track. */
|
||||
core::stringw m_sort_name;
|
||||
|
||||
bool m_use_fog;
|
||||
/** True if this track supports using smoothed normals. */
|
||||
bool m_smooth_normals;
|
||||
@ -428,6 +431,11 @@ public:
|
||||
void adjustForFog(scene::IMesh* mesh,
|
||||
scene::ISceneNode* parent_scene_node);
|
||||
void itemCommand(const XMLNode *node);
|
||||
core::stringw getName() const;
|
||||
core::stringw getSortName() const;
|
||||
// ------------------------------------------------------------------------
|
||||
bool isInGroup(const std::string &group_name);
|
||||
// ------------------------------------------------------------------------
|
||||
const core::vector3df& getSunRotation();
|
||||
/** Sets the current ambient color for a kart with index k. */
|
||||
void setAmbientColor(const video::SColor &color,
|
||||
@ -472,11 +480,6 @@ public:
|
||||
/** Returns a unique identifier for this track (the directory name). */
|
||||
const std::string& getIdent () const {return m_ident; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the name of the track, which is e.g. displayed on the screen.
|
||||
\note this is the LTR name, invoke fribidi as needed. */
|
||||
const wchar_t* getName () const
|
||||
{return translations->w_gettext(m_name.c_str()); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns all groups this track belongs to. */
|
||||
const std::vector<std::string>&
|
||||
getGroups () const {return m_groups; }
|
||||
@ -612,6 +615,7 @@ public:
|
||||
|
||||
float getDisplacementSpeed() const { return m_displacement_speed; }
|
||||
float getCausticsSpeed() const { return m_caustics_speed; }
|
||||
bool operator<(const Track &other) const;
|
||||
}; // class Track
|
||||
|
||||
#endif
|
||||
|
@ -698,7 +698,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
|
||||
@ -54,6 +54,9 @@ enum DebugMenuCommand
|
||||
DEBUG_GRAPHICS_MIPMAP_VIZ,
|
||||
DEBUG_GRAPHICS_NORMALS_VIZ,
|
||||
DEBUG_GRAPHICS_SSAO_VIZ,
|
||||
DEBUG_GRAPHICS_RSM_VIZ,
|
||||
DEBUG_GRAPHICS_RH_VIZ,
|
||||
DEBUG_GRAPHICS_GI_VIZ,
|
||||
DEBUG_GRAPHICS_SHADOW_VIZ,
|
||||
DEBUG_GRAPHICS_LIGHT_VIZ,
|
||||
DEBUG_GRAPHICS_DISTORT_VIZ,
|
||||
@ -83,7 +86,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 +99,7 @@ void addPowerup(PowerupManager::PowerupType powerup)
|
||||
kart->setPowerup(powerup, 10000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void addAttachment(Attachment::AttachmentType type)
|
||||
{
|
||||
@ -136,7 +139,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,22 +150,25 @@ 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 );
|
||||
sub->addItem(L"Mipmap viz", DEBUG_GRAPHICS_MIPMAP_VIZ );
|
||||
sub->addItem(L"Normals viz", DEBUG_GRAPHICS_NORMALS_VIZ );
|
||||
sub->addItem(L"SSAO viz", DEBUG_GRAPHICS_SSAO_VIZ );
|
||||
sub->addItem(L"RSM viz", DEBUG_GRAPHICS_RSM_VIZ);
|
||||
sub->addItem(L"RH viz", DEBUG_GRAPHICS_RH_VIZ);
|
||||
sub->addItem(L"GI viz", DEBUG_GRAPHICS_GI_VIZ);
|
||||
sub->addItem(L"Shadow viz", DEBUG_GRAPHICS_SHADOW_VIZ );
|
||||
sub->addItem(L"Light viz", DEBUG_GRAPHICS_LIGHT_VIZ );
|
||||
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 +181,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 +189,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 +202,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 +236,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 +251,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 +259,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,15 +267,39 @@ bool onEvent(const SEvent &event)
|
||||
{
|
||||
World* world = World::getWorld();
|
||||
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleSSAOViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_RSM_VIZ)
|
||||
{
|
||||
World* world = World::getWorld();
|
||||
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleRSM();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_RH_VIZ)
|
||||
{
|
||||
World* world = World::getWorld();
|
||||
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleRH();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_GI_VIZ)
|
||||
{
|
||||
World* world = World::getWorld();
|
||||
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleGI();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_SHADOW_VIZ)
|
||||
{
|
||||
World* world = World::getWorld();
|
||||
if (world != NULL) world->getPhysics()->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleShadowViz();
|
||||
}
|
||||
@ -277,7 +307,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 +315,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 +330,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 +447,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),
|
||||
|
@ -277,7 +277,7 @@ public:
|
||||
{
|
||||
for(int j=(int)start; j<(int)m_contents_vector.size()-1; j++)
|
||||
{
|
||||
if(*(m_contents_vector[j])>*(m_contents_vector[j+1])) continue;
|
||||
if(*(m_contents_vector[j+1])<*(m_contents_vector[j])) continue;
|
||||
// Now search the proper place for m_contents_vector[j+1]
|
||||
// in the sorted section contentsVectot[start:j]
|
||||
TYPE* t=m_contents_vector[j+1];
|
||||
@ -286,7 +286,7 @@ public:
|
||||
{
|
||||
m_contents_vector[i] = m_contents_vector[i-1];
|
||||
i--;
|
||||
} while (i>start && *t>*(m_contents_vector[i-1]));
|
||||
} while (i>start && *(m_contents_vector[i-1]) <*t);
|
||||
m_contents_vector[i]=t;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user