[Orxonox-commit 3392] r8079 - in code/trunk: . cmake/tools data/defaultConfig data/gui/configs data/gui/layouts data/gui/schemes data/gui/scripts data/levels data/overlays src src/external/enet src/libraries/core src/libraries/core/command src/libraries/core/input src/libraries/network src/libraries/tools src/modules/designtools src/modules/notifications src/modules/objects/triggers src/modules/overlays src/modules/overlays/hud src/modules/pickup src/modules/questsystem src/modules/questsystem/effects src/orxonox src/orxonox/controllers src/orxonox/gamestates src/orxonox/gametypes src/orxonox/graphics src/orxonox/items src/orxonox/overlays src/orxonox/sound

landauf at orxonox.net landauf at orxonox.net
Tue Mar 15 21:47:11 CET 2011


Author: landauf
Date: 2011-03-15 21:47:11 +0100 (Tue, 15 Mar 2011)
New Revision: 8079

Added:
   code/trunk/src/libraries/core/ViewportEventListener.cc
   code/trunk/src/libraries/core/ViewportEventListener.h
   code/trunk/src/modules/overlays/hud/PauseNotice.cc
   code/trunk/src/modules/overlays/hud/PauseNotice.h
Modified:
   code/trunk/
   code/trunk/cmake/tools/TargetUtilities.cmake
   code/trunk/data/defaultConfig/keybindings.ini
   code/trunk/data/gui/configs/CEGUIConfig.xsd
   code/trunk/data/gui/layouts/GraphicsMenu.layout
   code/trunk/data/gui/schemes/GUIScheme.xsd
   code/trunk/data/gui/schemes/OrxonoxLook.scheme
   code/trunk/data/gui/schemes/TaharezGreenLook.scheme
   code/trunk/data/gui/schemes/TaharezLook.scheme
   code/trunk/data/gui/scripts/AudioMenu.lua
   code/trunk/data/gui/scripts/ControlsMenu.lua
   code/trunk/data/gui/scripts/CreditsMenu.lua
   code/trunk/data/gui/scripts/DecisionPopup.lua
   code/trunk/data/gui/scripts/GUISheet.lua
   code/trunk/data/gui/scripts/GUITools.lua
   code/trunk/data/gui/scripts/GraphicsMenu.lua
   code/trunk/data/gui/scripts/HostMenu.lua
   code/trunk/data/gui/scripts/InGameMenu.lua
   code/trunk/data/gui/scripts/KeyBindMenu.lua
   code/trunk/data/gui/scripts/MainMenu.lua
   code/trunk/data/gui/scripts/MiscConfigMenu.lua
   code/trunk/data/gui/scripts/MouseControlsMenu.lua
   code/trunk/data/gui/scripts/MultiplayerMenu.lua
   code/trunk/data/gui/scripts/NotificationLayer.lua
   code/trunk/data/gui/scripts/SettingsMenu.lua
   code/trunk/data/gui/scripts/SheetManager.lua
   code/trunk/data/gui/scripts/SingleplayerMenu.lua
   code/trunk/data/levels/FPSTest.oxw
   code/trunk/data/levels/asteroids.oxw
   code/trunk/data/levels/dynamicMatch.oxw
   code/trunk/data/levels/fightInOurBack.oxw
   code/trunk/data/levels/lastManStanding.oxw
   code/trunk/data/levels/presentation09.oxw
   code/trunk/data/levels/presentation09b.oxw
   code/trunk/data/levels/presentationDM.oxw
   code/trunk/data/levels/presentationFS102.oxw
   code/trunk/data/levels/presentationFS10Ed.oxw
   code/trunk/data/levels/presentationHS09.oxw
   code/trunk/data/levels/presentationHS09b.oxw
   code/trunk/data/levels/teamBaseMatch.oxw
   code/trunk/data/levels/testSwallow.oxw
   code/trunk/data/levels/underAttack.oxw
   code/trunk/data/overlays/debug.oxo
   code/trunk/src/CMakeLists.txt
   code/trunk/src/external/enet/win32.c
   code/trunk/src/libraries/core/CMakeLists.txt
   code/trunk/src/libraries/core/Core.cc
   code/trunk/src/libraries/core/Core.h
   code/trunk/src/libraries/core/CorePrereqs.h
   code/trunk/src/libraries/core/GUIManager.cc
   code/trunk/src/libraries/core/GUIManager.h
   code/trunk/src/libraries/core/Game.cc
   code/trunk/src/libraries/core/GraphicsManager.cc
   code/trunk/src/libraries/core/GraphicsManager.h
   code/trunk/src/libraries/core/Loader.cc
   code/trunk/src/libraries/core/Loader.h
   code/trunk/src/libraries/core/OrxonoxClass.h
   code/trunk/src/libraries/core/WeakPtr.h
   code/trunk/src/libraries/core/command/CommandEvaluation.h
   code/trunk/src/libraries/core/command/ConsoleCommand.h
   code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc
   code/trunk/src/libraries/core/command/Shell.cc
   code/trunk/src/libraries/core/command/TclBind.cc
   code/trunk/src/libraries/core/command/TclBind.h
   code/trunk/src/libraries/core/command/TclThreadManager.cc
   code/trunk/src/libraries/core/input/InputManager.cc
   code/trunk/src/libraries/core/input/InputManager.h
   code/trunk/src/libraries/core/input/KeyBinder.cc
   code/trunk/src/libraries/core/input/Keyboard.cc
   code/trunk/src/libraries/core/input/Keyboard.h
   code/trunk/src/libraries/network/Host.cc
   code/trunk/src/libraries/tools/ResourceLocation.cc
   code/trunk/src/libraries/tools/Shader.cc
   code/trunk/src/libraries/tools/Shader.h
   code/trunk/src/libraries/tools/Timer.cc
   code/trunk/src/libraries/tools/Timer.h
   code/trunk/src/libraries/tools/ToolsPrereqs.h
   code/trunk/src/modules/designtools/ScreenshotManager.cc
   code/trunk/src/modules/designtools/ScreenshotManager.h
   code/trunk/src/modules/designtools/SkyboxGenerator.cc
   code/trunk/src/modules/notifications/NotificationManager.cc
   code/trunk/src/modules/notifications/NotificationQueue.cc
   code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc
   code/trunk/src/modules/objects/triggers/DistanceTrigger.cc
   code/trunk/src/modules/objects/triggers/DistanceTrigger.h
   code/trunk/src/modules/overlays/OverlaysPrereqs.h
   code/trunk/src/modules/overlays/hud/CMakeLists.txt
   code/trunk/src/modules/pickup/PickupRepresentation.cc
   code/trunk/src/modules/questsystem/QuestItem.cc
   code/trunk/src/modules/questsystem/QuestManager.cc
   code/trunk/src/modules/questsystem/effects/AddQuestHint.cc
   code/trunk/src/modules/questsystem/effects/ChangeQuestStatus.cc
   code/trunk/src/orxonox/CameraManager.cc
   code/trunk/src/orxonox/CameraManager.h
   code/trunk/src/orxonox/ChatInputHandler.cc
   code/trunk/src/orxonox/ChatInputHandler.h
   code/trunk/src/orxonox/LevelInfo.h
   code/trunk/src/orxonox/LevelManager.cc
   code/trunk/src/orxonox/LevelManager.h
   code/trunk/src/orxonox/controllers/HumanController.cc
   code/trunk/src/orxonox/controllers/HumanController.h
   code/trunk/src/orxonox/gamestates/GSLevel.cc
   code/trunk/src/orxonox/gamestates/GSMainMenu.cc
   code/trunk/src/orxonox/gamestates/GSMainMenu.h
   code/trunk/src/orxonox/gamestates/GSRoot.cc
   code/trunk/src/orxonox/gamestates/GSRoot.h
   code/trunk/src/orxonox/gametypes/Gametype.cc
   code/trunk/src/orxonox/graphics/Camera.cc
   code/trunk/src/orxonox/graphics/Camera.h
   code/trunk/src/orxonox/graphics/GlobalShader.cc
   code/trunk/src/orxonox/graphics/GlobalShader.h
   code/trunk/src/orxonox/graphics/Model.cc
   code/trunk/src/orxonox/items/Engine.cc
   code/trunk/src/orxonox/items/Engine.h
   code/trunk/src/orxonox/overlays/InGameConsole.cc
   code/trunk/src/orxonox/sound/AmbientSound.cc
Log:
merged usability branch back to trunk

incomplete summary of the changes in this branch:
 - enhanced keyboard navigation in GUIs
 - implemented new graphics menu and changeable window size at runtime
 - added developer mode
 - HUD shows if game is paused, game pauses if ingame menu is opened
 - removed a few obsolete commands and hid some that are more for internal use
 - numpad works in console and gui
 - faster loading of level info
 - enhanced usage of compositors (Shader class)
 - improved camera handling, configurable FOV and aspect ratio


Property changes on: code/trunk
___________________________________________________________________
Modified: svn:mergeinfo
   - /code/branches/ai:6592-7033
/code/branches/buildsystem:1874-2276,2278-2400
/code/branches/buildsystem2:2506-2658
/code/branches/buildsystem3:2662-2708
/code/branches/ceguilua:1802-1808
/code/branches/chat:6527-6797
/code/branches/chat2:6836-6910
/code/branches/console:5941-6104
/code/branches/consolecommands2:6451-7178
/code/branches/consolecommands3:7178-7283
/code/branches/core3:1572-1739
/code/branches/core4:3221-3224,3227,3234-3238,3242,3244-3250,3252-3254,3256,3259-3261,3264-3265,3268-3275,3277-3278,3280,3284-3285,3287,3289-3294,3305,3309-3310
/code/branches/core5:5768-5928,6009
/code/branches/data_cleanup:7537-7686
/code/branches/doc:7290-7400
/code/branches/dynamicmatch:6584-7030
/code/branches/fps:6591-7072
/code/branches/gamestate:6430-6572,6621-6661
/code/branches/gamestates2:6594-6745
/code/branches/gametypes:2826-3031
/code/branches/gcc43:1580
/code/branches/gui:1635-1723,2795-2894
/code/branches/hudelements:6584-6941
/code/branches/ingamemenu:6000-6023
/code/branches/input:1629-1636
/code/branches/ipv6:7293-7458
/code/branches/lastmanstanding:7479-7644
/code/branches/libraries:5612-5692
/code/branches/libraries2:5703-5737
/code/branches/lod:6586-6911
/code/branches/lodfinal:2372-2411
/code/branches/map:2801-3086,3089
/code/branches/masterserver:7502-7738
/code/branches/menu:5941-6146,6148,7536-7687
/code/branches/miniprojects:2754-2824
/code/branches/netp2:2835-2988
/code/branches/netp3:2988-3082
/code/branches/netp6:3214-3302
/code/branches/network:2356
/code/branches/network2:6434-6465
/code/branches/network3:7196-7344
/code/branches/network4:7497-7755
/code/branches/network5:7757-7781
/code/branches/network64:2210-2355
/code/branches/notifications:7314-7401
/code/branches/objecthierarchy:1911-2085,2100,2110-2169
/code/branches/objecthierarchy2:2171-2479
/code/branches/overlay:2117-2385
/code/branches/particles:2829-3085
/code/branches/particles2:6050-6106,6109
/code/branches/pch:3113-3194
/code/branches/physics:1912-2055,2107-2439
/code/branches/physics_merge:2436-2457
/code/branches/pickup2:5942-6405
/code/branches/pickup3:6418-6523
/code/branches/pickup4:6594-6710
/code/branches/pickups:1926-2086,2127,2827-2915
/code/branches/pickups2:2107-2497,2915-3071
/code/branches/png2:7262-7263
/code/branches/ppspickups1:6552-6708
/code/branches/ppspickups2:6527-6532,6554-6709
/code/branches/ppspickups3:6757-6997
/code/branches/ppspickups4:7003-7089
/code/branches/presentation:2369-2652,2654-2660,7736-7786
/code/branches/presentation2:6106-6416,7787-7800
/code/branches/presentation3:6913-7162
/code/branches/questsystem:1894-2088
/code/branches/questsystem2:2107-2259
/code/branches/questsystem5:2776-2905
/code/branches/releasetodo:7614-7647
/code/branches/resource:3327-3366
/code/branches/resource2:3372-5694
/code/branches/rocket:6523-6950
/code/branches/rocket2:6953-6970
/code/branches/script_trigger:1295-1953,1955
/code/branches/skybox2:6559-6989
/code/branches/sound:2829-3010
/code/branches/sound3:5941-6102
/code/branches/steering:5949-6091
/code/branches/weapon:1925-2094
/code/branches/weapon2:2107-2488
/code/branches/weapons:2897-3051
/code/branches/weaponsystem:2742-2890
   + /code/branches/ai:6592-7033
/code/branches/buildsystem:1874-2276,2278-2400
/code/branches/buildsystem2:2506-2658
/code/branches/buildsystem3:2662-2708
/code/branches/ceguilua:1802-1808
/code/branches/chat:6527-6797
/code/branches/chat2:6836-6910
/code/branches/console:5941-6104
/code/branches/consolecommands2:6451-7178
/code/branches/consolecommands3:7178-7283
/code/branches/core3:1572-1739
/code/branches/core4:3221-3224,3227,3234-3238,3242,3244-3250,3252-3254,3256,3259-3261,3264-3265,3268-3275,3277-3278,3280,3284-3285,3287,3289-3294,3305,3309-3310
/code/branches/core5:5768-5928,6009
/code/branches/data_cleanup:7537-7686
/code/branches/doc:7290-7400
/code/branches/dynamicmatch:6584-7030
/code/branches/fps:6591-7072
/code/branches/gamestate:6430-6572,6621-6661
/code/branches/gamestates2:6594-6745
/code/branches/gametypes:2826-3031
/code/branches/gcc43:1580
/code/branches/gui:1635-1723,2795-2894
/code/branches/hudelements:6584-6941
/code/branches/ingamemenu:6000-6023
/code/branches/input:1629-1636
/code/branches/ipv6:7293-7458
/code/branches/kicklib:7975-7977
/code/branches/lastmanstanding:7479-7644
/code/branches/libraries:5612-5692
/code/branches/libraries2:5703-5737
/code/branches/lod:6586-6911
/code/branches/lodfinal:2372-2411
/code/branches/map:2801-3086,3089
/code/branches/masterserver:7502-7738
/code/branches/menu:5941-6146,6148,7536-7687
/code/branches/miniprojects:2754-2824
/code/branches/netp2:2835-2988
/code/branches/netp3:2988-3082
/code/branches/netp6:3214-3302
/code/branches/network:2356
/code/branches/network2:6434-6465
/code/branches/network3:7196-7344
/code/branches/network4:7497-7755
/code/branches/network5:7757-7781
/code/branches/network64:2210-2355
/code/branches/notifications:7314-7401
/code/branches/objecthierarchy:1911-2085,2100,2110-2169
/code/branches/objecthierarchy2:2171-2479
/code/branches/overlay:2117-2385
/code/branches/particles:2829-3085
/code/branches/particles2:6050-6106,6109
/code/branches/pch:3113-3194
/code/branches/physics:1912-2055,2107-2439
/code/branches/physics_merge:2436-2457
/code/branches/pickup2:5942-6405
/code/branches/pickup3:6418-6523
/code/branches/pickup4:6594-6710
/code/branches/pickups:1926-2086,2127,2827-2915
/code/branches/pickups2:2107-2497,2915-3071
/code/branches/png2:7262-7263
/code/branches/ppspickups1:6552-6708
/code/branches/ppspickups2:6527-6532,6554-6709
/code/branches/ppspickups3:6757-6997
/code/branches/ppspickups4:7003-7089
/code/branches/presentation:2369-2652,2654-2660,7736-7786
/code/branches/presentation2:6106-6416,7787-7800
/code/branches/presentation3:6913-7162
/code/branches/questsystem:1894-2088
/code/branches/questsystem2:2107-2259
/code/branches/questsystem5:2776-2905
/code/branches/releasetodo:7614-7647
/code/branches/resource:3327-3366
/code/branches/resource2:3372-5694
/code/branches/rocket:6523-6950
/code/branches/rocket2:6953-6970
/code/branches/script_trigger:1295-1953,1955
/code/branches/skybox2:6559-6989
/code/branches/sound:2829-3010
/code/branches/sound3:5941-6102
/code/branches/steering:5949-6091
/code/branches/usability:7915-8078
/code/branches/weapon:1925-2094
/code/branches/weapon2:2107-2488
/code/branches/weapons:2897-3051
/code/branches/weaponsystem:2742-2890

Modified: code/trunk/cmake/tools/TargetUtilities.cmake
===================================================================
--- code/trunk/cmake/tools/TargetUtilities.cmake	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/cmake/tools/TargetUtilities.cmake	2011-03-15 20:47:11 UTC (rev 8079)
@@ -265,7 +265,7 @@
     )
     ADD_MODULE(${_target_name})
     # Ensure that the main program depends on the module
-    SET(ORXONOX_MODULES ${ORXONOX_MODULES} ${_target_name} CACHE STRING "" FORCE)
+    SET(ORXONOX_MODULES ${ORXONOX_MODULES} ${_target_name} CACHE INTERNAL "")
   ENDIF()
 
   # Static library flags are not globally available

Modified: code/trunk/data/defaultConfig/keybindings.ini
===================================================================
--- code/trunk/data/defaultConfig/keybindings.ini	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/defaultConfig/keybindings.ini	2011-03-15 20:47:11 UTC (rev 8079)
@@ -41,7 +41,7 @@
 KeyF8=
 KeyF9=
 KeyG=greet
-KeyGrave="openConsole"
+KeyGrave="InGameConsole openConsole"
 KeyH=
 KeyHome=
 KeyI=
@@ -126,7 +126,7 @@
 KeyTab="NewHumanController changeMode"
 KeyU=""
 KeyUP="scale 1 moveFrontBack"
-KeyUnassigned="openConsole"
+KeyUnassigned="InGameConsole openConsole"
 KeyUnderline=
 KeyUnlabeled=
 KeyV=

Modified: code/trunk/data/gui/configs/CEGUIConfig.xsd
===================================================================
--- code/trunk/data/gui/configs/CEGUIConfig.xsd	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/configs/CEGUIConfig.xsd	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
 
-	<xsd:element name="CEGUIConfig" type="CEGUIConfigType"/>
+    <xsd:element name="CEGUIConfig" type="CEGUIConfigType"/>
 
     <xsd:simpleType name="LogLevel">
         <xsd:restriction base="xsd:string">
@@ -11,18 +11,18 @@
             <xsd:enumeration value="Insane"/>
         </xsd:restriction>
     </xsd:simpleType>
-    
-	<xsd:complexType name="CEGUIConfigType">
-		<xsd:attribute name="Logfile" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="Scheme" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="DefaultFont" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="Layout" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="InitScript" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="TerminateScript" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="DefaultResourceGroup" type="xsd:string" use="optional"  default="" />
+
+    <xsd:complexType name="CEGUIConfigType">
+        <xsd:attribute name="Logfile" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="Scheme" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="DefaultFont" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="Layout" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="InitScript" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="TerminateScript" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="DefaultResourceGroup" type="xsd:string" use="optional"  default="" />
         <xsd:attribute name="LoggingLevel" type="LogLevel" use="optional"  default="Standard" />
-	</xsd:complexType>
-	
+    </xsd:complexType>
+
 </xsd:schema>
 
 

Modified: code/trunk/data/gui/layouts/GraphicsMenu.layout
===================================================================
--- code/trunk/data/gui/layouts/GraphicsMenu.layout	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/layouts/GraphicsMenu.layout	2011-03-15 20:47:11 UTC (rev 8079)
@@ -14,78 +14,196 @@
             <Property Name="HorzFormatting" Value="HorzCentred" />
             <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
             <Property Name="VertFormatting" Value="TopAligned" />
-            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.2,0},{0.75,0},{0.6375,0}}" />
-            <Window Type="MenuWidgets/StaticText" Name="orxonox/Resolution" >
-                <Property Name="Text" Value="Resolution" />
-                <Property Name="InheritsAlpha" Value="False" />
-                <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.15,0},{0.75,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/TabControl" Name="orxonox/GraphicsTabControl" >
+                <Property Name="TabHeight" Value="{0,26.4388}" />
                 <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                <Property Name="VertFormatting" Value="TopAligned" />
-                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.10,0},{0.475,0},{0.65,0}}" />
-                <Window Type="MenuWidgets/Listbox" Name="orxonox/ResolutionListbox" >
+                <Property Name="TabPanePosition" Value="Top" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.1,0},{0.95,0},{0.925,0}}" />
+                <Window Type="DefaultWindow" Name="orxonox/Display" >
+                    <Property Name="Text" Value="Display" />
                     <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                    <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.2,0},{0.95,0},{0.95,0}}" />
-                    <Event Name="ItemSelectionChanged" Function="GraphicsMenu.GraphicsResolutionListbox_changed"/>
+                    <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/Resolution" >
+                        <Property Name="Text" Value="Resolution" />
+                        <Property Name="HorzFormatting" Value="HorzCentred" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="VertFormatting" Value="TopAligned" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.025,0},{0.035,0},{0.4875,0},{0.96,0}}" />
+                        <Window Type="MenuWidgets/Checkbox" Name="orxonox/Display/Resolution/Fullscreen" >
+                            <Property Name="Text" Value="Fullscreen" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.15,0},{0.95,0},{0.27,0}}" />
+                            <Event Name="CheckStateChanged" Function="GraphicsMenu.callback_FullscreenCheckbox_CheckStateChanged" />
+                        </Window>
+                        <Window Type="MenuWidgets/Combobox" Name="orxonox/Display/Resolution/Combobox" >
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="ClippedByParent" Value="False" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.3,0},{0.95,0},{1.2,0}}" />
+                            <Property Name="MaxEditTextLength" Value="1073741823" />
+                            <Event Name="ListSelectionAccepted" Function="GraphicsMenu.callback_ResolutionCombobox_ListSelectionAccepted" />
+                        </Window>
+                        <Window Type="MenuWidgets/Editbox" Name="orxonox/Display/Resolution/EditboxWidth" >
+                            <Property Name="MaxTextLength" Value="1073741823" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.45,0},{0.45,0},{0.57,0}}" />
+                            <Event Name="TextChanged" Function="GraphicsMenu.callback_ResolutionEditboxWidth_TextChanged" />
+                        </Window>
+                        <Window Type="MenuWidgets/Editbox" Name="orxonox/Display/Resolution/EditboxHeight" >
+                            <Property Name="MaxTextLength" Value="1073741823" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.55,0},{0.45,0},{0.95,0},{0.57,0}}" />
+                            <Event Name="TextChanged" Function="GraphicsMenu.callback_ResolutionEditboxHeight_TextChanged" />
+                        </Window>
+                        <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/Resolution/x" >
+                            <Property Name="Text" Value="x" />
+                            <Property Name="FrameEnabled" Value="False" />
+                            <Property Name="HorzFormatting" Value="HorzCentred" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.45,0},{0.45,0},{0.55,0},{0.57,0}}" />
+                            <Property Name="BackgroundEnabled" Value="False" />
+                        </Window>
+                        <Window Type="MenuWidgets/Button" Name="orxonox/Display/Resolution/Apply" >
+                            <Property Name="Text" Value="Apply" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.61,0},{0.75,0},{0.73,0}}" />
+                            <Event Name="Clicked" Function="GraphicsMenu.callback_Apply_Clicked" />
+                        </Window>
+                        <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/Resolution/AspectRatioLabel" >
+                            <Property Name="Text" Value="Aspect Ratio" />
+                            <Property Name="FrameEnabled" Value="False" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.825,0},{0.6,0},{0.95,0}}" />
+                            <Property Name="BackgroundEnabled" Value="False" />
+                        </Window>
+                        <Window Type="MenuWidgets/Editbox" Name="orxonox/Display/Resolution/AspectRatio" >
+                            <Property Name="Text" Value="1" />
+                            <Property Name="MaxTextLength" Value="1073741823" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.65,0},{0.825,0},{0.95,0},{0.95,0}}" />
+                        </Window>
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/Theme" >
+                        <Property Name="Text" Value="Theme" />
+                        <Property Name="HorzFormatting" Value="HorzCentred" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="VertFormatting" Value="TopAligned" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.035,0},{0.975,0},{0.32,0}}" />
+                        <Window Type="MenuWidgets/Combobox" Name="orxonox/Display/Theme/Combobox" >
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="ClippedByParent" Value="False" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.5,0},{0.95,0},{1.6,0}}" />
+                            <Property Name="MaxEditTextLength" Value="1073741823" />
+                            <Event Name="ListSelectionAccepted" Function="GraphicsMenu.callback_ThemeCombobox_ListSelectionAccepted" />
+                        </Window>
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/More" >
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.37,0},{0.975,0},{0.7,0}}" />
+                        <Window Type="MenuWidgets/Checkbox" Name="orxonox/Display/More/VSync" >
+                            <Property Name="Text" Value="VSync" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.1,0},{0.95,0},{0.45,0}}" />
+                            <Event Name="CheckStateChanged" Function="GraphicsMenu.callback_VSyncCheckbox_CheckStateChanged" />
+                        </Window>
+                        <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/More/FSAALabel" >
+                            <Property Name="Text" Value="FSAA" />
+                            <Property Name="FrameEnabled" Value="False" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.55,0},{0.3,0},{0.9,0}}" />
+                            <Property Name="BackgroundEnabled" Value="False" />
+                        </Window>
+                        <Window Type="MenuWidgets/Combobox" Name="orxonox/Display/More/FSAA" >
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="ClippedByParent" Value="False" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.3,0},{0.55,0},{0.95,0},{2.1,0}}" />
+                            <Property Name="MaxEditTextLength" Value="1073741823" />
+                            <Event Name="ListSelectionAccepted" Function="GraphicsMenu.callback_FSAACombobox_ListSelectionAccepted" />
+                        </Window>
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/Notice" >
+                        <Property Name="Font" Value="BlueHighway-12" />
+                        <Property Name="Text" >Changing the theme, FSAA,
+or VSync requires a restart</Property>
+                        <Property Name="HorzFormatting" Value="HorzCentred" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.75,0},{0.975,0},{0.96,0}}" />
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/NoticeRed" >
+                        <Property Name="Font" Value="BlueHighway-12" />
+                        <Property Name="Text" >Restart required</Property>
+                        <Property Name="TextColours" Value="tl:FFFF0000 tr:FFFF8888 bl:FFFF8888 br:FFFFFFFF" />
+                        <Property Name="HorzFormatting" Value="HorzCentred" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.75,0},{0.975,0},{0.96,0}}" />
+                    </Window>
                 </Window>
-            </Window>
-            <Window Type="MenuWidgets/StaticText" Name="orxonox/Themes" >
-                <Property Name="Text" Value="Themes" />
-                <Property Name="InheritsAlpha" Value="False" />
-                <Property Name="HorzFormatting" Value="HorzCentred" />
-                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                <Property Name="VertFormatting" Value="TopAligned" />
-                <Property Name="UnifiedAreaRect" Value="{{0.525,0},{0.10,0},{0.95,0},{0.35,0}}" />
-                <Window Type="MenuWidgets/Listbox" Name="orxonox/ThemeDropBox" >
+                <Window Type="DefaultWindow" Name="orxonox/Settings" >
+                    <Property Name="Text" Value="Settings" />
+                    <Property Name="Visible" Value="False" />
                     <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                    <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.3,0},{0.95,0},{0.95,0}" />
-                    <Event Name="ItemSelectionChanged" Function="GraphicsMenu.ThemeDropBox_changed"/>
+                    <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Settings/FovLabel" >
+                        <Property Name="Text" Value="Vertical field of view (FOV)" />
+                        <Property Name="FrameEnabled" Value="False" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.035,0},{0.05,0},{0.5,0},{0.12,0}}" />
+                        <Property Name="BackgroundEnabled" Value="False" />
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Settings/FpsLimitLabel" >
+                        <Property Name="Text" Value="Maximal frame rate" />
+                        <Property Name="FrameEnabled" Value="False" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.035,0},{0.18,0},{0.5,0},{0.25,0}}" />
+                        <Property Name="BackgroundEnabled" Value="False" />
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Settings/ParticleLodLabel" >
+                        <Property Name="Text" Value="Particle detail level" />
+                        <Property Name="FrameEnabled" Value="False" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.035,0},{0.31,0},{0.5,0},{0.38,0}}" />
+                        <Property Name="BackgroundEnabled" Value="False" />
+                    </Window>
+                    <Window Type="MenuWidgets/Editbox" Name="orxonox/Settings/Fov" >
+                        <Property Name="MaxTextLength" Value="1073741823" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5,0},{0.03,0},{0.65,0},{0.14,0}}" />
+                    </Window>
+                    <Window Type="MenuWidgets/Editbox" Name="orxonox/Settings/FpsLimit" >
+                        <Property Name="MaxTextLength" Value="1073741823" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5,0},{0.16,0},{0.65,0},{0.27,0}}" />
+                    </Window>
+                    <Window Type="MenuWidgets/Combobox" Name="orxonox/Settings/ParticleLodCombobox" >
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="ClippedByParent" Value="False" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5,0},{0.29,0},{0.7,0},{0.725,0}}" />
+                        <Property Name="MaxEditTextLength" Value="1073741823" />
+                    </Window>
+                    <Window Type="MenuWidgets/Checkbox" Name="orxonox/Settings/MeshLodCheckbox" >
+                        <Property Name="Text" Value="Enable mesh LOD" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.035,0},{0.44,0},{0.5,0},{0.51,0}}" />
+                    </Window>
+                    <Window Type="MenuWidgets/Checkbox" Name="orxonox/Settings/MotionBlurCheckbox" >
+                        <Property Name="Text" Value="Enable motion blur" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.035,0},{0.57,0},{0.5,0},{0.64,0}}" />
+                    </Window>
                 </Window>
             </Window>
-            <Window Type="MenuWidgets/StaticText" Name="orxonox/Brightness" >
-                <Property Name="Text" Value="Brightness" />
-                <Property Name="InheritsAlpha" Value="False" />
-                <Property Name="HorzFormatting" Value="HorzCentred" />
-                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                <Property Name="VertFormatting" Value="TopAligned" />
-                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.70,0},{0.475,0},{0.85,0}}" />
-                <Window Type="MenuWidgets/HorizontalScrollbar" Name="orxonox/BrightnessScrollbar" >
-                    <Property Name="Disabled" Value="true" />
-                    <Property Name="PageSize" Value="0" />
-                    <Property Name="StepSize" Value="0.1" />
-                    <Property Name="OverlapSize" Value="0" />
-                    <Property Name="DocumentSize" Value="1" />
-                    <Property Name="ScrollPosition" Value="0" />
-                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                    <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.6,0},{0.95,0},{0.8,0}}" />
-                    <Event Name="ThumbTrackStarted" Function="GraphicsMenu.GraphicsBrightnessScrollbar_started" />
-                    <Event Name="ThumbTrackEnded" Function="GraphicsMenu.GraphicsBrightnessScrollbar_ended" />
-                    <Event Name="ScrollPosChanged" Function="GraphicsMenu.GraphicsBrightnessScrollbar_changed" />
-                </Window>
-            </Window>
-            <Window Type="MenuWidgets/Checkbox" Name="orxonox/FullscreenCheckbox" >
-                <Property Name="Text" Value="Fullscreen" />
-                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                <Property Name="UnifiedAreaRect" Value="{{0.65,0},{0.35,0},{0.85,0},{0.425,0}}" />
-                <Event Name="CheckStateChanged" Function="GraphicsMenu.GraphicsFullscreenCheckbox_clicked"/>
-            </Window>
-            <Window Type="MenuWidgets/StaticText" Name="orxonox/GraphicsInfo" >
-                <Property Name="Text" >
-Changes in graphics
-settings require
-a game restart.</Property>
-                <Property Name="TextColours" Value="FFFFFFFF" />
-                <Property Name="InheritsAlpha" Value="False" />
-                <Property Name="HorzFormatting" Value="HorzCentred" />
-                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                <Property Name="VertFormatting" Value="TopAligned" />
-                <Property Name="UnifiedAreaRect" Value="{{0.525,0},{0.425,0},{0.95,0},{0.85,0}}" />
-            </Window>
         </Window>
-        <Window Type="MenuWidgets/Button" Name="orxonox/GraphicsBackButton" >
-            <Property Name="Text" Value="Back" />
+        <Window Type="MenuWidgets/Button" Name="orxonox/GraphicsOkButton" >
+            <Property Name="Text" Value="OK" />
             <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
-            <Event Name="Clicked" Function="GraphicsMenu.GraphicsBackButton_clicked"/>
+            <Property Name="UnifiedAreaRect" Value="{{0.2875,0},{0.6625,0},{0.4875,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="GraphicsMenu.callback_Ok_Clicked" />
         </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/GraphicsCancelButton" >
+            <Property Name="Text" Value="Cancel" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.6625,0},{0.7125,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="GraphicsMenu.callback_Cancel_Clicked" />
+        </Window>
     </Window>
 </GUILayout>

Modified: code/trunk/data/gui/schemes/GUIScheme.xsd
===================================================================
--- code/trunk/data/gui/schemes/GUIScheme.xsd	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/schemes/GUIScheme.xsd	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,54 +1,54 @@
 <?xml version="1.0" ?>
 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
-	<xsd:element name="GUIScheme" type="SchemeType" />
-	<xsd:complexType name="SchemeType">
+    <xsd:element name="GUIScheme" type="SchemeType" />
+    <xsd:complexType name="SchemeType">
         <xsd:choice minOccurs="0" maxOccurs="unbounded">
-			<xsd:element name="Imageset" type="NamedDataType" />
+            <xsd:element name="Imageset" type="NamedDataType" />
             <xsd:element name="ImagesetFromImage" type="NamedDataType" />
-			<xsd:element name="Font" type="NamedDataType" />
+            <xsd:element name="Font" type="NamedDataType" />
             <xsd:element name="LookNFeel" type="FileDataType" />
-			<xsd:element name="WindowSet" type="WindowSetType" />
-			<xsd:element name="WindowRendererSet" type="WindowRendererSetType" />
-			<xsd:element name="WindowAlias" type="WindowAliasType" />
+            <xsd:element name="WindowSet" type="WindowSetType" />
+            <xsd:element name="WindowRendererSet" type="WindowRendererSetType" />
+            <xsd:element name="WindowAlias" type="WindowAliasType" />
             <xsd:element name="FalagardMapping" type="FalagardMapType" />
-		</xsd:choice>
-		<xsd:attribute name="Name" type="xsd:string" use="required" />
-	</xsd:complexType>
-	<xsd:complexType name="WindowSetType">
-		<xsd:sequence>
+        </xsd:choice>
+        <xsd:attribute name="Name" type="xsd:string" use="required" />
+    </xsd:complexType>
+    <xsd:complexType name="WindowSetType">
+        <xsd:sequence>
             <xsd:element name="WindowFactory" type="WindowFactoryType" minOccurs="0" maxOccurs="unbounded" />
-		</xsd:sequence>
-		<xsd:attribute name="Filename" type="xsd:string" use="required" />
-	</xsd:complexType>
-	<xsd:complexType name="WindowRendererSetType">
-		<xsd:sequence>
+        </xsd:sequence>
+        <xsd:attribute name="Filename" type="xsd:string" use="required" />
+    </xsd:complexType>
+    <xsd:complexType name="WindowRendererSetType">
+        <xsd:sequence>
             <xsd:element name="WindowRendererFactory" type="WindowRendererFactoryType" minOccurs="0" maxOccurs="unbounded" />
-		</xsd:sequence>
-		<xsd:attribute name="Filename" type="xsd:string" use="required" />
-	</xsd:complexType>
+        </xsd:sequence>
+        <xsd:attribute name="Filename" type="xsd:string" use="required" />
+    </xsd:complexType>
     <xsd:complexType name="FileDataType">
         <xsd:attribute name="Filename" type="xsd:string" use="required" />
         <xsd:attribute name="ResourceGroup" type="xsd:string" use="optional"  default="" />
     </xsd:complexType>
-	<xsd:complexType name="NamedDataType">
-		<xsd:attribute name="Name" type="xsd:string" use="required" />
-		<xsd:attribute name="Filename" type="xsd:string" use="required" />
-		<xsd:attribute name="ResourceGroup" type="xsd:string" use="optional"  default="" />
-	</xsd:complexType>
-	<xsd:complexType name="WindowFactoryType">
-		<xsd:attribute name="Name" type="xsd:string" use="required" />
-	</xsd:complexType>
-	<xsd:complexType name="WindowRendererFactoryType">
-		<xsd:attribute name="Name" type="xsd:string" use="required" />
-	</xsd:complexType>
-	<xsd:complexType name="WindowAliasType">
-		<xsd:attribute name="Alias" type="xsd:string" use="required" />
-		<xsd:attribute name="Target" type="xsd:string" use="required" />
-	</xsd:complexType>
+    <xsd:complexType name="NamedDataType">
+        <xsd:attribute name="Name" type="xsd:string" use="required" />
+        <xsd:attribute name="Filename" type="xsd:string" use="required" />
+        <xsd:attribute name="ResourceGroup" type="xsd:string" use="optional"  default="" />
+    </xsd:complexType>
+    <xsd:complexType name="WindowFactoryType">
+        <xsd:attribute name="Name" type="xsd:string" use="required" />
+    </xsd:complexType>
+    <xsd:complexType name="WindowRendererFactoryType">
+        <xsd:attribute name="Name" type="xsd:string" use="required" />
+    </xsd:complexType>
+    <xsd:complexType name="WindowAliasType">
+        <xsd:attribute name="Alias" type="xsd:string" use="required" />
+        <xsd:attribute name="Target" type="xsd:string" use="required" />
+    </xsd:complexType>
     <xsd:complexType name="FalagardMapType">
         <xsd:attribute name="WindowType" type="xsd:string" use="required" />
         <xsd:attribute name="TargetType" type="xsd:string" use="required" />
-		<xsd:attribute name="Renderer" type="xsd:string" use="required" />
+        <xsd:attribute name="Renderer" type="xsd:string" use="required" />
         <xsd:attribute name="LookNFeel" type="xsd:string" use="required" />
     </xsd:complexType>
-</xsd:schema>
\ No newline at end of file
+</xsd:schema>

Modified: code/trunk/data/gui/schemes/OrxonoxLook.scheme
===================================================================
--- code/trunk/data/gui/schemes/OrxonoxLook.scheme	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/schemes/OrxonoxLook.scheme	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,8 +1,8 @@
 <?xml version="1.0" ?>
 <GUIScheme Name="OrxonoxLook">
-	<Imageset Name="OrxonoxLook" Filename="OrxonoxLook.imageset" />
-	<LookNFeel Filename="OrxonoxLook.looknfeel" />
-	<WindowRendererSet Filename="CEGUIFalagardWRBase" />
+    <Imageset Name="OrxonoxLook" Filename="OrxonoxLook.imageset" />
+    <LookNFeel Filename="OrxonoxLook.looknfeel" />
+    <WindowRendererSet Filename="CEGUIFalagardWRBase" />
 
     <!-- Standard widgets -->
     <FalagardMapping WindowType="OrxonoxLook/StaticImage"              TargetType="DefaultWindow"           Renderer="Falagard/StaticImage"       LookNFeel="OrxonoxLook/StaticImage" />
@@ -44,7 +44,7 @@
     <FalagardMapping WindowType="OrxonoxLook/Titlebar"                 TargetType="CEGUI/Titlebar"          Renderer="Falagard/Titlebar"          LookNFeel="OrxonoxLook/Titlebar" />
     <FalagardMapping WindowType="OrxonoxLook/Tooltip"                  TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="OrxonoxLook/Tooltip" />
     <FalagardMapping WindowType="OrxonoxLook/Tree"                     TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="OrxonoxLook/Tree" />
-    
+
     <!-- Additional widgets -->
     <FalagardMapping WindowType="OrxonoxLook/AlternateProgressBar"        TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="OrxonoxLook/AltProgressBar" />
     <FalagardMapping WindowType="OrxonoxLook/VUMeter"                     TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="OrxonoxLook/VUMeter" />

Modified: code/trunk/data/gui/schemes/TaharezGreenLook.scheme
===================================================================
--- code/trunk/data/gui/schemes/TaharezGreenLook.scheme	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/schemes/TaharezGreenLook.scheme	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,8 +1,8 @@
 <?xml version="1.0" ?>
 <GUIScheme Name="TaharezGreenLook">
-	<Imageset Name="TaharezGreenLook" Filename="TaharezGreenLook.imageset" />
-	<LookNFeel Filename="TaharezGreenLook.looknfeel" />
-	<WindowRendererSet Filename="CEGUIFalagardWRBase" />
+    <Imageset Name="TaharezGreenLook" Filename="TaharezGreenLook.imageset" />
+    <LookNFeel Filename="TaharezGreenLook.looknfeel" />
+    <WindowRendererSet Filename="CEGUIFalagardWRBase" />
 
     <!-- Standard widgets -->
     <FalagardMapping WindowType="TaharezGreenLook/StaticImage"              TargetType="DefaultWindow"           Renderer="Falagard/StaticImage"       LookNFeel="TaharezGreenLook/StaticImage" />
@@ -44,7 +44,7 @@
     <FalagardMapping WindowType="TaharezGreenLook/Titlebar"                 TargetType="CEGUI/Titlebar"          Renderer="Falagard/Titlebar"          LookNFeel="TaharezGreenLook/Titlebar" />
     <FalagardMapping WindowType="TaharezGreenLook/Tooltip"                  TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="TaharezGreenLook/Tooltip" />
     <FalagardMapping WindowType="TaharezGreenLook/Tree"                     TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="TaharezGreenLook/Tree" />
-    
+
     <!-- Additional widgets -->
     <FalagardMapping WindowType="TaharezGreenLook/AlternateProgressBar"        TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezGreenLook/AltProgressBar" />
     <FalagardMapping WindowType="TaharezGreenLook/VUMeter"                     TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezGreenLook/VUMeter" />

Modified: code/trunk/data/gui/schemes/TaharezLook.scheme
===================================================================
--- code/trunk/data/gui/schemes/TaharezLook.scheme	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/schemes/TaharezLook.scheme	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,8 +1,8 @@
 <?xml version="1.0" ?>
 <GUIScheme Name="TaharezLook">
-	<Imageset Name="TaharezLook" Filename="TaharezLook.imageset" />
-	<LookNFeel Filename="TaharezLook.looknfeel" />
-	<WindowRendererSet Filename="CEGUIFalagardWRBase" />
+    <Imageset Name="TaharezLook" Filename="TaharezLook.imageset" />
+    <LookNFeel Filename="TaharezLook.looknfeel" />
+    <WindowRendererSet Filename="CEGUIFalagardWRBase" />
 
     <!-- Standard widgets -->
     <FalagardMapping WindowType="TaharezLook/StaticImage"              TargetType="DefaultWindow"           Renderer="Falagard/StaticImage"       LookNFeel="TaharezLook/StaticImage" />
@@ -44,7 +44,7 @@
     <FalagardMapping WindowType="TaharezLook/Titlebar"                 TargetType="CEGUI/Titlebar"          Renderer="Falagard/Titlebar"          LookNFeel="TaharezLook/Titlebar" />
     <FalagardMapping WindowType="TaharezLook/Tooltip"                  TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="TaharezLook/Tooltip" />
     <FalagardMapping WindowType="TaharezLook/Tree"                     TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="TaharezLook/Tree" />
-    
+
     <!-- Additional widgets -->
     <FalagardMapping WindowType="TaharezLook/AlternateProgressBar"        TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezLook/AltProgressBar" />
     <FalagardMapping WindowType="TaharezLook/VUMeter"                     TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezLook/VUMeter" />

Modified: code/trunk/data/gui/scripts/AudioMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/AudioMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/AudioMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -2,13 +2,6 @@
 
 local P = createMenuSheet("AudioMenu")
 
-P.buttonList = {}
-
-function P.onShow()
-    P.oldindex = -2
-    P.index = -1
-end
-
 function P.onLoad()
     soundMgr = orxonox.SoundManager:getInstance()
     block = false
@@ -49,11 +42,10 @@
         listboxwindow:setItemSelectState(0,true)
     end
 
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/AudioBackButton"),
-            ["function"]  = P.AudioBackButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.AudioBackButton_clicked
+    })
 end
 
 function P.AudioMasterScrollbar_changed(e)
@@ -184,9 +176,5 @@
     hideMenuSheet(P.name)
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 1)
-end
-
 return P
 

Modified: code/trunk/data/gui/scripts/ControlsMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/ControlsMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/ControlsMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,39 +1,28 @@
 -- ControlsMenu.lua
 
 local P = createMenuSheet("ControlsMenu")
-P.buttonList = {}
 P.loadAlong = { "MouseControlsMenu", "KeyBindMenu" }
 
 function P.onLoad()
-    P.multiplayerMode = "startClient" 
+    P.multiplayerMode = "startClient"
 
     --buttons are arranged in a 3x1 matrix:
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/MouseControlsButton"),
-            ["function"]  = P.ControlsMouseControlsButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.ControlsMouseControlsButton_clicked
+    })
 
-    local item = {
+    P:setButton(2, 1, {
             ["button"] = winMgr:getWindow("orxonox/KeybindingsButton"),
-            ["function"]  = P.ControlsKeyboardControlsButton_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.ControlsKeyboardControlsButton_clicked
+    })
 
-    local item = {
+    P:setButton(3, 1, {
             ["button"] = winMgr:getWindow("orxonox/ControlsBackButton"),
-            ["function"]  = P.ControlsBackButton_clicked
-    }
-    P.buttonList[3] = item
-
+            ["callback"]  = P.ControlsBackButton_clicked
+    })
 end
 
-function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
-end
-
 function P.ControlsMouseControlsButton_clicked(e)
     showMenuSheet("MouseControlsMenu", true)
 end
@@ -46,9 +35,5 @@
     hideMenuSheet(P.name)
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 3, 1)
-end
-
 return P
 

Modified: code/trunk/data/gui/scripts/CreditsMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/CreditsMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/CreditsMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -2,22 +2,16 @@
 
 local P = createMenuSheet("CreditsMenu")
 
-P.buttonList = {}
 P.scrollbarWidth = 13
 
 function P.onLoad()
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/CreditsBackButton"),
-            ["function"]  = P.CreditsBackButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.CreditsBackButton_clicked
+    })
 end
 
 function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
-
     local description = winMgr:getWindow("orxonox/CreditsText")
     description:setProperty("HorzFormatting", "WordWrapLeftAligned")
     description:setProperty("VertFormatting", "TopAligned")
@@ -32,9 +26,5 @@
     hideMenuSheet(P.name)
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 1)
-end
-
 return P
 

Modified: code/trunk/data/gui/scripts/DecisionPopup.lua
===================================================================
--- code/trunk/data/gui/scripts/DecisionPopup.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/DecisionPopup.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -2,29 +2,22 @@
 
 local P = createMenuSheet("DecisionPopup")
 
-P.buttonList = {}
-
-function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
-end
-
 function P.onLoad()
 
     --button are arranged in a 1x2 matrix
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/DecisionPopup_button_yes"),
-            ["function"]  = P.button_yes
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.button_yes
+    })
 
-    local item = {
+    P:setButton(1, 2, {
             ["button"] = winMgr:getWindow("orxonox/DecisionPopup_button_no"),
-            ["function"]  = P.button_no
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.button_no
+    })
+end
 
+function P.onShow()
+    P:setSelection(1, 1)
 end
 
 function P.setCallback(functionPtr)
@@ -50,9 +43,5 @@
     hideMenuSheet("DecisionPopup")
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 2)
-end
-
 return P
 

Modified: code/trunk/data/gui/scripts/GUISheet.lua
===================================================================
--- code/trunk/data/gui/scripts/GUISheet.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/GUISheet.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -15,18 +15,37 @@
 function P:onLoad()
 end
 
+-- Override this function if you need to do work on show
+function P:onShow()
+end
+
+-- Override this function if you need to do work on hide
+function P:onHide()
+end
+
+-- Override this function if you need to do work on quit
+function P:onQuit()
+end
+
+-- Override this function if you want to react on keystrokes
+function P:onKeyPressed()
+end
+
+-- Override this function if you want to update the gui after the window was resized
+function P:onWindowResized()
+end
+
 -- show function for the GUI
 function P:show()
     self.window:show()
     self.bVisible = true
 
+    -- set the selected button's state
+    self:setSelectedButtonsStateToSelected()
+
     self:onShow()
 end
 
--- Override this function if you need to do work on show
-function P:onShow()
-end
-
 -- hide function for the GUI
 function P:hide()
     self.window:hide()
@@ -35,12 +54,13 @@
     self:onHide()
 end
 
--- Override this function if you need to do work on hide
-function P:onHide()
-end
+function P:quit()
+    -- reset the selected button
+    if self.buttons then
+        self:resetSelection()
+    end
 
--- Override this function if you need to do work just after the sheet has been hidden
-function P:afterHide()
+    self:onQuit()
 end
 
 function P:load()
@@ -63,7 +83,316 @@
     return self
 end
 
-function P:onKeyPressed(e)
+-- Handles key pressed while the gui sheed is displayed
+function P:keyPressed()
+    if self.buttons then
+        if code == "208" then     -- key down
+            self:moveSelectionRow(1)
+        elseif code == "200" then -- key up
+            self:moveSelectionRow(-1)
+        elseif code == "205" then -- key right
+            self:moveSelectionColumn(1)
+        elseif code == "203" then -- key left
+            self:moveSelectionColumn(-1)
+        elseif code == "28" or code == "156"  then -- key enter or key numpad enter
+            self:pressSelectedButton()
+        end
+    end
+
+    self:onKeyPressed()
 end
 
+function P:windowResized()
+    self:onWindowResized()
+end
+
+
+-------------------------------------------------------------------------------
+-- Keyboard control -----------------------------------------------------------
+-------------------------------------------------------------------------------
+
+-- Initializes the buttons table, used to control the menu with the keyboard
+function P:initButtons(rows, columns)
+    self.rows = rows
+    self.columns = columns
+    self.buttons = {}
+    self.selectedRow = 0
+    self.selectedColumn = 0
+    self.ratio = 1
+end
+
+-- ratio: the button's with divided by the button's height (used to calculate distance between buttons - adjust this until you get the desired behavior)
+function P:setRatio(ratio)
+    self.ratio = ratio
+end
+
+-- Defines the button for a given position in the table. The upper-left button is at position (1, 1)
+function P:setButton(row, column, button)
+    if not self.buttons then
+        -- init the table
+        self:initButtons(row, column)
+    elseif row > self.rows or column > self.columns then
+        -- rearrange the table
+        local maxRows = math.max(self.rows, row)
+        local maxColumns = math.max(self.columns, column)
+
+        for r = self.rows, 1, -1 do
+            for c = self.columns, 1, -1 do
+                local b = self:getButton(r, c)
+                if b then
+                    self.buttons[(r - 1) * self.columns + (c - 1)] = nil
+                    self.buttons[(r - 1) * maxColumns + (c - 1)] = b
+                end
+            end
+        end
+
+        self.rows = maxRows
+        self.columns = maxColumns
+    end
+
+    self.buttons[(row - 1) * self.columns + (column - 1)] = button
+end
+
+-- Returns the button at a given position in the table. The upper-left button is at position (1, 1)
+function P:getButton(row, column)
+    if self.buttons then
+        return self.buttons[(row - 1) * self.columns + (column - 1)]
+    else
+        return nil
+    end
+end
+
+-- Returns the selected button
+function P:getSelectedButton()
+    if self:hasSelection() then
+        return self:getButton(self.selectedRow, self.selectedColumn)
+    else
+        return nil
+    end
+end
+
+-- Presses the selected button if any
+function P:pressSelectedButton()
+    if self:getSelectedButton() then
+        self.pressedEnter = true
+        self:getSelectedButton().callback()
+        self.pressedEnter = false
+    end
+end
+
+-- Sets the selection to a given row and column. The upper-left button is at position (1, 1)
+function P:setSelection(row, column)
+    if not self.buttons then
+        return
+    end
+
+    assert(row > 0 and column > 0 and row <= self.rows and column <= self.columns, "(" .. row .. "/" .. column .. ") is not in the valid bounds of the table (1/1)-(" .. self.rows .. "/" .. self.columns .. ")")
+
+    self:setSelectedButtonsStateToNormal()
+
+    self.selectedRow = row
+    self.selectedColumn = column
+
+    self:setSelectedButtonsStateToSelected()
+end
+
+-- Sets the selection to the button closest to the given row and column. The upper-left button is at position (1, 1)
+function P:setSelectionNear(row, column)
+    if not self.buttons then
+        return
+    end
+
+    assert(row > 0 and column > 0 and row <= self.rows and column <= self.columns, "(" .. row .. "/" .. column .. ") is not in the valid bounds of the table (1/1)-(" .. self.rows .. "/" .. self.columns .. ")")
+
+    if self:getButton(row, column) then
+        self:setSelection(row, column)
+    else
+        local min = 1000000
+        local minRow, minColumn
+
+        for r = 1, self.rows do
+            for c = 1, self.columns do
+                if self:getButton(r, c) then
+                    local distance = math.sqrt((row - r)^2 + ((column - c) * self.ratio)^2)
+                    if distance < min then
+                        min = distance; minRow = r; minColumn = c
+                    end
+                end
+            end
+        end
+
+        if minRow and minColumn then
+            self:setSelection(minRow, minColumn)
+        else
+            self:resetSelection()
+        end
+    end
+end
+
+-- Moves the selection by a given number of rows (a positive value means down, a negative value means up)
+function P:moveSelectionRow(relRow)
+    self:moveSelection(relRow, "selectedRow", "selectedColumn", "rows", "columns", true)
+end
+
+-- Moves the selection by a given number of columns (a positive value means right, a negative value means left)
+function P:moveSelectionColumn(relColumn)
+    self:moveSelection(relColumn, "selectedColumn", "selectedRow", "columns", "rows", false)
+end
+
+-- Generic move function, the values are determined at runtime depending on the arguments
+function P:moveSelection(relMove, selectedThis, selectedOther, limitThis, limitOther, isRow)
+    if not self.buttons then
+        return
+    end
+
+    -- if there's no selection yet, prepare it such that the selection enters the table from the desired side
+    if self.selectedRow > 0 or self.selectedColumn > 0 then
+        self:setSelectedButtonsStateToNormal()
+    else
+        if relMove > 0 then
+            self[selectedThis] = 0
+            self[selectedOther] = 1
+        elseif relMove < 0 then
+            self[selectedThis] = self[limitThis] + 1
+            self[selectedOther] = 1
+        else
+            return
+        end
+    end
+
+    -- move the selection according to the parameters
+    self[selectedThis] = self[selectedThis] + relMove
+
+    -- wrap around on overflow or underflow
+    while self[selectedThis] > self[limitThis] do self[selectedThis] = self[selectedThis] - self[limitThis] end
+    while self[selectedThis] <= 0              do self[selectedThis] = self[selectedThis] + self[limitThis] end
+
+    -- if the button is deactivated, search the button closest to the desired location
+    if self:getSelectedButton() == nil then
+        local min = 1000000
+        local minV1, minV2
+        local limit, step
+
+        if relMove > 0 then
+            limit = self[limitThis]
+            step = 1
+        else
+            limit = 1
+            step = -1
+        end
+
+        for v1 = self[selectedThis], limit, step do
+            for v2 = 1, self[limitOther] do
+                local button
+                if isRow == true then
+                    button = self:getButton(v1, v2)
+                else
+                    button = self:getButton(v2, v1)
+                end
+                if button then
+                    local distance
+                    if isRow == true then
+                        distance = math.sqrt((self[selectedThis] - v1)^2 + ((self[selectedOther] - v2) * self.ratio)^2)
+                    else
+                        distance = math.sqrt(((self[selectedThis] - v1) * self.ratio)^2 + (self[selectedOther] - v2)^2)
+                    end
+                    if distance < min then
+                        min = distance; minV1 = v1; minV2 = v2
+                    end
+                end
+            end
+        end
+
+        if minV1 and minV2 then
+            self[selectedThis] = minV1
+            self[selectedOther] = minV2
+        elseif self:hasButtons() then
+            -- no suitable button found - wrap around and search again
+            if relMove > 0 then
+                self[selectedThis] = 0
+            else
+                self[selectedThis] = self[limitThis] + 1
+            end
+            self:moveSelection(relMove, selectedThis, selectedOther, limitThis, limitOther, isRow)
+        end
+    end
+
+    self:setSelectedButtonsStateToSelected()
+end
+
+-- Resets the selection
+function P:resetSelection()
+    self:setSelectedButtonsStateToNormal()
+
+    self.selectedRow = 0
+    self.selectedColumn = 0
+end
+
+-- Checks if there's at least one button in the table
+function P:hasButtons()
+    local count = 0
+    for r = 1, self.rows do
+        for c = 1, self.columns do
+            if self:getButton(r, c) then
+                count = count + 1
+            end
+        end
+    end
+
+    return (count > 0)
+end
+
+-- Determines if a button is selected
+function P:hasSelection()
+    if self.selectedRow and self.selectedRow > 0 and self.selectedColumn and self.selectedColumn > 0 then
+        return true
+    else
+        return false
+    end
+end
+
+-- Sets the selected button's state to normal
+function P:setSelectedButtonsStateToNormal()
+    self:setSelectedButtonsState("Normal")
+end
+
+-- Sets the selected button's state to selected
+function P:setSelectedButtonsStateToSelected()
+    self:setSelectedButtonsState("Selected")
+end
+
+-- Sets the selected button's state to pushed
+function P:setSelectedButtonsStateToPushed()
+    self:setSelectedButtonsState("Pushed")
+end
+
+-- Sets the selected button's state
+function P:setSelectedButtonsState(state)
+    if self:getSelectedButton() then
+        local element = self:getSelectedButton().button
+        local offset = getElementStateOffset(element)
+
+        if offset then
+            element:setProperty("NormalImageRightEdge",  string.sub(element:getProperty("NormalImageRightEdge"),  1, offset) .. state)
+            element:setProperty("NormalImageLeftEdge",   string.sub(element:getProperty("NormalImageLeftEdge"),   1, offset) .. state)
+            element:setProperty("NormalImageBackground", string.sub(element:getProperty("NormalImageBackground"), 1, offset) .. state)
+        end
+    end
+end
+
+-- Gets the offset of the button's current state
+function getElementStateOffset(element)
+    local property = element:getProperty("NormalImageRightEdge")
+
+    if string.sub(property, string.len(property) - 5, string.len(property)) == "Normal" then
+        return -7
+    elseif string.sub(property, string.len(property) - 7, string.len(property)) == "Selected" then
+        return -9
+    elseif string.sub(property, string.len(property) - 5, string.len(property)) == "Pushed" then
+        return -7
+    else
+        return nil
+    end
+end
+
 return P

Modified: code/trunk/data/gui/scripts/GUITools.lua
===================================================================
--- code/trunk/data/gui/scripts/GUITools.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/GUITools.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -53,284 +53,3 @@
     local height = lines * window:getFont():getLineSpacing() + frameHeight
     return height
 end
-
---function to iterate through a menu sheet by using arrowkeys
-
--- at arguments:
---  list: 2-dimensional table, arguments are items that contain a button and its function
---        !!note: each button can only be in the list once!!
---  code: code of any key on the keyboard
---  P: menusheet
---  n: number of rows of the buttontable
---  m: number of colums of the buttontable
-
-function buttonIteratorHelper(list, code, P, n, m)
-
-    --after a key (down,up,left,right) is pressed the index of the current button has to be updated    
-
-    --key down
-    if code == "208" then
-        if P.index < 0 then     -- initial status
-            P.index = 0
-            P.oldindex = -1
-        else
-            P.oldindex = P.index
-            P.index = (P.index + m) % (m*n)     --modulo operation works as a "wrap around" in the button menu
-                                                
-            while list[P.index+1] == nil do     
-                P.oldindex = P.index
-                P.index = (P.index + m) % (m*n)
-            end
-        end
-
-    --key up
-    elseif code == "200" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif(P.index == 0) then
-            P.oldindex = P.index
-            P.index = m*n-m
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = (P.index-m)%(m*n)
-            end
-        else
-            P.oldindex = P.index
-            P.index = (P.index -m) % (m*n)
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = (P.index-m)%(m*n)
-            end
-        end
-
-    --key right
-    elseif code == "205" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif (P.index+1) % m == 0 then     -- we are at the right-end of a row
-            P.oldindex = P.index
-            P.index = P.index + 1 -m
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = P.index + 1
-            end
-        else
-            P.oldindex = P.index
-            P.index = P.index + 1
-
-            while list[P.index+1] == nil do
-                if (P.index+1) % m == 0 then     -- we are at the right-end of a row
-                    P.oldindex = P.index
-                    P.index = P.index + 1-m
-
-                else    
-                    P.oldindex = P.index
-                    P.index = P.index + 1
-                end
-            end
-        end    
-
-    --key left
-    elseif code == "203" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif P.index % m == 0 then         -- we are at the left-end of a row 
-            P.oldindex = P.index
-            P.index = P.index +m-1
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = P.index -1
-            end
-        else
-            P.oldindex = P.index
-            P.index = P.index -1
-
-            while list[P.index+1] == nil do
-                if P.index % m == 0 then     -- we are at the left-end of a row 
-                    P.oldindex = P.index
-                    P.index = P.index -1 + m
-                else                
-                    P.oldindex = P.index
-                    P.index = P.index -1
-                end
-            end   
-        end
-    end
-       
-    --to update the new current button
-    if (code == "208" or code == "200" or code == "203" or code == "205") and P.oldindex~= P.index then
-
-        local system = CEGUI.System:getSingleton()
-        local window = winMgr:getWindow("orxonox/MainMenuBackground")
-
-        local item = list[P.index+1]
-        local child = item["button"]
-        local s = child:getProperty("NormalImageRightEdge") 
-
-        --teste ob der Button nicht schon gehighlightet ist
-        if string.sub(s,string.len(s)-8,string.len(s)) == "Highlight" then
-            --nop
-        else
-            child:setProperty("NormalImageRightEdge", string.sub(child:getProperty("NormalImageRightEdge"),1,-7) .. "Highlight")
-            child:setProperty("NormalImageLeftEdge", string.sub(child:getProperty("NormalImageLeftEdge"),1,-7) .. "Highlight")
-            child:setProperty("NormalImageBackground", string.sub(child:getProperty("NormalImageBackground"),1,-7) .. "Highlight")
-            if P.oldindex >= 0 then
-                if list[P.oldindex+1] ~= nil then
-                    local item = list[P.oldindex+1]
-                    local oldChild = item["button"]
-                    oldChild:setProperty("NormalImageRightEdge", string.sub(oldChild:getProperty("NormalImageRightEdge"),1,-10) .. "Normal")
-                    oldChild:setProperty("NormalImageLeftEdge", string.sub(oldChild:getProperty("NormalImageLeftEdge"),1,-10) .. "Normal")
-                    oldChild:setProperty("NormalImageBackground", string.sub(oldChild:getProperty("NormalImageBackground"),1,-10) .. "Normal")
-                end
-            end
-        end
-
-        --for every highlighted button check if index is on its position. If not, set imageproperty on "normal"
-        local i = 1
-        while i < (n*m) do
-            if i == P.index +1 then 
-                i = i+1
-            else
-                if list[i] ~= nil then 
-                local item = list[i]
-                local child = item["button"]
-                local s = child:getProperty("NormalImageRightEdge")
-                    if string.sub(s,string.len(s)-8,string.len(s)) == "Highlight" then
-                        child:setProperty("NormalImageRightEdge", string.sub(child:getProperty("NormalImageRightEdge"),1,-10) .. "Normal")
-                        child:setProperty("NormalImageLeftEdge", string.sub(child:getProperty("NormalImageLeftEdge"),1,-10) .. "Normal")
-                        child:setProperty("NormalImageBackground", string.sub(child:getProperty("NormalImageBackground"),1,-10) .. "Normal")
-                    end
-                end
-            end
-                i=i+1
-        end
-    end  
-
-    --enter
-    if code == "28" and P.index >= 0 then
-        local item = list[P.index+1]
-        local child = item["button"] 
-        child:setProperty("NormalImageRightEdge", string.sub(child:getProperty("NormalImageRightEdge"),1,-10) .. "Normal")
-        child:setProperty("NormalImageLeftEdge", string.sub(child:getProperty("NormalImageLeftEdge"),1,-10) .. "Normal")
-        child:setProperty("NormalImageBackground", string.sub(child:getProperty("NormalImageBackground"),1,-10) .. "Normal")
-
-        local foo = item["function"]
-        foo()
-    end
-
-end
-
---write index and oldindex on the console
---works like buttonIteratorHelper
-function indexTester(list,code,P,n,m)
-    --key down
-    if code == "208" then
-        if P.index < 0 then     -- initial status
-            P.index = 0
-            P.oldindex = -1
-        else
-            P.oldindex = P.index
-            P.index = (P.index + m) % (m*n)
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = (P.index + m) % (m*n)
-            end
-        end
-
-    --key up
-    elseif code == "200" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif(P.index == 0) then
-            P.oldindex = P.index
-            P.index = m*n-m
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = (P.index-m)%(m*n)
-            end
-        else
-            P.oldindex = P.index
-            P.index = (P.index -m) % (m*n)
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = P.index -m
-            end
-        end
-
-    --key right
-    elseif code == "205" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif (P.index+1) % m == 0 then     -- we are at the right-end of a row
-            P.oldindex = P.index
-            P.index = P.index + 1 -m
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = P.index + 1
-            end
-        else
-            P.oldindex = P.index
-            P.index = P.index + 1
-
-            while list[P.index+1] == nil do
-                if (P.index+1) % m == 0 then     -- we are at the right-end of a row
-                    P.oldindex = P.index
-                    P.index = P.index + 1-m
-
-                else    
-                    P.oldindex = P.index
-                    P.index = P.index + 1
-                end
-            end
-        end    
-
-    --key left
-    elseif code == "203" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif P.index % m == 0 then         -- we are at the left-end of a row 
-            P.oldindex = P.index
-            P.index = P.index +m-1
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = P.index -1
-            end
-        else
-            P.oldindex = P.index
-            P.index = P.index -1
-
-            while list[P.index+1] == nil do
-                if P.index % m == 0 then     -- we are at the left-end of a row 
-                    P.oldindex = P.index
-                    P.index = P.index -1 + m
-                else                
-                    P.oldindex = P.index
-                    P.index = P.index -1
-                end
-            end   
-        end
-    end    
-
-    cout(0, P.oldindex)
-    cout(0, P.index)
-
-end
-
-
-
-

Modified: code/trunk/data/gui/scripts/GraphicsMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/GraphicsMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/GraphicsMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -2,238 +2,419 @@
 
 local P = createMenuSheet("GraphicsMenu")
 
-P.buttonList = {}
+P.resolutionList = {"custom", "640 x 480", "720 x 480", "720 x 576", "800 x 600", "1024 x 600", "1024 x 768", "1152 x 864", "1280 x 720", "1280 x 800", "1280 x 960", "1280 x 1024", "1360 x 768", "1440 x 900", "1600 x 900", "1600 x 1200", "1680 x 1050"}
 P.schemeList = {"TaharezGreen", "Orxonox"}
+P.fsaaList = {"0", "2", "4", "8", "8 [Quality]"}
+P.particleLodList = {"None", "Low", "Normal", "High"}
 
-function P.onShow()
-    --indices to iterate through buttonlist (trivial in this menu sheet)
-    P.oldindex = -2
-    P.index = -1
-end
+function P:onLoad()
+    -------------------
+    -- Button matrix --
+    -------------------
 
-function P.onLoad()
-    block = true
-    file = orxonox.PathConfig:getConfigPathString() .. orxonox.getConfig("GraphicsManager", "ogreConfigFile_")
-    search_mode = 0
-    f = io.open(file, "r")
-    firstline = f:read("*line")
-    rendersystem = string.sub(firstline, 15)
-    for line in f:lines() do
-        if search_mode == 0 then
-            if string.find(line, rendersystem) ~= nil then
-                search_mode = 1
-            end
-        end
-        if search_mode == 1 then
-            if string.sub(line, 1, 11) == "Full Screen" then
-                if string.sub(line, 13) == "Yes" then
-                    fullscreen = true
-                else
-                    fullscreen = false
-                end
-            end
-            if string.sub(line, 1, 10) == "Video Mode" then
-                if string.match(line, "@") == "@" then
-                    resolution = string.sub(line, 12, string.find(line, "@")-2)
-                else
-                    resolution = string.sub(line, 12)
-                end
-                break
-            end
-        end
+    P:setButton(1, 1, {
+            ["button"] = winMgr:getWindow("orxonox/GraphicsOkButton"),
+            ["callback"]  = P.callback_Ok_Clicked
+    })
+
+    P:setButton(1, 2, {
+            ["button"] = winMgr:getWindow("orxonox/GraphicsCancelButton"),
+            ["callback"]  = P.callback_Cancel_Clicked
+    })
+
+    -- place apply button at the bottom in the matrix, even though it's in fact at the top, to make the OK button highlighted by default
+    P:setButton(2, 1, {
+            ["button"] = winMgr:getWindow("orxonox/Display/Resolution/Apply"),
+            ["callback"]  = P.callback_Apply_Clicked
+    })
+
+    -----------------
+    -- Combo boxes --
+    -----------------
+
+    -- resolution combobox
+    local resolutionCombobox = winMgr:getWindow("orxonox/Display/Resolution/Combobox")
+    CEGUI.toCombobox(resolutionCombobox):setReadOnly(true)
+
+    for k,v in pairs(P.resolutionList) do
+        local item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        resolutionCombobox:addItem(item)
     end
-    f:close()
-    local fullscreenwindow = tolua.cast(winMgr:getWindow("orxonox/FullscreenCheckbox"),"CEGUI::Checkbox")
-    fullscreenwindow:setSelected(fullscreen)
-    listboxwindow = winMgr:getWindow("orxonox/ResolutionListbox")
-    local resolutionList = {}
-    table.insert(resolutionList, "640 x 480")
-    table.insert(resolutionList, "720 x 480")
-    table.insert(resolutionList, "720 x 576")
-    table.insert(resolutionList, "800 x 480")
-    table.insert(resolutionList, "800 x 600")
-    table.insert(resolutionList, "1024 x 480")
-    table.insert(resolutionList, "1024 x 600")
-    table.insert(resolutionList, "1024 x 768")
-    table.insert(resolutionList, "1152 x 864")
-    table.insert(resolutionList, "1280 x 720")
-    table.insert(resolutionList, "1280 x 768")
-    table.insert(resolutionList, "1440 x 900")
-    for k,v in pairs(resolutionList) do
-        item = CEGUI.createListboxTextItem(v)
+
+    -- themes combobox
+    local themeCombobox = winMgr:getWindow("orxonox/Display/Theme/Combobox")
+    CEGUI.toCombobox(themeCombobox):setReadOnly(true)
+
+    for k,v in pairs(P.schemeList) do
+        local item = CEGUI.createListboxTextItem(v)
         item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
-        CEGUI.toListbox(listboxwindow):addItem(item)
+        themeCombobox:addItem(item)
     end
-    if resolution == "640 x 480" then
-        listboxwindow:setItemSelectState(0,true)
-    elseif resolution == "720 x 480" then
-        listboxwindow:setItemSelectState(1,true)
-    elseif resolution == "720 x 576" then
-        listboxwindow:setItemSelectState(2,true)
-    elseif resolution == "800 x 480" then
-        listboxwindow:setItemSelectState(3,true)
-    elseif resolution == "800 x 600" then
-        listboxwindow:setItemSelectState(4,true)
-    elseif resolution == "1024 x 480" then
-        listboxwindow:setItemSelectState(5,true)
-    elseif resolution == "1024 x 600" then
-        listboxwindow:setItemSelectState(6,true)
-    elseif resolution == "1024 x 768" then
-        listboxwindow:setItemSelectState(7,true)
-    elseif resolution == "1152 x 864" then
-        listboxwindow:setItemSelectState(8,true)
-    elseif resolution == "1280 x 720" then
-        listboxwindow:setItemSelectState(9,true)
-    elseif resolution == "1280 x 768" then
-        listboxwindow:setItemSelectState(10,true)
-    elseif resolution == "1440 x 900" then
-        listboxwindow:setItemSelectState(11,true)
+
+    -- fsaa combobox
+    local fsaaCombobox = winMgr:getWindow("orxonox/Display/More/FSAA")
+    CEGUI.toCombobox(fsaaCombobox):setReadOnly(true)
+
+    for k,v in pairs(P.fsaaList) do
+        local item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        fsaaCombobox:addItem(item)
     end
-    scrollbar_active = false
-    block = false
 
-    local item = {
-            ["button"] = winMgr:getWindow("orxonox/GraphicsBackButton"),
-            ["function"]  = P.GraphicsBackButton_clicked
-    }
-    P.buttonList[1] = item
+    -- particle lod combobox
+    local particleLodCombobox = winMgr:getWindow("orxonox/Settings/ParticleLodCombobox")
+    CEGUI.toCombobox(particleLodCombobox):setReadOnly(true)
 
-    local dropbox = winMgr:getWindow("orxonox/ThemeDropBox")
-    local scheme = orxonox.CommandExecutor:query("getConfig GUIManager guiScheme_")
-    for k,v in pairs(P.schemeList) do
-        local item = CEGUI.createListboxTextItem(P.schemeList[k])
+    for k,v in pairs(P.particleLodList) do
+        local item = CEGUI.createListboxTextItem(v)
         item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
-        CEGUI.toListbox(dropbox):addItem(item)
-        if v == scheme then
-            dropbox:setItemSelectState(item, true)
+        particleLodCombobox:addItem(item)
+    end
+end
+
+function P:onShow()
+    -----------------
+    -- Display tab --
+    -----------------
+
+    -- fullscreen checkbox / resolution combobox / resolution editboxes
+    self:onWindowResized()
+
+    -- apply button
+    self.updateApplyButton()
+
+    -- aspect ratio editbox
+    local aspectRatioEditbox = winMgr:getWindow("orxonox/Display/Resolution/AspectRatio")
+    local currentAspectRatio = orxonox.CommandExecutor:query("getConfig Camera aspectRatio_")
+    aspectRatioEditbox:setText(currentAspectRatio)
+
+    -- themes combobox
+    local themeCombobox = winMgr:getWindow("orxonox/Display/Theme/Combobox")
+    local currentTheme = orxonox.CommandExecutor:query("getConfig GUIManager guiScheme_")
+
+    for i = 0, themeCombobox:getDropList():getItemCount() - 1 do
+        local item = themeCombobox:getListboxItemFromIndex(i)
+        themeCombobox:setItemSelectState(item, (item:getText() == currentTheme))
+    end
+
+    -- vsync checkbox
+    local vsyncCheckbox = winMgr:getWindow("orxonox/Display/More/VSync")
+    local hasVSync = orxonox.GraphicsManager:getInstance():hasVSyncEnabled()
+    CEGUI.toCheckbox(vsyncCheckbox):setSelected(hasVSync)
+
+    -- fsaa combobox
+    local fsaaCombobox = winMgr:getWindow("orxonox/Display/More/FSAA")
+    local currentFSAAMode = orxonox.GraphicsManager:getInstance():getFSAAMode()
+
+    for i = 0, fsaaCombobox:getDropList():getItemCount() - 1 do
+        local item = fsaaCombobox:getListboxItemFromIndex(i)
+        fsaaCombobox:setItemSelectState(item, (item:getText() == currentFSAAMode))
+    end
+
+    -- notice
+    self:updateRedLabel()
+
+    ------------------
+    -- Settings tab --
+    ------------------
+
+    -- fov editbox
+    local fovEditbox = winMgr:getWindow("orxonox/Settings/Fov")
+    local currentFov = orxonox.CommandExecutor:query("getConfig Camera fov_")
+    fovEditbox:setText(currentFov)
+
+    -- fps limit editbox
+    local fpsEditbox = winMgr:getWindow("orxonox/Settings/FpsLimit")
+    local currentFpsLimit = orxonox.CommandExecutor:query("getConfig GraphicsSettings fpsLimit")
+    fpsEditbox:setText(currentFpsLimit)
+
+    -- particle lod combobox
+    local particleLodCombobox = winMgr:getWindow("orxonox/Settings/ParticleLodCombobox")
+    local currentParticleLod = orxonox.CommandExecutor:query("getConfig GraphicsSettings particlesDetailLevel")
+
+    if currentParticleLod == "" then
+        particleLodCombobox:disable()
+    else
+        particleLodCombobox:enable()
+
+        for i = 0, particleLodCombobox:getDropList():getItemCount() - 1 do
+            local item = particleLodCombobox:getListboxItemFromIndex(i)
+            particleLodCombobox:setItemSelectState(item, (tostring(i) == currentParticleLod))
         end
     end
 
+    -- mesh lod checkbox
+    local meshLodCheckbox = winMgr:getWindow("orxonox/Settings/MeshLodCheckbox")
+    local hasMeshLod = orxonox.CommandExecutor:query("getConfig GraphicsSettings enableMeshLoD")
+    if hasMeshLod == "true" then
+        hasMeshLod = true
+    elseif hasMeshLod == "false" then
+        hasMeshLod = false
+    end
+    CEGUI.toCheckbox(meshLodCheckbox):setSelected(hasMeshLod)
+
+    -- motion blur checkbox
+    local motionBlurCheckbox = winMgr:getWindow("orxonox/Settings/MotionBlurCheckbox")
+    local hasMotionBlur = orxonox.CommandExecutor:query("getConfig GraphicsSettings enableMotionBlur")
+    if hasMotionBlur == "true" then
+        hasMotionBlur = true
+    elseif hasMotionBlur == "false" then
+        hasMotionBlur = false
+    end
+    CEGUI.toCheckbox(motionBlurCheckbox):setSelected(hasMotionBlur)
 end
 
-function P.ThemeDropBox_changed(e)
-    local dropbox = winMgr:getWindow("orxonox/ThemeDropBox")
-    local listbox = CEGUI.toListbox(dropbox)
-    local choice = listbox:getFirstSelectedItem()
-    local index = 0
-    if choice ~= nil then
-        index = listbox:getItemIndex(choice)
+function P:onWindowResized()
+    -- fullscreen checkbox
+    local fullscreenCheckbox = winMgr:getWindow("orxonox/Display/Resolution/Fullscreen")
+    local isFullscreen = orxonox.GraphicsManager:getInstance():isFullScreen()
+    CEGUI.toCheckbox(fullscreenCheckbox):setSelected(isFullscreen)
+
+    -- resolution combobox
+    local resolutionCombobox = winMgr:getWindow("orxonox/Display/Resolution/Combobox")
+
+    local currentWidth = orxonox.GraphicsManager:getInstance():getWindowWidth()
+    local currentHeight = orxonox.GraphicsManager:getInstance():getWindowHeight()
+
+    if P.forceResolutionEditboxes then
+        currentWidth = P.newWidth
+        currentHeight = P.newHeight
+        P.forceResolutionEditboxes = false
     end
-    orxonox.CommandExecutor:execute("config GUIManager guiScheme_ " .. P.schemeList[index+1])
+
+    local currentResolution = currentWidth .. " x " .. currentHeight
+
+    for i = 0, resolutionCombobox:getDropList():getItemCount() - 1 do
+        local item = resolutionCombobox:getListboxItemFromIndex(i)
+        resolutionCombobox:setItemSelectState(item, item:getText() == currentResolution)
+    end
+
+    -- resolution editboxes
+    self.updateResolutionEditboxes()
 end
 
-function P.GraphicsResolutionListbox_changed(e)
-    if listboxwindow:isItemSelected(0) then
-        resolution = "640 x 480"
-    elseif listboxwindow:isItemSelected(1) then
-        resolution = "720 x 480"
-    elseif listboxwindow:isItemSelected(2) then
-        resolution = "720 x 576"
-    elseif listboxwindow:isItemSelected(3) then
-        resolution = "800 x 480"
-    elseif listboxwindow:isItemSelected(4) then
-        resolution = "800 x 600"
-    elseif listboxwindow:isItemSelected(5) then
-        resolution = "1024 x 480"
-    elseif listboxwindow:isItemSelected(6) then
-        resolution = "1024 x 600"
-    elseif listboxwindow:isItemSelected(7) then
-        resolution = "1024 x 768"
-    elseif listboxwindow:isItemSelected(8) then
-        resolution = "1152 x 864"
-    elseif listboxwindow:isItemSelected(9) then
-        resolution = "1280 x 720"
-    elseif listboxwindow:isItemSelected(10) then
-        resolution = "1280 x 768"
-    elseif listboxwindow:isItemSelected(11) then
-        resolution = "1440 x 900"
-    end
-    search_mode = 0
-    f = io.open(file, "r")
-    firstline = f:read("*line")
-    text = firstline .. "\n"
-    rendersystem = string.sub(firstline, 15)
-    for line in f:lines() do
-        if search_mode == 0 then
-            if string.find(line, rendersystem) ~= nil then
-                search_mode = 1
-            end
+----------------------
+-- Helper functions --
+----------------------
+
+-- updates the text of the resolution checkboxes and checks if they should be enabled (only if the "custom" resolution was selected)
+function P.updateResolutionEditboxes()
+    -- resolution combobox
+    local resolutionCombobox = winMgr:getWindow("orxonox/Display/Resolution/Combobox")
+
+    local currentWidth = orxonox.GraphicsManager:getInstance():getWindowWidth()
+    local currentHeight = orxonox.GraphicsManager:getInstance():getWindowHeight()
+
+    -- resolution editboxes
+    local widthEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxWidth")
+    local heightEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxHeight")
+    widthEditbox:disable()
+    heightEditbox:disable()
+
+    -- selected combobox item
+    local item = resolutionCombobox:getSelectedItem()
+    if item then
+        local itemText = item:getText()
+        if itemText ~= "custom" then
+            currentWidth = string.sub(itemText, 1, string.find(itemText, "x") - 2)
+            currentHeight = string.sub(itemText, string.find(itemText, "x") + 2)
+        else
+            widthEditbox:enable()
+            heightEditbox:enable()
         end
-        if search_mode == 1 then
-            if string.sub(line, 1, 10) == "Video Mode" then
-                if string.match(line, "@") == "@" then
-                    line = "Video Mode=" .. resolution .. string.sub(line, string.find(line, "@")-1)
-                else
-                    line = "Video Mode=" .. resolution
-                end
-                search_mode = 2
-            end
-        end
-        text = text .. line .. "\n"
     end
-    f:close()
-    f = io.open(file, "w")
-    f:write(text)
-    f:close()
+
+    widthEditbox:setText(currentWidth)
+    heightEditbox:setText(currentHeight)
 end
 
-function P.GraphicsBrightnessScrollbar_changed(e)
-    if scrollbar_active == false then
-        -- brightness
-        logMessage(0, "event: brightness")
+-- checks if the apply button should be enabled or disabled (only enabled if the current settings are different from the selected values)
+function P.updateApplyButton()
+    -- fullscreen checkbox
+    local fullscreenCheckbox = winMgr:getWindow("orxonox/Display/Resolution/Fullscreen")
+    local isFullscreen = orxonox.GraphicsManager:getInstance():isFullScreen()
+    local fullscreenChanged = (isFullscreen ~= CEGUI.toCheckbox(fullscreenCheckbox):isSelected())
+
+    -- resolution editboxes
+    local widthEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxWidth")
+    local heightEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxHeight")
+    local currentWidth = tostring(orxonox.GraphicsManager:getInstance():getWindowWidth())
+    local currentHeight = tostring(orxonox.GraphicsManager:getInstance():getWindowHeight())
+    local widthChanged = (currentWidth ~= widthEditbox:getText())
+    local heightChanged = (currentHeight ~= heightEditbox:getText())
+    local resolutionEditboxesEnabled = not widthEditbox:isDisabled()
+
+    -- apply button
+    local applyButton = winMgr:getWindow("orxonox/Display/Resolution/Apply")
+
+    if fullscreenChanged or widthChanged or heightChanged or resolutionEditboxesEnabled then
+        applyButton:enable()
+    else
+        applyButton:disable()
     end
 end
 
-function P.GraphicsBrightnessScrollbar_started(e)
-    scrollbar_active = true
+function P.updateRedLabel()
+    -- theme
+    local themeCombobox = winMgr:getWindow("orxonox/Display/Theme/Combobox")
+    local currentTheme = orxonox.CommandExecutor:query("getConfig GUIManager guiScheme_")
+    local themeChanged = (currentTheme ~= themeCombobox:getText())
+
+    -- vsync
+    local vsyncCheckbox = winMgr:getWindow("orxonox/Display/More/VSync")
+    local hasVSync = orxonox.GraphicsManager:getInstance():hasVSyncEnabled()
+    local vsyncChanged = (hasVSync ~= CEGUI.toCheckbox(vsyncCheckbox):isSelected())
+
+    -- fsaa
+    local fsaaCombobox = winMgr:getWindow("orxonox/Display/More/FSAA")
+    local currentFSAAMode = orxonox.GraphicsManager:getInstance():getFSAAMode()
+    local fsaaChanged = (currentFSAAMode ~= fsaaCombobox:getText())
+
+    local needRestart = themeChanged or vsyncChanged or fsaaChanged
+
+    local notice = winMgr:getWindow("orxonox/Display/Notice")
+    notice:setVisible(not needRestart)
+    local noticeRed = winMgr:getWindow("orxonox/Display/NoticeRed")
+    noticeRed:setVisible(needRestart)
 end
 
-function P.GraphicsBrightnessScrollbar_ended(e)
-    -- brightness
-    logMessage(0, "event: brightness")
-    scrollbar_active = false
+---------------------
+-- Event callbacks --
+---------------------
+
+-- resolution
+
+function P.callback_FullscreenCheckbox_CheckStateChanged(e)
+    P.updateApplyButton()
 end
 
-function P.GraphicsFullscreenCheckbox_clicked(e)
-    if block == false then
-        search_mode = 0
-        f = io.open(file, "r")
-        firstline = f:read("*line")
-        text = firstline .. "\n"
-        rendersystem = string.sub(firstline, 15)
-        for line in f:lines() do
-            if search_mode == 0 then
-                if string.find(line, rendersystem) ~= nil then
-                    search_mode = 1
-                end
-            end
-            if search_mode == 1 then
-                if string.sub(line, 1, 11) == "Full Screen" then
-                    if fullscreen == true then
-                        line = "Full Screen=No"
-                        fullscreen = false
-                    else
-                        line = "Full Screen=Yes"
-                        fullscreen = true
-                    end
-                    search_mode = 2
-                end
-            end
-            text = text .. line .. "\n"
-        end
-        f:close()
-        f = io.open(file, "w")
-        f:write(text)
-        f:close()
+function P.callback_ResolutionCombobox_ListSelectionAccepted(e)
+    P.updateResolutionEditboxes()
+end
+
+function P.callback_ResolutionEditboxWidth_TextChanged(e)
+    P.updateApplyButton()
+end
+
+function P.callback_ResolutionEditboxHeight_TextChanged(e)
+    P.updateApplyButton()
+end
+
+-- theme
+
+function P.callback_ThemeCombobox_ListSelectionAccepted(e)
+    P.updateRedLabel()
+end
+
+-- vsync
+
+function P.callback_VSyncCheckbox_CheckStateChanged(e)
+    P.updateRedLabel()
+end
+
+-- fsaa
+
+function P.callback_FSAACombobox_ListSelectionAccepted(e)
+    P.updateRedLabel()
+end
+
+-- buttons
+
+function P.callback_Apply_Clicked(e)
+    -- resolution
+    local fullscreenCheckbox = winMgr:getWindow("orxonox/Display/Resolution/Fullscreen")
+    local checkedFullscreen = tostring(CEGUI.toCheckbox(fullscreenCheckbox):isSelected())
+
+    local widthEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxWidth")
+    local heightEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxHeight")
+
+    P.newWidth = widthEditbox:getText()
+    P.newHeight = heightEditbox:getText()
+    P.forceResolutionEditboxes = true
+
+    -- start revert timer
+    P.oldWidth = orxonox.GraphicsManager:getInstance():getWindowWidth()
+    P.oldHeight = orxonox.GraphicsManager:getInstance():getWindowHeight()
+    P.oldFullscreen = orxonox.GraphicsManager:getInstance():isFullScreen()
+
+    P.revertTimerHandle = orxonox.CommandExecutor:query("delayreal 10 {hideGUI DecisionPopup; GraphicsManager setScreenResolution " .. P.oldWidth .. " " .. P.oldHeight .. " " .. tostring(P.oldFullscreen) .. "; config Core lastLevelTimestamp_ [expr [getConfig Core ogreConfigTimestamp_] + 1]}")
+
+    -- change settings
+    orxonox.CommandExecutor:execute("GraphicsManager setScreenResolution " .. P.newWidth .. " " .. P.newHeight .. " " .. checkedFullscreen)
+
+    P.updateApplyButton()
+
+    -- prompt for confirmation
+    openDecisionPopup("Do you want to keep these settings? (Settings will be reverted in 10 seconds if not accepted)", GraphicsMenu.callback_ApplyDecisionPopup)
+    if checkedFullscreen then
+        showCursor()
     end
 end
 
-function P.GraphicsBackButton_clicked(e)
+function P.callback_ApplyDecisionPopup(pressedOK)
+    orxonox.CommandExecutor:execute("killdelay " .. P.revertTimerHandle)
+
+    if not pressedOK then
+        orxonox.CommandExecutor:execute("GraphicsManager setScreenResolution " .. P.oldWidth .. " " .. P.oldHeight .. " " .. tostring(P.oldFullscreen))
+        P:onShow()
+    end
+
+    -- update timestamp to avoid showing the ogre config dialog again after the user accepted or reverted the resolution
+    orxonox.CommandExecutor:execute("config Core lastLevelTimestamp_ [expr [getConfig Core ogreConfigTimestamp_] + 1]")
+end
+
+function P.callback_Ok_Clicked(e)
+    -- aspect ratio
+    local aspectRatioEditbox = winMgr:getWindow("orxonox/Display/Resolution/AspectRatio")
+    orxonox.CommandExecutor:execute("config Camera aspectRatio_ " .. aspectRatioEditbox:getText())
+
+    -- theme
+    local themeCombobox = winMgr:getWindow("orxonox/Display/Theme/Combobox")
+    orxonox.CommandExecutor:execute("config GUIManager guiScheme_ " .. themeCombobox:getText())
+
+    -- vsync
+    local vsyncCheckbox = winMgr:getWindow("orxonox/Display/More/VSync")
+    local hasVSync = orxonox.GraphicsManager:getInstance():hasVSyncEnabled()
+    if hasVSync ~= CEGUI.toCheckbox(vsyncCheckbox):isSelected() then
+        orxonox.CommandExecutor:execute("GraphicsManager setVSync " .. tostring(CEGUI.toCheckbox(vsyncCheckbox):isSelected()))
+    end
+
+    -- fsaa
+    local fsaaCombobox = winMgr:getWindow("orxonox/Display/More/FSAA")
+    local currentFSAAMode = orxonox.GraphicsManager:getInstance():getFSAAMode()
+    if currentFSAAMode ~= fsaaCombobox:getText() then
+        orxonox.CommandExecutor:execute("GraphicsManager setFSAA {" .. fsaaCombobox:getText() .. "}") -- enclose argument in { ... } because it can contain [brackets] (conflicts with tcl)
+    end
+
+    -- fov
+    local fovEditbox = winMgr:getWindow("orxonox/Settings/Fov")
+    orxonox.CommandExecutor:execute("config Camera fov_ " .. fovEditbox:getText())
+
+    -- fps limit
+    local fpsEditbox = winMgr:getWindow("orxonox/Settings/FpsLimit")
+    orxonox.CommandExecutor:execute("config GraphicsSettings fpsLimit " .. fpsEditbox:getText())
+
+    -- particle lod
+    local particleLodCombobox = winMgr:getWindow("orxonox/Settings/ParticleLodCombobox")
+    local item = particleLodCombobox:getSelectedItem()
+    if item then
+        orxonox.CommandExecutor:execute("config GraphicsSettings particlesDetailLevel " .. particleLodCombobox:getItemIndex(item))
+    end
+
+    -- mesh lod
+    local meshLodCheckbox = winMgr:getWindow("orxonox/Settings/MeshLodCheckbox")
+    orxonox.CommandExecutor:execute("config GraphicsSettings enableMeshLoD " .. tostring(CEGUI.toCheckbox(meshLodCheckbox):isSelected()))
+
+    -- motion blur
+    local motionBlurCheckbox = winMgr:getWindow("orxonox/Settings/MotionBlurCheckbox")
+    orxonox.CommandExecutor:execute("config GraphicsSettings enableMotionBlur " .. tostring(CEGUI.toCheckbox(motionBlurCheckbox):isSelected()))
+
     hideMenuSheet(P.name)
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 1)
+function P.callback_Cancel_Clicked(e)
+    hideMenuSheet(P.name)
 end
 
 return P

Modified: code/trunk/data/gui/scripts/HostMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/HostMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/HostMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -4,32 +4,36 @@
 
 P.multiplayerMode = "startServer"
 
-P.buttonList = {}
 P.levelList = {}
 P.itemList = {}
 P.showAll = false
 
 function P.onLoad()
-    P.multiplayerMode = "startServer" 
+    P.multiplayerMode = "startServer"
     local window = winMgr:getWindow("orxonox/MultiplayerShowAllCheckbox")
     local button = tolua.cast(window,"CEGUI::Checkbox")
     button:setSelected(false)
     P.createLevelList()
 
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/HostMenuStartButton"),
-            ["function"]  = P.HostMenuStartButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.HostMenuStartButton_clicked
+    })
 
-    local item = {
+    P:setButton(1, 2, {
             ["button"] = winMgr:getWindow("orxonox/HostMenuBackButton"),
-            ["function"]  = P.HostMenuBackButton_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.HostMenuBackButton_clicked
+    })
 end
 
 function P.onShow()
+    if P.showAll ~= orxonox.GUIManager:inDevMode() then
+        local window = winMgr:getWindow("orxonox/MultiplayerShowAllCheckbox")
+        local button = tolua.cast(window,"CEGUI::Checkbox")
+        P.showAll = not P.showAll
+        button:setSelected(P.showAll)
+    end
+
     if P.multiplayerMode == "startServer" then
         local window = winMgr:getWindow("orxonox/HostMenuHostButton")
         local button = tolua.cast(window,"CEGUI::RadioButton")
@@ -43,10 +47,6 @@
         button:setSelected(true)
         P.createLevelList()
     end
-
-    P.oldindex = -2
-    P.index = -1
-
 end
 
 function P.createLevelList()
@@ -96,7 +96,7 @@
     hideMenuSheet(P.name)
 end
 
-function P.HostMenuStartButton_clicked(e)    
+function P.HostMenuStartButton_clicked(e)
     local listbox = CEGUI.toListbox(winMgr:getWindow("orxonox/HostMenuListbox"))
     local choice = listbox:getFirstSelectedItem()
     if choice ~= nil then
@@ -118,8 +118,4 @@
    end
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 2)
-end
-
 return P

Modified: code/trunk/data/gui/scripts/InGameMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/InGameMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/InGameMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -3,44 +3,43 @@
 local P = createMenuSheet("InGameMenu")
 P.loadAlong = { "DecisionPopup" }
 
-P.buttonList = {}
-
 function P.onLoad()
-    P.multiplayerMode = "startClient" 
+    P.multiplayerMode = "startClient"
 
     --button are arranged in a 4x1 matrix, the left lower item is nil
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/InGameMenu_ReturnButton"),
-            ["function"]  = P.button_settings_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.button_return_clicked
+    })
 
-    local item = {
+    P:setButton(2, 1, {
             ["button"] = winMgr:getWindow("orxonox/InGameMenu_MainMenuButton"),
-            ["function"]  = P.button_mainmenu_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.button_mainmenu_clicked
+    })
 
-    local item = {
+    P:setButton(3, 1, {
             ["button"] = winMgr:getWindow("orxonox/InGameMenu_SettingsButton"),
-            ["function"]  = P.button_settings_clicked
-    }
-    P.buttonList[3] = item
+            ["callback"]  = P.button_settings_clicked
+    })
 
-    local item = {
+    P:setButton(4, 1, {
             ["button"] = winMgr:getWindow("orxonox/InGameMenu_QuitButton"),
-            ["function"]  = P.button_quit_clicked
-    }
-    P.buttonList[4] = item
-
+            ["callback"]  = P.button_quit_clicked
+    })
 end
 
 function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
+    if P:hasSelection() == false then
+        P:setSelection(1, 1)
+    end
+
+    orxonox.execute("setPause 1")
 end
 
+function P.onQuit()
+    orxonox.execute("setPause 0")
+end
+
 -- events for ingamemenu
 function P.button_quit_clicked(e)
     openDecisionPopup( "Do you really want to quit the game?", InGameMenu.callback )
@@ -63,14 +62,10 @@
     if doExit then
         hideMenuSheet("InGameMenu")
         orxonox.execute("exit")
-    else 
+    else
         P.onShow()
     end
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 4, 1)
-end
-
 return P
 

Modified: code/trunk/data/gui/scripts/KeyBindMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/KeyBindMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/KeyBindMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -25,7 +25,7 @@
     table.insert(commandList, "scale -1 rotatePitch")
     table.insert(commandList, "NewHumanController changeMode")
     table.insert(commandList, "switchCamera")
-    table.insert(commandList, "openConsole")
+    table.insert(commandList, "InGameConsole openConsole")
     table.insert(commandList, "OverlayGroup toggleVisibility Debug")
     table.insert(commandList, "OverlayGroup toggleVisibility Stats")
     table.insert(commandList, "OrxonoxOverlay toggleVisibility QuestGUI")
@@ -34,6 +34,10 @@
     table.insert(commandList, "startchat_small")
     table.insert(commandList, "mouseLook")
     table.insert(commandList, "pause")
+    table.insert(commandList, "printScreen")
+    if orxonox.GUIManager:inDevMode() then
+        table.insert(commandList, "printScreenHD 3")
+    end
 
     nameList = {}
     table.insert(nameList, "Primary Fire")
@@ -64,6 +68,10 @@
     table.insert(nameList, "Show small Chat")
     table.insert(nameList, "Look Around")
     table.insert(nameList, "Pause")
+    table.insert(nameList, "Screenshot")
+    if orxonox.GUIManager:inDevMode() then
+        table.insert(nameList, "HD screenshot")
+    end
 
     linesList = {}
 
@@ -99,6 +107,11 @@
 
     local funct = luaState:createLuaFunctor("KeyBindMenu.callback()")
     orxonox.KeyBinderManager:getInstance():registerKeybindCallback(funct)
+
+    P:setButton(1, 1, {
+            ["button"] = winMgr:getWindow("orxonox/KeyBindBackButton"),
+            ["callback"]  = P.KeyBindBackButton_clicked
+    })
 end
 
 function P.KeyNameNiceifier(key)

Modified: code/trunk/data/gui/scripts/MainMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/MainMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/MainMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -3,53 +3,39 @@
 local P = createMenuSheet("MainMenu")
 P.loadAlong = { "SingleplayerMenu", "MultiplayerMenu", "SettingsMenu", "CreditsMenu" }
 
-P.buttonList = {}
-
 function P.onLoad()
     --buttons are arranged in a 6x1 Matrix (list)
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/QuickGameTestButton"),
-            ["function"]  = P.QuickGameTestButton_clicked
-    }
-    table.insert(P.buttonList,item)
+            ["callback"]  = P.QuickGameTestButton_clicked
+    })
 
-    item = {
+    P:setButton(2, 1, {
             ["button"] = winMgr:getWindow("orxonox/SingleplayerButton"),
-            ["function"]  = P.SingleplayerButton_clicked
-    }
-    table.insert(P.buttonList,item)
+            ["callback"]  = P.SingleplayerButton_clicked
+    })
 
-    item = {
+    P:setButton(3, 1, {
             ["button"] = winMgr:getWindow("orxonox/MultiplayerButton"),
-            ["function"]  = P.MultiplayerButton_clicked
-    }
-    table.insert(P.buttonList,item)
+            ["callback"]  = P.MultiplayerButton_clicked
+    })
 
-    item = {
+    P:setButton(4, 1, {
             ["button"] = winMgr:getWindow("orxonox/SettingsButton"),
-            ["function"]  = P.SettingsButton_clicked
-    }
-    table.insert(P.buttonList,item)
+            ["callback"]  = P.SettingsButton_clicked
+    })
 
-    item = {
+    P:setButton(5, 1, {
             ["button"] = winMgr:getWindow("orxonox/CreditsButton"),
-            ["function"]  = P.CreditsButton_clicked
-    }
-    table.insert(P.buttonList,item)
+            ["callback"]  = P.CreditsButton_clicked
+    })
 
-    item = {
+    P:setButton(6, 1, {
             ["button"] = winMgr:getWindow("orxonox/ExitButton"),
-            ["function"]  = P.ExitButton_clicked
-    }
-    table.insert(P.buttonList,item) 
+            ["callback"]  = P.ExitButton_clicked
+    })
 end
 
-function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
-end
-
 -- events for MainMenu
 function P.QuickGameTestButton_clicked(e)
     hideAllMenuSheets()
@@ -76,9 +62,5 @@
     orxonox.execute("exit")
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 6, 1)
-end
-
 return P
 

Modified: code/trunk/data/gui/scripts/MiscConfigMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/MiscConfigMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/MiscConfigMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -34,6 +34,7 @@
     table.insert(P.commandList, "TeamDeathmatch teams_")
     table.insert(P.commandList, "HumanPlayer nick_")
     table.insert(P.commandList, "ChatOverlay displayTime_")
+    table.insert(P.commandList, "Core bDevMode_")
 
     P.nameList = {}
     table.insert(P.nameList, "Mouse sensitivity")
@@ -53,6 +54,7 @@
     table.insert(P.nameList, "TeamDeathmatch: Number of teams")
     table.insert(P.nameList, "Playername")
     table.insert(P.nameList, "Chat: display time")
+    table.insert(P.nameList, "Developer's Mode")
 
     P.linesList = {}
 
@@ -84,6 +86,10 @@
 
     P.createLines()
 
+    P:setButton(1, 1, {
+            ["button"] = winMgr:getWindow("orxonox/MiscConfigMenu/MiscConfigBackButton"),
+            ["callback"]  = P.MiscConfigBackButton_clicked
+    })
 end
 
 function P.createLine(k)

Modified: code/trunk/data/gui/scripts/MouseControlsMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/MouseControlsMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/MouseControlsMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -31,6 +31,11 @@
     else
         invert_active = false
     end
+
+    P:setButton(1, 1, {
+            ["button"] = winMgr:getWindow("orxonox/MouseControlsBackButton"),
+            ["callback"]  = P.MouseControlsBackButton_clicked
+    })
 end
 
 function P.MouseControlsMouseNormalScrollbar_changed(e)

Modified: code/trunk/data/gui/scripts/MultiplayerMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/MultiplayerMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/MultiplayerMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -2,42 +2,33 @@
 
 local P = createMenuSheet("MultiplayerMenu")
 
-P.buttonList = {}
-
 --joinMode is 1 for choice "LAN" and 2 for "Internet"
 --initial status 1
 P.joinMode = 1
 
 function P.onLoad()
-    P.multiplayerMode = "startClient" 
+    P.multiplayerMode = "startClient"
 
-    --button are arranged in a 2x2 matrix, the left lower item is nil
-    local item = {
+    --button are arranged in a 3x2 matrix, Join and Host buttons are in the upper left and middle, the back button in the lower right of the table
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/MultiplayerJoinButton"),
-            ["function"]  = P.MultiplayerJoinButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.MultiplayerJoinButton_clicked
+    })
 
-    local item = {
+    P:setButton(1, 2, {
             ["button"] = winMgr:getWindow("orxonox/MultiplayerHostButton"),
-            ["function"]  = P.MultiplayerHostButton_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.MultiplayerHostButton_clicked
+    })
 
-    local item = {
+    P:setButton(2, 3, {
             ["button"] = winMgr:getWindow("orxonox/MultiplayerBackButton"),
-            ["function"]  = P.MultiplayerBackButton_clicked
-    }
-    P.buttonList[4] = item
+            ["callback"]  = P.MultiplayerBackButton_clicked
+    })
 end
 
 function P.onShow()
     --P.showServerList()
 
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
-    
     if P.joinMode == 1 then
         local window = winMgr:getWindow("orxonox/MultiplayerLanButton")
         local button = tolua.cast(window,"CEGUI::RadioButton")
@@ -55,7 +46,7 @@
     local button = tolua.cast(we.window,"CEGUI::RadioButton")
     P.joinMode = 1
     if button:isSelected() == true then
-	    P.showServerList()
+        P.showServerList()
     end
 end
 
@@ -64,8 +55,8 @@
     local button = tolua.cast(we.window,"CEGUI::RadioButton")
     P.joinMode = 2
     if button:isSelected() == true then
-	    P.showServerList()
-	end
+        P.showServerList()
+    end
 end
 
 function P.MultiplayerHostButton_clicked(e)
@@ -91,74 +82,70 @@
 end
 
 function P.showServerList()
-	-- LAN Discovery
-	if P.joinMode == 1 then
-		local listbox = winMgr:getWindow("orxonox/MultiplayerListbox")
-		CEGUI.toListbox(listbox):resetList()
-		local discovery = orxonox.LANDiscovery:getInstance()
-		discovery:discover()
-		P.serverList = {}
-		local index = 0
-		local servername = ""
-		local serverip = ""
-		while true do
-		    servername = discovery:getServerListItemName(index)
-		    if servername == "" then
-		        break
-		    end
-		    serverip = discovery:getServerListItemIP(index)
-		    if serverip == "" then
-		      break
-		    end
-		    table.insert(P.serverList, {servername, serverip})
-		    index = index + 1
-		end
-		index = 1
-		for k,v in pairs(P.serverList) do
-		    local item = CEGUI.createListboxTextItem( v[1] .. ": " .. v[2] )
-		    item:setID(index)
-		    index = index + 1
-		    item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
-		    CEGUI.toListbox(listbox):addItem(item)
-		end
-	-- WAN Discovery
-	elseif P.joinMode == 2 then
-		local listbox = winMgr:getWindow("orxonox/MultiplayerListbox")
-		CEGUI.toListbox(listbox):resetList()
-		local discovery = orxonox.WANDiscovery:getInstance()
-		cout(0, "discovering.\n" )
-		discovery:discover()
-		cout(0, "discovered.\n" )
-		P.serverList = {}
-		local index = 0
-		local servername = ""
-		local serverip = ""
-		while true do
-		    servername = discovery:getServerListItemName(index)
-		    if servername == "" then
-		        break
-		    end
-		    serverip = discovery:getServerListItemIP(index)
-		    if serverip == "" then
-		      break
-		    end
-		    table.insert(P.serverList, {servername, serverip})
-		    index = index + 1
-		end
-		index = 1
-		for k,v in pairs(P.serverList) do
-		    local item = CEGUI.createListboxTextItem( v[1] .. ": " .. v[2] )
-		    item:setID(index)
-		    index = index + 1
-		    item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
-		    CEGUI.toListbox(listbox):addItem(item)
-		end
-	end
-	
-end
+    -- LAN Discovery
+    if P.joinMode == 1 then
+        local listbox = winMgr:getWindow("orxonox/MultiplayerListbox")
+        CEGUI.toListbox(listbox):resetList()
+        local discovery = orxonox.LANDiscovery:getInstance()
+        discovery:discover()
+        P.serverList = {}
+        local index = 0
+        local servername = ""
+        local serverip = ""
+        while true do
+            servername = discovery:getServerListItemName(index)
+            if servername == "" then
+                break
+            end
+            serverip = discovery:getServerListItemIP(index)
+            if serverip == "" then
+                break
+            end
+            table.insert(P.serverList, {servername, serverip})
+            index = index + 1
+        end
+        index = 1
+        for k,v in pairs(P.serverList) do
+            local item = CEGUI.createListboxTextItem( v[1] .. ": " .. v[2] )
+            item:setID(index)
+            index = index + 1
+            item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+            CEGUI.toListbox(listbox):addItem(item)
+        end
+    -- WAN Discovery
+    elseif P.joinMode == 2 then
+        local listbox = winMgr:getWindow("orxonox/MultiplayerListbox")
+        CEGUI.toListbox(listbox):resetList()
+        local discovery = orxonox.WANDiscovery:getInstance()
+        cout(0, "discovering.\n" )
+        discovery:discover()
+        cout(0, "discovered.\n" )
+        P.serverList = {}
+        local index = 0
+        local servername = ""
+        local serverip = ""
+        while true do
+            servername = discovery:getServerListItemName(index)
+            if servername == "" then
+                break
+            end
+            serverip = discovery:getServerListItemIP(index)
+            if serverip == "" then
+                break
+            end
+            table.insert(P.serverList, {servername, serverip})
+            index = index + 1
+        end
+        index = 1
+        for k,v in pairs(P.serverList) do
+            local item = CEGUI.createListboxTextItem( v[1] .. ": " .. v[2] )
+            item:setID(index)
+            index = index + 1
+            item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+            CEGUI.toListbox(listbox):addItem(item)
+        end
+    end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 2, 2)
 end
 
 return P

Modified: code/trunk/data/gui/scripts/NotificationLayer.lua
===================================================================
--- code/trunk/data/gui/scripts/NotificationLayer.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/NotificationLayer.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -45,7 +45,7 @@
     P.queueList[queueName] = nil
 end
 
--- Pushes an input notification to the input queue. 
+-- Pushes an input notification to the input queue.
 function P.pushNotification(queueName, notification)
     local queue = P.queueList[queueName]
     if queue == nil then
@@ -332,7 +332,7 @@
 end
 
 -- Is called after the sheet has been hidden.
-function P.afterHide()
+function P.onQuit()
     -- If we leave the edit mode we show the sheet again.
     if P.editMode then
         P.leaveEditMode()

Modified: code/trunk/data/gui/scripts/SettingsMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/SettingsMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/SettingsMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -3,50 +3,37 @@
 local P = createMenuSheet("SettingsMenu")
 P.loadAlong = { "ControlsMenu", "AudioMenu", "GraphicsMenu" }
 
-P.buttonList = {}
-
 function P.onLoad()
     --"Gameplay" and "Multiplayer Options" are not integrated in the list
-    --buttons are arranged in a 4x2 matrix. The lower-right element is not in the matrix!
-    local item = {
+    --buttons are arranged in a 4x2 matrix.
+    P:setButton(1, 2, {
             ["button"] = winMgr:getWindow("orxonox/SettingsMenu/GraphicsButton"),
-            ["function"]  = P.SettingsGraphicsButton_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.SettingsGraphicsButton_clicked
+    })
 
-    local item = {
+    P:setButton(2, 2, {
             ["button"] = winMgr:getWindow("orxonox/SettingsMenu/AudioButton"),
-            ["function"]  = P.SettingsAudioButton_clicked
-    }
-    P.buttonList[4] = item
+            ["callback"]  = P.SettingsAudioButton_clicked
+    })
 
-
-    local item = {
+    P:setButton(3, 1, {
             ["button"] = winMgr:getWindow("orxonox/SettingsMenu/ControlsButton"),
-            ["function"]  = P.SettingsControlsButton_clicked
-    }
-    P.buttonList[5] = item
+            ["callback"]  = P.SettingsControlsButton_clicked
+    })
 
-    local item = {
+    P:setButton(3, 2, {
             ["button"] = winMgr:getWindow("orxonox/SettingsMenu/MiscellaneousButton"),
-            ["function"]  = P.SettingsMiscellaneousButton_clicked
-    }
-    P.buttonList[6] = item
+            ["callback"]  = P.SettingsMiscellaneousButton_clicked
+    })
 
-    local item = {
+    P:setButton(4, 1, {
             ["button"] = winMgr:getWindow("orxonox/SettingsMenu/SettingsBackButton"),
-            ["function"]  = P.SettingsBackButton_clicked
-    }
-    P.buttonList[7] = item
+            ["callback"]  = P.SettingsBackButton_clicked
+    })
 
+    P:setButton(4, 2, P:getButton(4, 1))
 end
 
-function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = 3
-    P.index = 2
-end
-
 function P.SettingsGameplayButton_clicked(e)
     showMenuSheet("GameplayMenu", true)
 end
@@ -75,9 +62,5 @@
     hideMenuSheet(P.name)
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 4, 2)
-end
-
 return P
 

Modified: code/trunk/data/gui/scripts/SheetManager.lua
===================================================================
--- code/trunk/data/gui/scripts/SheetManager.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/SheetManager.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -7,28 +7,24 @@
 local bInGameConsoleClosed = false
 local mainMenuLoaded = false
 orxonox.GUIManager:subscribeEventHelper(menuSheetsRoot, "KeyDown", "keyPressed")
+orxonox.GUIManager:subscribeEventHelper(menuSheetsRoot, "Sized", "windowResized")
 
------------------------
---- Local functions ---
------------------------
+------------------------
+--- Global functions ---
+------------------------
 
-local function hideCursor()
+function hideCursor()
     if cursor:isVisible() then
         cursor:hide()
     end
 end
 
-local function showCursor()
+function showCursor()
     if not cursor:isVisible() and inputMgr:isMouseExclusive() then
         cursor:show()
     end
 end
 
-
-------------------------
---- Global functions ---
-------------------------
-
 -- Loads the GUI with the specified name
 -- The name corresponds to the filename of the *.lua and *.layout files
 -- but without the extension
@@ -92,7 +88,8 @@
     {
         ["sheet"]          = menuSheet,
         ["bHidePrevious"]  = bHidePrevious,
-        ["bNoInput"]       = bNoInput
+        ["bNoInput"]       = bNoInput,
+        ["name"]           = name
     }
     table.insert(activeMenuSheets, sheetTuple) -- indexed array access
     activeMenuSheets[name] = sheetTuple -- name access
@@ -120,15 +117,22 @@
     end
 
     -- Hide all previous sheets if necessary
+    local previous
     if bHidePrevious then
         for i = 1, activeMenuSheets.size - 1 do
-            activeMenuSheets[i].sheet:hide()
+            previous = activeMenuSheets[i].sheet
+            previous:hide()
         end
     end
-    
+
     menuSheet:show()
     menuSheetsRoot:activate()
 
+    -- select first button if the menu was opened with the keyboard
+    if previous and previous.pressedEnter and menuSheet:hasSelection() == false then
+        menuSheet:setSelectionNear(1, 1)
+    end
+
     return menuSheet
 end
 
@@ -178,7 +182,7 @@
     if not sheetTuple.bNoInput then
         inputMgr:leaveState(sheetTuple.sheet.inputState)
     end
-    
+
     -- CURSOR SHOWING
     local i = activeMenuSheets.size
     -- Find top most sheet that doesn't have tShowCusor == TriBool.Dontcare
@@ -199,7 +203,7 @@
         hideCursor()
     end
 
-    sheetTuple.sheet:afterHide()
+    sheetTuple.sheet:quit()
 end
 
 -- Hides all menu GUI sheets
@@ -241,12 +245,31 @@
         if code == "1" then
             keyESC()
         elseif code == "0"then
-            orxonox.CommandExecutor:execute("openConsole")
+            orxonox.CommandExecutor:execute("InGameConsole openConsole")
         end
     end
-    sheet.sheet:onKeyPressed()
+    sheet.sheet:keyPressed()
 end
 
+function windowResized(e)
+    for name, sheet in pairs(loadedSheets) do
+        if orxonox.GraphicsManager:getInstance():isFullScreen() or sheet.tShowCursor == TriBool.False then
+            inputMgr:setMouseExclusive(sheet.inputState, TriBool.True)
+        else
+            inputMgr:setMouseExclusive(sheet.inputState, TriBool.False)
+        end
+    end
+    local sheetTuple = activeMenuSheets[activeMenuSheets.size]
+    if sheetTuple then
+        if orxonox.GraphicsManager:getInstance():isFullScreen() and sheetTuple.sheet.tShowCursor ~= TriBool.False then
+            showCursor()
+        else
+            hideCursor()
+        end
+        sheetTuple.sheet:windowResized()
+    end
+end
+
 function setBackgroundImage(imageSet, imageName)
     guiMgr:setBackgroundImage(imageSet, imageName)
 end
@@ -275,6 +298,16 @@
     bInGameConsoleClosed = not bInGameConsoleClosed;
 end
 
+function getGUIFirstActive(name, bHidePrevious, bNoInput)
+    local sheet = activeMenuSheets.topSheetTuple
+    -- If the topmost gui sheet has the input name
+    if sheet ~= nil and sheet.name == name then
+        guiMgr:toggleGUIHelper(name, bHidePrevious, bNoInput, false);
+    else
+        guiMgr:toggleGUIHelper(name, bHidePrevious, bNoInput, true);
+    end
+end
+
 ----------------------
 --- Initialisation ---
 ----------------------

Modified: code/trunk/data/gui/scripts/SingleplayerMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/SingleplayerMenu.lua	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/gui/scripts/SingleplayerMenu.lua	2011-03-15 20:47:11 UTC (rev 8079)
@@ -2,7 +2,6 @@
 
 local P = createMenuSheet("SingleplayerMenu")
 
-P.buttonList = {}
 P.levelList = {}
 P.itemList = {}
 P.showAll = false
@@ -14,19 +13,27 @@
     P.createLevelList()
 
     --buttons are arranged in a 1x2 matrix
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/SingleplayerStartButton"),
-            ["function"]  = P.SingleplayerStartButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.SingleplayerStartButton_clicked
+    })
 
-    local item = {
+    P:setButton(1, 2, {
             ["button"] = winMgr:getWindow("orxonox/SingleplayerBackButton"),
-            ["function"]  = P.SingleplayerBackButton_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.SingleplayerBackButton_clicked
+    })
 end
 
+function P.onShow()
+    if P.showAll ~= orxonox.GUIManager:inDevMode() then
+        local window = winMgr:getWindow("orxonox/SingleplayerShowAllCheckbox")
+        local button = tolua.cast(window,"CEGUI::Checkbox")
+        P.showAll = not P.showAll
+        button:setSelected(P.showAll)
+        P.createLevelList()
+    end
+end
+
 function P.createLevelList()
     P.levelList = {}
     P.itemList = {}
@@ -46,8 +53,6 @@
         end
         index = index + 1
     end
-    --TODO: Reintroduce sorting, if needed. At the moment it's sorted by filename.
-    --table.sort(levelList)
     for k,v in pairs(P.levelList) do
         local item = CEGUI.createListboxTextItem(v:getName())
         item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
@@ -60,12 +65,6 @@
     end
 end
 
-function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
-end
-
 function P.SingleplayerStartButton_clicked(e)
     local listbox = CEGUI.toListbox(winMgr:getWindow("orxonox/SingleplayerLevelListbox"))
     local choice = listbox:getFirstSelectedItem()
@@ -92,9 +91,5 @@
     hideMenuSheet(P.name)
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 2)
-end
-
 return P
 

Modified: code/trunk/data/levels/FPSTest.oxw
===================================================================
--- code/trunk/data/levels/FPSTest.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/FPSTest.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -56,7 +56,7 @@
 ?>
   <MovableEntity position="<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000 - 2000) ?>" collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 100) ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>" >
       <attached>
-        <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+        <Model position="0,0,0" scale="<?lua print(j * 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
       </attached>
       <collisionShapes>
         <SphereCollisionShape radius="<?lua print(j * 100) ?>" />

Modified: code/trunk/data/levels/asteroids.oxw
===================================================================
--- code/trunk/data/levels/asteroids.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/asteroids.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -34,12 +34,12 @@
       collisionType = dynamic
       linearDamping = 0.8
       angularDamping = 0
-      scale = <?lua print(j * 150)?>
+      scale = "<?lua print(j * 150)?>"
       collisiondamage = 1
       enablecollisiondamage = true
     >
       <attached>
-        <Model mass=<?lua print(j * 1000) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+        <Model mass="<?lua print(j * 1000) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
       </attached>
       <collisionShapes>
         <SphereCollisionShape radius="<?lua print(j * 350) ?>" />

Modified: code/trunk/data/levels/dynamicMatch.oxw
===================================================================
--- code/trunk/data/levels/dynamicMatch.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/dynamicMatch.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -79,9 +79,9 @@
 j = math.random()
 ?>
 
-    <StaticEntity position="<?lua print(x + math.random() * 1000-500) ?>,<?lua print(y + math.random() * 1000-500) ?>,<?lua print(z + math.random() * 5000-2500) ?>" scale=<?lua print(j * 5) ?> >
+    <StaticEntity position="<?lua print(x + math.random() * 1000-500) ?>,<?lua print(y + math.random() * 1000-500) ?>,<?lua print(z + math.random() * 5000-2500) ?>" scale="<?lua print(j * 5) ?>" >
       <attached>
-        <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh">
+        <Model position="0,0,0" scale="<?lua print(j * 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh">
 	  <attached><!-- ---------asteroid fog----- -->
             <ParticleEmitter position="0,0,0" source="Orxonox/Steam" />
           </attached>

Modified: code/trunk/data/levels/fightInOurBack.oxw
===================================================================
--- code/trunk/data/levels/fightInOurBack.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/fightInOurBack.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -171,7 +171,7 @@
     <EventTrigger name="activateTeam1No1" acitvations=1 stayactive="true">
     <events>
     <trigger>
-        <SpaceShip position="<?lua print(3800-i*x) ?>,0,3000" lookat="<?lua print(4800-i*x) ?>,0,4000" health=<?lua print(health) ?> maxhealth=<?lua print(health) ?> initialhealth=<?lua print(health) ?> >
+        <SpaceShip position="<?lua print(3800-i*x) ?>,0,3000" lookat="<?lua print(4800-i*x) ?>,0,4000" health="<?lua print(health) ?>" maxhealth="<?lua print(health) ?>" initialhealth="<?lua print(health) ?>" >
             <templates>
                    <Template link=spaceshipTransporter />
              </templates>
@@ -198,7 +198,7 @@
     <EventTrigger name="activateTeam1No1" acitvations=1 stayactive="true">
     <events>
     <trigger>
-        <SpaceShip position="<?lua print(2600+x) ?>,0,<?lua print(3150-z) ?>" lookat="<?lua print(3500+x) ?>,0,<?lua print(4150-z) ?>" health=<?lua print(health) ?> maxhealth=<?lua print(health) ?> initialhealth=<?lua print(health) ?> >
+        <SpaceShip position="<?lua print(2600+x) ?>,0,<?lua print(3150-z) ?>" lookat="<?lua print(3500+x) ?>,0,<?lua print(4150-z) ?>" health="<?lua print(health) ?>" maxhealth="<?lua print(health) ?>" initialhealth="<?lua print(health) ?>" >
             <templates>
                    <Template link=spaceshipTransporter />
              </templates>
@@ -283,7 +283,7 @@
 ?>
 <MovableEntity collisionType=kinematic linearDamping=0.8 angularDamping=0 mass="<?lua print(scale * 5) ?>" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" rotationaxis="<?lua print(math.random()) ?>,<?lua print(math.random()) ?>,<?lua print(math.random()) ?>" rotationrate="<?lua print(math.random()*15) ?>">
     <attached>
-        <Model scale=<?lua print(scale) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false/>
+        <Model scale="<?lua print(scale) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false/>
     </attached>
     <collisionShapes>
         <SphereCollisionShape radius="<?lua print(scale * 3) ?>" />
@@ -302,7 +302,7 @@
 ?>
 <MovableEntity collisionType=kinematic linearDamping=0.8 angularDamping=0 mass="<?lua print(scale * 5) ?>" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" rotationaxis="<?lua print(math.random()) ?>,<?lua print(math.random()) ?>,<?lua print(math.random()) ?>" rotationrate="<?lua print(math.random()*15) ?>" >
     <attached>
-        <Model scale=<?lua print(math.random(20,70)) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false/>
+        <Model scale="<?lua print(math.random(20,70)) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false/>
     </attached>
     <collisionShapes>
             <SphereCollisionShape radius="<?lua print(scale * 3) ?>" />

Modified: code/trunk/data/levels/lastManStanding.oxw
===================================================================
--- code/trunk/data/levels/lastManStanding.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/lastManStanding.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -75,7 +75,7 @@
 
     <SpawnPoint team=0 position="<?lua print(y*1.4+z*0.2) ?>,0,<?lua print(z*1.4-y*0.2) ?>" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
 
-    <StaticEntity position="<?lua print(y) ?>,0,<?lua print(z) ?>" scale=<?lua print(j * 2) ?> collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,0,<?lua print(z) ?>" scale="<?lua print(j * 2) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=15 mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh">
 	</Model>
@@ -85,7 +85,7 @@
       </collisionShapes>
     </StaticEntity>
 
-    <StaticEntity position="<?lua print(y) ?>,100,<?lua print(z) ?>" scale=<?lua print(j * 2) ?> collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,100,<?lua print(z) ?>" scale="<?lua print(j * 2) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=15 mesh="ast<?lua print( math.mod(i+3,6) + 1) ?>.mesh">
 	</Model>
@@ -95,7 +95,7 @@
       </collisionShapes>
     </StaticEntity>
 
-    <StaticEntity position="<?lua print(y) ?>,200,<?lua print(z) ?>" scale=<?lua print(j * 2) ?> collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,200,<?lua print(z) ?>" scale="<?lua print(j * 2) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=15 mesh="ast<?lua print( math.mod(i*5,6) + 1) ?>.mesh">
 	</Model>
@@ -105,7 +105,7 @@
       </collisionShapes>
     </StaticEntity>
 
-    <StaticEntity position="<?lua print(y) ?>,-100,<?lua print(z) ?>" scale=<?lua print(j * 2) ?> collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,-100,<?lua print(z) ?>" scale="<?lua print(j * 2) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=15 mesh="ast<?lua print( math.mod(i*13+1,6) + 1) ?>.mesh">
 	</Model>
@@ -115,7 +115,7 @@
       </collisionShapes>
     </StaticEntity>
 
-    <StaticEntity position="<?lua print(y) ?>,-200,<?lua print(z) ?>" scale=<?lua print(j * 2) ?> collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,-200,<?lua print(z) ?>" scale="<?lua print(j * 2) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=15 mesh="ast<?lua print( math.mod(i*17,6) + 1) ?>.mesh">
 	</Model>
@@ -126,7 +126,7 @@
     </StaticEntity>
 
 <!-- ---------Top Asteroid----------- -->
-    <StaticEntity position="<?lua print(y) ?>,300,<?lua print(z) ?>" scale=<?lua print(j * 2.1) ?> pitch="90" roll="180" yaw="<?lua print(-90+i*360/max) ?>" collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,300,<?lua print(z) ?>" scale="<?lua print(j * 2.1) ?>" pitch="90" roll="180" yaw="<?lua print(-90+i*360/max) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=25 mesh="ast6.mesh">
 	</Model>

Modified: code/trunk/data/levels/presentation09.oxw
===================================================================
--- code/trunk/data/levels/presentation09.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/presentation09.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,6 +1,6 @@
 <LevelInfo
- name = "Presentation X"
- description = "1st Presentation level for Orxonox Convention X"
+ name = "Presentation X 3rd"
+ description = "3rd Presentation level for Orxonox Convention X"
  tags = "presentation"
 />
 
@@ -46,9 +46,9 @@
         j = math.random()
       ?>
 
-      <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 50) ?> <?lua end ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+      <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass="<?lua print(j * 50) ?>" <?lua end ?> scale="<?lua print(j * 5) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+          <Model position="0,0,0" scale="<?lua print(j * 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
         </attached>
         <?lua if i == 5 then ?><collisionShapes>
           <SphereCollisionShape radius="<?lua print(j * 70) ?>" />

Modified: code/trunk/data/levels/presentation09b.oxw
===================================================================
--- code/trunk/data/levels/presentation09b.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/presentation09b.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -280,7 +280,7 @@
             position="<?lua print(200-270/8*i)?> ,15,2"
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
             quadratic=1
@@ -290,7 +290,7 @@
             position="<?lua print(200-270/8*i)?>,-15,2"
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
             quadratic=1
@@ -356,7 +356,7 @@
     ?>
       <MovableEntity position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.8 angularDamping=0.8 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 - 15) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(s) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+          <Model position="0,0,0" scale="<?lua print(s) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
         </attached>
       </MovableEntity>
     <?lua end ?>

Modified: code/trunk/data/levels/presentationDM.oxw
===================================================================
--- code/trunk/data/levels/presentationDM.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/presentationDM.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -45,9 +45,9 @@
       for i = 1, 100, 1 do
         j = math.random()
     ?>
-      <MovableEntity position="<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000 - 2000) ?>" collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 50) ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+      <MovableEntity position="<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000 - 2000) ?>" collisionType=dynamic linearDamping=0.8 angularDamping=0 mass="<?lua print(j * 50) ?>" scale="<?lua print(j * 5) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+          <Model position="0,0,0" scale="<?lua print(j * 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
         </attached>
         <collisionShapes>
           <SphereCollisionShape radius="<?lua print(j * 70) ?>" />

Modified: code/trunk/data/levels/presentationFS102.oxw
===================================================================
--- code/trunk/data/levels/presentationFS102.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/presentationFS102.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,5 +1,5 @@
 <LevelInfo
- name = "Presentation XI FPS"
+ name = "Presentation XI FPS 1st"
  description = "2nd Presentation level for Orxonox Convention XI, FPS"
  tags = "presentation"
 />

Modified: code/trunk/data/levels/presentationFS10Ed.oxw
===================================================================
--- code/trunk/data/levels/presentationFS10Ed.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/presentationFS10Ed.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,5 +1,5 @@
 <LevelInfo
- name = "Presentation XI FPS"
+ name = "Presentation XI FPS 2nd"
  description = "3rd Presentation level for Orxonox Convention XI, FPS"
  tags = "presentation"
 />

Modified: code/trunk/data/levels/presentationHS09.oxw
===================================================================
--- code/trunk/data/levels/presentationHS09.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/presentationHS09.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,5 +1,5 @@
 <LevelInfo
- name = "Presentation X"
+ name = "Presentation X 1st"
  description = "1st Presentation level for Orxonox Convention X"
  tags = "presentation"
 />
@@ -192,7 +192,7 @@
           <Template link=spaceshipassff />
         </templates>
         <controller>
-          <WaypointPatrolController name=attacker alertnessradius=<?lua print(math.random() * 2000) ?> team=0 active=false>
+          <WaypointPatrolController name=attacker alertnessradius="<?lua print(math.random() * 2000) ?>" team=0 active=false>
             <waypoints>
               <StaticEntity position="<?lua print(2800 + math.random() * 500 - 250) ?>,<?lua print(2500 + math.random() * 500 - 250) ?>,<?lua print(1500 + math.random() * 500 - 250) ?>" />
               <StaticEntity position="<?lua print(5000 + math.random() * 500 - 250) ?>,<?lua print(0 + math.random() * 500 - 250) ?>,<?lua print(0 + math.random() * 500 - 250) ?>" />
@@ -283,7 +283,7 @@
             position="<?lua print(200-270/8*i)?> ,15,2"
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
             quadratic=1
@@ -293,7 +293,7 @@
             position="<?lua print(200-270/8*i)?>,-15,2"
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
             quadratic=1
@@ -367,7 +367,7 @@
     ?>
       <MovableEntity mass=90000 position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.8 angularDamping=0.8 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(s) ?> mesh="<?lua print(elements[e])?>" />
+          <Model position="0,0,0" scale="<?lua print(s) ?>" mesh="<?lua print(elements[e])?>" />
         </attached>
       </MovableEntity>
     <?lua end ?>

Modified: code/trunk/data/levels/presentationHS09b.oxw
===================================================================
--- code/trunk/data/levels/presentationHS09b.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/presentationHS09b.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -1,5 +1,5 @@
 <LevelInfo
- name = "Presentation X"
+ name = "Presentation X 2nd"
  description = "2nd Presentation level for Orxonox Convention X"
  tags = "presentation"
 />
@@ -45,9 +45,9 @@
         z = math.random() * 2000 - 1000
         s = math.random() * 100
     ?>
-      <MovableEntity collisiontype=dynamic mass=<?lua print(s*10)?> position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.01 angularDamping=0 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
+      <MovableEntity collisiontype=dynamic mass="<?lua print(s*10)?>" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.01 angularDamping=0 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(s) ?> mesh="asteroid_UV.mesh" />
+          <Model position="0,0,0" scale="<?lua print(s) ?>" mesh="asteroid_UV.mesh" />
         </attached>
         <collisionShapes>
           <SphereCollisionShape radius="<?lua print(s*0.9) ?>" />
@@ -144,7 +144,7 @@
             position="<?lua print(200-270/8*i)?> ,15,2"
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
             quadratic=1
@@ -154,7 +154,7 @@
             position="<?lua print(200-270/8*i)?>,-15,2"
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
             quadratic=1
@@ -202,9 +202,9 @@
         z = math.random() * 2000 - 1000
         s = math.random() * 100
     ?>
-      <MovableEntity collisiontype=dynamic mass=<?lua print(s*10)?> position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.01 angularDamping=0 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
+      <MovableEntity collisiontype=dynamic mass="<?lua print(s*10)?>" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.01 angularDamping=0 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(s) ?> mesh="asteroid_ice.mesh" />
+          <Model position="0,0,0" scale="<?lua print(s) ?>" mesh="asteroid_ice.mesh" />
         </attached>
         <collisionShapes>
           <SphereCollisionShape radius="<?lua print(s*0.9)?>" />

Modified: code/trunk/data/levels/teamBaseMatch.oxw
===================================================================
--- code/trunk/data/levels/teamBaseMatch.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/teamBaseMatch.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -55,7 +55,7 @@
         <?lua
           for i = 1, 10, 1 do
         ?>
-          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay="<?lua print(math.random()) ?>" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
             <events>
               <spawn>
                 <EventListener event="base 1" />
@@ -96,7 +96,7 @@
         <?lua
           for i = 1, 10, 1 do
         ?>
-          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay="<?lua print(math.random()) ?>" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
             <events>
               <spawn>
                 <EventListener event="base 2" />
@@ -137,7 +137,7 @@
         <?lua
           for i = 1, 10, 1 do
         ?>
-          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay="<?lua print(math.random()) ?>" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
             <events>
               <spawn>
                 <EventListener event="base 3" />
@@ -177,7 +177,7 @@
         <?lua
           for i = 1, 10, 1 do
         ?>
-          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay="<?lua print(math.random()) ?>" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
             <events>
               <spawn>
                 <EventListener event="base 4" />
@@ -218,7 +218,7 @@
         <?lua
           for i = 1, 10, 1 do
         ?>
-          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay="<?lua print(math.random()) ?>" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
             <events>
               <spawn>
                 <EventListener event="base 5" />

Modified: code/trunk/data/levels/testSwallow.oxw
===================================================================
--- code/trunk/data/levels/testSwallow.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/testSwallow.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -45,9 +45,9 @@
 j = math.random()
 ?>
 
-    <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 50) ?> <?lua end ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass="<?lua print(j * 50) ?>" <?lua end ?> scale="<?lua print(j * 5) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
       <attached>
-        <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+        <Model position="0,0,0" scale="<?lua print(j * 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
       </attached>
       <?lua if i == 5 then ?><collisionShapes>
         <SphereCollisionShape radius="<?lua print(j * 70) ?>" />

Modified: code/trunk/data/levels/underAttack.oxw
===================================================================
--- code/trunk/data/levels/underAttack.oxw	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/levels/underAttack.oxw	2011-03-15 20:47:11 UTC (rev 8079)
@@ -35,7 +35,7 @@
           />
         </attached>
           <collisionShapes>
-            <SphereCollisionShape radius=<?lua print(x) ?> position="0,0,0" />
+            <SphereCollisionShape radius="<?lua print(x) ?>" position="0,0,0" />
           </collisionShapes>
       </MovableEntity>
     <?lua end ?>
@@ -98,7 +98,7 @@
             position="<?lua print(200-270/8*i)?> ,15,2"
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
             quadratic=1
@@ -108,7 +108,7 @@
             position="<?lua print(200-270/8*i)?>,-15,2"
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
             quadratic=1

Modified: code/trunk/data/overlays/debug.oxo
===================================================================
--- code/trunk/data/overlays/debug.oxo	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/data/overlays/debug.oxo	2011-03-15 20:47:11 UTC (rev 8079)
@@ -65,6 +65,15 @@
      align    = "center"
     />
 
+    <PauseNotice
+     name     = "pausenotice"
+     position = "0.5, 0.1"
+     font     = "VeraMono"
+     textsize = 0.03
+     colour   = "1.0, 1.0, 1.0, 1.0"
+     align    = "center"
+    />
+
     <AnnounceMessage
      name     = "announcemessage"
      position = "0.5, 0.75"

Modified: code/trunk/src/CMakeLists.txt
===================================================================
--- code/trunk/src/CMakeLists.txt	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/CMakeLists.txt	2011-03-15 20:47:11 UTC (rev 8079)
@@ -118,6 +118,7 @@
 ADD_SUBDIRECTORY(external)
 ADD_SUBDIRECTORY(libraries)
 ADD_SUBDIRECTORY(orxonox)
+SET(ORXONOX_MODULES CACHE INTERNAL "")
 ADD_SUBDIRECTORY(modules)
 
 ################## Executable ###################

Modified: code/trunk/src/external/enet/win32.c
===================================================================
--- code/trunk/src/external/enet/win32.c	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/external/enet/win32.c	2011-03-15 20:47:11 UTC (rev 8079)
@@ -10,6 +10,7 @@
 #include <ws2tcpip.h>
 #define ENET_BUILDING_LIB 1
 #include "enet/enet.h"
+#include <ws2tcpip.h>
 
 static enet_uint32 timeBase = 0;
 

Modified: code/trunk/src/libraries/core/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/core/CMakeLists.txt	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/CMakeLists.txt	2011-03-15 20:47:11 UTC (rev 8079)
@@ -34,7 +34,6 @@
   ObjectListBase.cc
   OrxonoxClass.cc
   Resource.cc
-  WindowEventListener.cc
 
   # hierarchy
   Identifier.cc
@@ -48,7 +47,12 @@
   NamespaceNode.cc
   Template.cc
   XMLPort.cc
+
+COMPILATION_BEGIN ListenerCompilation.cc
+  ViewportEventListener.cc
+  WindowEventListener.cc
   XMLNameListener.cc
+COMPILATION_END
 
 COMPILATION_BEGIN FilesystemCompilation.cc
   command/ArgumentCompletionFunctions.cc
@@ -75,6 +79,7 @@
     ConfigFileManager.h
     Game.h
     GameMode.h
+    GraphicsManager.h
     GUIManager.h
     Loader.h
     LuaState.h

Modified: code/trunk/src/libraries/core/Core.cc
===================================================================
--- code/trunk/src/libraries/core/Core.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/Core.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -207,8 +207,12 @@
     {
 #ifdef ORXONOX_RELEASE
         const unsigned int defaultLevelLogFile = 3;
+        SetConfigValue(bDevMode_, false)
+            .description("Developer mode. If not set, hides some things from the user to not confuse him.");
 #else
         const unsigned int defaultLevelLogFile = 4;
+        SetConfigValue(bDevMode_, true)
+            .description("Developer mode. If not set, hides some things from the user to not confuse him.");
 #endif
         SetConfigValueExternal(softDebugLevelLogFile_, "OutputHandler", "softDebugLevelLogFile", defaultLevelLogFile)
             .description("The maximum level of debug output shown in the log file");

Modified: code/trunk/src/libraries/core/Core.h
===================================================================
--- code/trunk/src/libraries/core/Core.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/Core.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -90,6 +90,9 @@
             inline long long getOgreConfigTimestamp() const
                 { return this->ogreConfigTimestamp_; }
 
+            inline bool inDevMode(void) const
+                { return this->bDevMode_; }
+
         private:
             Core(const Core&); //!< Don't use (undefined symbol)
 
@@ -129,6 +132,7 @@
             bool                          bStartIOConsole_;            //!< Set to false if you don't want to use the IOConsole
             long long                     lastLevelTimestamp_;         ///< Timestamp when the last level was started
             long long                     ogreConfigTimestamp_;        ///< Timestamp wehen the ogre config level was modified
+            bool                          bDevMode_;                   //!< Developers bit. If set to false, some options are not available as to not confuse the normal user.
 
             static Core*                  singletonPtr_s;
     };

Modified: code/trunk/src/libraries/core/CorePrereqs.h
===================================================================
--- code/trunk/src/libraries/core/CorePrereqs.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/CorePrereqs.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -181,6 +181,7 @@
     class Template;
     class Thread;
     class ThreadPool;
+    class ViewportEventListener;
     template <class T>
     class WeakPtr;
     class WindowEventListener;

Modified: code/trunk/src/libraries/core/GUIManager.cc
===================================================================
--- code/trunk/src/libraries/core/GUIManager.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/GUIManager.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -31,9 +31,7 @@
 
 #include <boost/bind.hpp>
 #include <memory>
-extern "C" {
-#include <lua.h>
-}
+
 #include <CEGUIDefaultLogger.h>
 #include <CEGUIExceptions.h>
 #include <CEGUIInputEvent.h>
@@ -106,6 +104,7 @@
 
     SetConsoleCommand("showGUI", &GUIManager::showGUI).defaultValue(1, false).defaultValue(2, false);
     SetConsoleCommand("hideGUI", &GUIManager::hideGUI);
+    SetConsoleCommand("toggleGUI", &GUIManager::toggleGUI).defaultValue(1, false).defaultValue(2, false);
 
     /**
     @brief
@@ -285,6 +284,29 @@
         GUIManager::getInstance().executeCode("hideMenuSheet(\"" + name + "\")");
     }
 
+    /**
+    @brief
+        Toggles specified GUI.
+        If the GUI with the input name is already shown and on the top, it is hidden, else it is shown.
+    */
+    /*static*/ void GUIManager::toggleGUI(const std::string& name, bool bHidePrevious, bool bNoInput)
+    {
+        GUIManager::getInstance().executeCode("getGUIFirstActive(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ", " + multi_cast<std::string>(bNoInput) + ")");
+    }
+
+    /**
+    @brief
+        Helper method to toggle a specified GUI.
+        Is called by lua.
+    */
+    void GUIManager::toggleGUIHelper(const std::string& name, bool bHidePrevious, bool bNoInput, bool show)
+    {
+        if(show)
+            GUIManager::showGUI(name, bHidePrevious, bNoInput);
+        else
+            GUIManager::hideGUI(name);
+    }
+
     const std::string& GUIManager::createInputState(const std::string& name, TriBool::Value showCursor, TriBool::Value useKeyboard, bool bBlockJoyStick)
     {
         InputState* state = InputManager::getInstance().createInputState(name);
@@ -511,11 +533,11 @@
     */
     void GUIManager::windowResized(unsigned int newWidth, unsigned int newHeight)
     {
-        this->guiRenderer_->setDisplaySize(CEGUI::Size(newWidth, newHeight));
+        this->guiRenderer_->setDisplaySize(CEGUI::Size((float)newWidth, (float)newHeight));
     }
 
     /**
-        @brief Notify CEGUI if the windows loses the focus (stops higlight of menu items, etc).
+        @brief Notify CEGUI if the windows loses the focus (stops highlighting of menu items, etc).
     */
     void GUIManager::windowFocusChanged(bool bFocus)
     {

Modified: code/trunk/src/libraries/core/GUIManager.h
===================================================================
--- code/trunk/src/libraries/core/GUIManager.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/GUIManager.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -48,6 +48,7 @@
 #include "util/TriBool.h"
 #include "util/Singleton.h"
 #include "input/InputHandler.h"
+#include "Core.h"
 #include "OrxonoxClass.h"
 #include "WindowEventListener.h"
 
@@ -87,10 +88,18 @@
         static void showGUI(const std::string& name, bool bHidePrevious = false, bool bNoInput = false);
         void showGUIExtra(const std::string& name, const std::string& ptr, bool bHidePrevious = false, bool bNoInput = false);
         static void hideGUI(const std::string& name);
+        static void toggleGUI(const std::string& name, bool bHidePrevious = false, bool bNoInput = false);
+        void toggleGUIHelper(const std::string& name, bool bHidePrevious, bool bNoInput, bool show); // tolua_export
         void keyESC();
         void setBackgroundImage(const std::string& imageSet, const std::string imageName); // tolua_export
         void setBackgroundImage(const std::string& image);
 
+        /**
+        @brief Helper method to get the developer's mode without having to export Core.h.
+        @see Core::inDevMode
+        */
+        static bool inDevMode(void) { return Core::getInstance().inDevMode(); } // tolua_export
+
         //! Creates a new InputState to be used with a GUI Sheet
         const std::string& createInputState(const std::string& name, TriBool::Value showCursor = TriBool::True, TriBool::Value useKeyboard = TriBool::True, bool bBlockJoyStick = false); // tolua_export
         LuaState* getLuaState(void)

Modified: code/trunk/src/libraries/core/Game.cc
===================================================================
--- code/trunk/src/libraries/core/Game.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/Game.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -49,6 +49,7 @@
 #include "ConfigValueIncludes.h"
 #include "GameMode.h"
 #include "GameState.h"
+#include "GraphicsManager.h"
 #include "GUIManager.h"
 #include "command/ConsoleCommand.h"
 
@@ -59,10 +60,10 @@
     SetConsoleCommand("exit", &stop_game);
     static void printFPS()
         { COUT(0) << Game::getInstance().getAvgFPS() << std::endl; }
-    SetConsoleCommand("printFPS", &printFPS);
+    SetConsoleCommand("Stats", "printFPS", &printFPS);
     static void printTickTime()
         { COUT(0) << Game::getInstance().getAvgTickTime() << std::endl; }
-    SetConsoleCommand("printTickTime", &printTickTime);
+    SetConsoleCommand("Stats", "printTickTime", &printTickTime);
 
     std::map<std::string, GameStateInfo> Game::gameStateDeclarations_s;
     Game* Game::singletonPtr_s = 0;
@@ -141,7 +142,8 @@
             .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
         SetConfigValue(statisticsAvgLength_, 1000000)
             .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
-        SetConfigValue(fpsLimit_, 50)
+
+        SetConfigValueExternal(fpsLimit_, "GraphicsSettings", "fpsLimit", 50)
             .description("Sets the desired frame rate (0 for no limit).");
     }
 
@@ -206,7 +208,9 @@
             this->updateStatistics();
 
             // Limit frame rate
-            this->updateFPSLimiter();
+            static bool hasVSync = GraphicsManager::getInstance().hasVSyncEnabled(); // can be static since changes of VSync currently require a restart
+            if (this->fpsLimit_ > 0 && !hasVSync)
+                this->updateFPSLimiter();
         }
 
         // UNLOAD all remaining states

Modified: code/trunk/src/libraries/core/GraphicsManager.cc
===================================================================
--- code/trunk/src/libraries/core/GraphicsManager.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/GraphicsManager.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -48,6 +48,7 @@
 
 #include "SpecialConfig.h"
 #include "util/Clock.h"
+#include "util/Convert.h"
 #include "util/Exception.h"
 #include "util/StringUtils.h"
 #include "util/SubString.h"
@@ -56,15 +57,26 @@
 #include "Core.h"
 #include "Game.h"
 #include "GameMode.h"
+#include "GUIManager.h"
 #include "Loader.h"
 #include "MemoryArchive.h"
 #include "PathConfig.h"
+#include "ViewportEventListener.h"
 #include "WindowEventListener.h"
 #include "XMLFile.h"
 #include "command/ConsoleCommand.h"
+#include "input/InputManager.h"
 
 namespace orxonox
 {
+    static const std::string __CC_GraphicsManager_group = "GraphicsManager";
+    static const std::string __CC_setScreenResolution_name = "setScreenResolution";
+    static const std::string __CC_setFSAA_name = "setFSAA";
+    static const std::string __CC_setVSync_name = "setVSync";
+    DeclareConsoleCommand(__CC_GraphicsManager_group, __CC_setScreenResolution_name, &prototype::string__uint_uint_bool);
+    DeclareConsoleCommand(__CC_GraphicsManager_group, __CC_setFSAA_name, &prototype::string__string);
+    DeclareConsoleCommand(__CC_GraphicsManager_group, __CC_setVSync_name, &prototype::string__bool);
+
     static const std::string __CC_printScreen_name = "printScreen";
     DeclareConsoleCommand(__CC_printScreen_name, &prototype::void__void);
 
@@ -94,6 +106,8 @@
 #endif
         , renderWindow_(0)
         , viewport_(0)
+        , lastFrameStartTime_(0.0f)
+        , lastFrameEndTime_(0.0f)
     {
         RegisterObject(GraphicsManager);
 
@@ -135,6 +149,9 @@
 
         Ogre::WindowEventUtilities::removeWindowEventListener(renderWindow_, ogreWindowEventListener_.get());
         ModifyConsoleCommand(__CC_printScreen_name).resetFunction();
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setScreenResolution_name).resetFunction();
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setFSAA_name).resetFunction();
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setVSync_name).resetFunction();
 
         // Undeclare the resources
         Loader::unload(resources_.get());
@@ -303,7 +320,11 @@
     {
         CCOUT(4) << "Configuring Renderer" << std::endl;
 
-        if (!ogreRoot_->restoreConfig() || Core::getInstance().getOgreConfigTimestamp() > Core::getInstance().getLastLevelTimestamp())
+        bool updatedConfig = Core::getInstance().getOgreConfigTimestamp() > Core::getInstance().getLastLevelTimestamp();
+        if (updatedConfig)
+            COUT(2) << "Ogre config file has changed, but no level was started since then. Displaying config dialogue again to verify the changes." << std::endl;
+
+        if (!ogreRoot_->restoreConfig() || updatedConfig)
         {
             if (!ogreRoot_->showConfigDialog())
                 ThrowException(InitialisationFailed, "OGRE graphics configuration dialogue canceled.");
@@ -329,6 +350,9 @@
 
         // add console commands
         ModifyConsoleCommand(__CC_printScreen_name).setFunction(&GraphicsManager::printScreen, this);
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setScreenResolution_name).setFunction(&GraphicsManager::setScreenResolution, this);
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setFSAA_name).setFunction(&GraphicsManager::setFSAA, this);
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setVSync_name).setFunction(&GraphicsManager::setVSync, this);
     }
 
     void GraphicsManager::loadDebugOverlay()
@@ -342,31 +366,32 @@
     /**
     @note
         A note about the Ogre::FrameListener: Even though we don't use them,
-        they still get called. However, the delta times are not correct (except
-        for timeSinceLastFrame, which is the most important). A little research
-        as shown that there is probably only one FrameListener that doesn't even
-        need the time. So we shouldn't run into problems.
+        they still get called.
     */
     void GraphicsManager::postUpdate(const Clock& time)
     {
+        // Time before rendering
+        uint64_t timeBeforeTick = time.getRealMicroseconds();
+
+        // Ogre's time keeping object
         Ogre::FrameEvent evt;
-        evt.timeSinceLastFrame = time.getDeltaTime();
-        evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
 
-        // don't forget to call _fireFrameStarted to OGRE to make sure
-        // everything goes smoothly
+        // Translate to Ogre float times before the update
+        float temp = lastFrameStartTime_;
+        lastFrameStartTime_ = (float)timeBeforeTick * 0.000001f;
+        evt.timeSinceLastFrame = lastFrameStartTime_ - temp;
+        evt.timeSinceLastEvent = lastFrameStartTime_ - lastFrameEndTime_;
+
+        // Ogre requires the time too
         ogreRoot_->_fireFrameStarted(evt);
 
         // Pump messages in all registered RenderWindows
         // This calls the WindowEventListener objects.
         Ogre::WindowEventUtilities::messagePump();
-        // make sure the window stays active even when not focused
+        // Make sure the window stays active even when not focused
         // (probably only necessary on windows)
         this->renderWindow_->setActive(true);
 
-        // Time before rendering
-        uint64_t timeBeforeTick = time.getRealMicroseconds();
-
         // Render frame
         ogreRoot_->_updateAllRenderTargets();
 
@@ -374,13 +399,25 @@
         // Subtract the time used for rendering from the tick time counter
         Game::getInstance().subtractTickTime((int32_t)(timeAfterTick - timeBeforeTick));
 
-        // again, just to be sure OGRE works fine
-        ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
+        // Translate to Ogre float times after the update
+        temp = lastFrameEndTime_;
+        lastFrameEndTime_ = (float)timeBeforeTick * 0.000001f;
+        evt.timeSinceLastFrame = lastFrameEndTime_ - temp;
+        evt.timeSinceLastEvent = lastFrameEndTime_ - lastFrameStartTime_;
+
+        // Ogre also needs the time after the frame finished
+        ogreRoot_->_fireFrameEnded(evt);
     }
 
     void GraphicsManager::setCamera(Ogre::Camera* camera)
     {
+        Ogre::Camera* oldCamera = this->viewport_->getCamera();
+
         this->viewport_->setCamera(camera);
+        GUIManager::getInstance().setCamera(camera);
+
+        for (ObjectList<ViewportEventListener>::iterator it = ObjectList<ViewportEventListener>::begin(); it != ObjectList<ViewportEventListener>::end(); ++it)
+            it->cameraChanged(this->viewport_, oldCamera);
     }
 
     /**
@@ -439,21 +476,108 @@
 
     bool GraphicsManager::isFullScreen() const
     {
+        return this->renderWindow_->isFullScreen();
+    }
+
+    unsigned int GraphicsManager::getWindowWidth() const
+    {
+        return this->renderWindow_->getWidth();
+    }
+
+    unsigned int GraphicsManager::getWindowHeight() const
+    {
+        return this->renderWindow_->getHeight();
+    }
+
+    bool GraphicsManager::hasVSyncEnabled() const
+    {
         Ogre::ConfigOptionMap& options = ogreRoot_->getRenderSystem()->getConfigOptions();
-        if (options.find("Full Screen") != options.end())
+        Ogre::ConfigOptionMap::iterator it = options.find("VSync");
+        if (it != options.end())
+            return (it->second.currentValue == "Yes");
+        else
+            return false;
+    }
+
+    std::string GraphicsManager::getFSAAMode() const
+    {
+        Ogre::ConfigOptionMap& options = ogreRoot_->getRenderSystem()->getConfigOptions();
+        Ogre::ConfigOptionMap::iterator it = options.find("FSAA");
+        if (it != options.end())
+            return it->second.currentValue;
+        else
+            return "";
+    }
+
+    std::string GraphicsManager::setScreenResolution(unsigned int width, unsigned int height, bool fullscreen)
+    {
+        // workaround to detect if the colour depth should be written to the config file
+        bool bWriteColourDepth = false;
+        Ogre::ConfigOptionMap& options = ogreRoot_->getRenderSystem()->getConfigOptions();
+        Ogre::ConfigOptionMap::iterator it = options.find("Video Mode");
+        if (it != options.end())
+            bWriteColourDepth = (it->second.currentValue.find('@') != std::string::npos);
+
+        if (bWriteColourDepth)
         {
-            if (options["Full Screen"].currentValue == "Yes")
-                return true;
-            else
-                return false;
+            this->ogreRoot_->getRenderSystem()->setConfigOption("Video Mode", multi_cast<std::string>(width)
+                                                                    + " x " + multi_cast<std::string>(height)
+                                                                    + " @ " + multi_cast<std::string>(this->getRenderWindow()->getColourDepth()) + "-bit colour");
         }
         else
         {
-            COUT(0) << "Could not find 'Full Screen' render system option. Fix This!!!" << std::endl;
-            return false;
+            this->ogreRoot_->getRenderSystem()->setConfigOption("Video Mode", multi_cast<std::string>(width)
+                                                                    + " x " + multi_cast<std::string>(height));
         }
+
+        this->ogreRoot_->getRenderSystem()->setConfigOption("Full Screen", fullscreen ? "Yes" : "No");
+
+        std::string validate = this->ogreRoot_->getRenderSystem()->validateConfigOptions();
+
+        if (validate == "")
+        {
+            GraphicsManager::getInstance().getRenderWindow()->setFullscreen(fullscreen, width, height);
+            this->ogreRoot_->saveConfig();
+            Core::getInstance().updateOgreConfigTimestamp();
+            // Also reload the input devices
+            InputManager::getInstance().reload();
+        }
+
+        return validate;
     }
 
+    std::string GraphicsManager::setFSAA(const std::string& mode)
+    {
+        this->ogreRoot_->getRenderSystem()->setConfigOption("FSAA", mode);
+
+        std::string validate = this->ogreRoot_->getRenderSystem()->validateConfigOptions();
+
+        if (validate == "")
+        {
+            //this->ogreRoot_->getRenderSystem()->reinitialise(); // can't use this that easily, because it recreates the render window, invalidating renderWindow_
+            this->ogreRoot_->saveConfig();
+            Core::getInstance().updateOgreConfigTimestamp();
+        }
+
+        return validate;
+    }
+
+    std::string GraphicsManager::setVSync(bool vsync)
+    {
+        this->ogreRoot_->getRenderSystem()->setConfigOption("VSync", vsync ? "Yes" : "No");
+
+        std::string validate = this->ogreRoot_->getRenderSystem()->validateConfigOptions();
+
+        if (validate == "")
+        {
+            //this->ogreRoot_->getRenderSystem()->reinitialise(); // can't use this that easily, because it recreates the render window, invalidating renderWindow_
+            this->ogreRoot_->saveConfig();
+            Core::getInstance().updateOgreConfigTimestamp();
+        }
+
+        return validate;
+    }
+
     void GraphicsManager::printScreen()
     {
         assert(this->renderWindow_);

Modified: code/trunk/src/libraries/core/GraphicsManager.h
===================================================================
--- code/trunk/src/libraries/core/GraphicsManager.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/GraphicsManager.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -53,14 +53,17 @@
 #include "util/Singleton.h"
 #include "OrxonoxClass.h"
 
+// tolua_begin
 namespace orxonox
 {
     /**
     @brief
         Graphics engine manager class
     */
-    class _CoreExport GraphicsManager : public Singleton<GraphicsManager>, public OrxonoxClass, public Ogre::LogListener
-    {
+    class _CoreExport GraphicsManager
+// tolua_end
+        : public Singleton<GraphicsManager>, public OrxonoxClass, public Ogre::LogListener
+    { // tolua_export
         friend class Singleton<GraphicsManager>;
     public:
         GraphicsManager(bool bLoadRenderer = true);
@@ -73,8 +76,18 @@
         Ogre::Viewport* getViewport()         { return this->viewport_; }
         Ogre::RenderWindow* getRenderWindow() { return this->renderWindow_; }
         size_t getRenderWindowHandle();
+
+// tolua_begin
+        static GraphicsManager& getInstance() { return Singleton<GraphicsManager>::getInstance(); } // tolua_export
+
         bool isFullScreen() const;
+        unsigned int getWindowWidth() const;
+        unsigned int getWindowHeight() const;
 
+        bool hasVSyncEnabled() const;
+        std::string getFSAAMode() const;
+// tolua_end
+
         void upgradeToGraphics();
         void loadDebugOverlay();
         bool rendererLoaded() const { return renderWindow_ != NULL; }
@@ -95,6 +108,9 @@
 
         // console commands
         void printScreen();
+        std::string setScreenResolution(unsigned int width, unsigned int height, bool fullscreen);
+        std::string setFSAA(const std::string& mode);
+        std::string setVSync(bool vsync);
 
         scoped_ptr<OgreWindowEventListener> ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
 #if OGRE_VERSION < 0x010600
@@ -104,6 +120,8 @@
         scoped_ptr<Ogre::Root>              ogreRoot_;                //!< Ogre's root
         Ogre::RenderWindow* renderWindow_;             //!< the one and only render window
         Ogre::Viewport*     viewport_;                 //!< default full size viewport
+        float               lastFrameStartTime_;       //!< Time stamp of the beginning of the last frame
+        float               lastFrameEndTime_;         //!< Time stamp of the end of the last frame
 
         // XML files for the resources and the debug overlay
         shared_ptr<XMLFile> resources_;                //!< XML with resource locations
@@ -120,7 +138,9 @@
         int                 ogreLogLevelCritical_;     //!< Corresponding Orxonox debug level for LL_CRITICAL
 
         static GraphicsManager* singletonPtr_s;        //!< Pointer to the Singleton
+// tolua_begin
     };
 }
+// tolua_end
 
 #endif /* _GraphicsManager_H__ */

Modified: code/trunk/src/libraries/core/Loader.cc
===================================================================
--- code/trunk/src/libraries/core/Loader.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/Loader.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -146,7 +146,7 @@
     @return
         Returns true if successful.
     */
-    bool Loader::load(const XMLFile* file, const ClassTreeMask& mask, bool verbose)
+    bool Loader::load(const XMLFile* file, const ClassTreeMask& mask, bool verbose, bool bRemoveLuaTags)
     {
         if (!file)
             return false;
@@ -154,7 +154,7 @@
         Loader::currentMask_s = file->getMask() * mask;
 
         std::string xmlInput;
-        if (file->getLuaSupport())
+        if (file->getLuaSupport() && !bRemoveLuaTags)
         {
             // Use the LuaState to replace the XML tags (calls our function)
             scoped_ptr<LuaState> luaState(new LuaState());
@@ -171,6 +171,15 @@
                 return false;
             }
             xmlInput = Resource::open(file->getFilename())->getAsString();
+
+            if (bRemoveLuaTags)
+            {
+                // Remove all Lua code.
+                // Note: we only need this to speed up parsing of level files at the
+                // start of the program.
+                // Assumption: the LevelInfo tag does not use Lua scripting
+                xmlInput = removeLuaTags(xmlInput);
+            }
         }
 
         try
@@ -270,10 +279,9 @@
         return Loader::load(file, mask, verbose);
     }
 
-    std::string Loader::replaceLuaTags(const std::string& text)
+    bool Loader::getLuaTags(const std::string& text, std::map<size_t, bool>& luaTags)
     {
-        // create map with all Lua tags
-        std::map<size_t, bool> luaTags;
+        // fill map with all Lua tags
         {
             size_t pos = 0;
             while ((pos = text.find("<?lua", pos)) != std::string::npos)
@@ -327,11 +335,21 @@
             if (!expectedValue)
             {
                 COUT(2) << "Warning: Error in level file" << std::endl;
-                // todo: errorhandling
-                return "";
+                // TODO: error handling
+                return false; 
             }
         }
 
+        return true;
+    }
+
+    std::string Loader::replaceLuaTags(const std::string& text)
+    {
+        // create a map with all lua tags
+        std::map<size_t, bool> luaTags;
+        if (!getLuaTags(text, luaTags))
+            return "";
+
         // Use a stringstream object to speed up the parsing
         std::ostringstream output;
 
@@ -420,4 +438,42 @@
 
         return output.str();
     }
+
+    std::string Loader::removeLuaTags(const std::string& text)
+    {
+        // create a map with all lua tags
+        std::map<size_t, bool> luaTags;
+        if (!getLuaTags(text, luaTags))
+            return "";
+
+        // Use a stringstream object to speed up the concatenation
+        std::ostringstream output;
+
+        // cut the original string into pieces and only write the non Lua parts
+        std::map<size_t, bool>::iterator it = luaTags.begin();
+        bool bLuaCode = false;
+        size_t start = 0;
+        size_t end = 0;
+
+        do
+        {
+            if (it != luaTags.end())
+                end = (it++)->first;
+            else
+                end = std::string::npos;
+
+            if (!bLuaCode)
+            {
+                output << text.substr(start, end - start);
+                start = end + 5;
+            }
+            else
+                start = end + 2;
+
+            bLuaCode = !bLuaCode;
+        }
+        while (end != std::string::npos);
+
+        return output.str();
+    }
 }

Modified: code/trunk/src/libraries/core/Loader.h
===================================================================
--- code/trunk/src/libraries/core/Loader.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/Loader.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -41,6 +41,7 @@
 
 #include "CorePrereqs.h"
 
+#include <map>
 #include <vector>
 #include "ClassTreeMask.h"
 
@@ -60,15 +61,19 @@
             static void unload(const ClassTreeMask& mask = ClassTreeMask());
             static bool reload(const ClassTreeMask& mask = ClassTreeMask(), bool verbose = true);
 
-            static bool load(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask(), bool verbose = true);
+            static bool load(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask(),
+                             bool verbose = true, bool bRemoveLuaTags = false);
             static void unload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
             static bool reload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask(), bool verbose = true);
 
             static std::string replaceLuaTags(const std::string& text);
+            static std::string removeLuaTags(const std::string& text);
 
             static ClassTreeMask currentMask_s;
 
         private:
+            static bool getLuaTags(const std::string& text, std::map<size_t, bool>& luaTags);
+
             static std::vector<std::pair<const XMLFile*, ClassTreeMask> > files_s;
     };
 }

Modified: code/trunk/src/libraries/core/OrxonoxClass.h
===================================================================
--- code/trunk/src/libraries/core/OrxonoxClass.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/OrxonoxClass.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -193,6 +193,8 @@
         friend class OrxonoxClass;
 
         protected:
+            virtual ~DestructionListener() {}
+
             inline void registerAsDestructionListener(OrxonoxClass* object)
                 { if (object) { object->registerDestructionListener(this); } }
             inline void unregisterAsDestructionListener(OrxonoxClass* object)

Copied: code/trunk/src/libraries/core/ViewportEventListener.cc (from rev 8078, code/branches/usability/src/libraries/core/ViewportEventListener.cc)
===================================================================
--- code/trunk/src/libraries/core/ViewportEventListener.cc	                        (rev 0)
+++ code/trunk/src/libraries/core/ViewportEventListener.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -0,0 +1,38 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 2
+ *   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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ViewportEventListener.h"
+#include "CoreIncludes.h"
+
+namespace orxonox
+{
+    ViewportEventListener::ViewportEventListener()
+    {
+        RegisterRootObject(ViewportEventListener);
+    }
+}

Copied: code/trunk/src/libraries/core/ViewportEventListener.h (from rev 8078, code/branches/usability/src/libraries/core/ViewportEventListener.h)
===================================================================
--- code/trunk/src/libraries/core/ViewportEventListener.h	                        (rev 0)
+++ code/trunk/src/libraries/core/ViewportEventListener.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 2
+ *   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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ViewportEventListener_H__
+#define _ViewportEventListener_H__
+
+#include "util/OgreForwardRefs.h"
+
+#include "CorePrereqs.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _CoreExport ViewportEventListener : virtual public OrxonoxClass
+    {
+        public:
+            virtual void cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera) {}
+
+        protected:
+            ViewportEventListener();
+            virtual ~ViewportEventListener() {}
+    };
+}
+
+#endif /* _ViewportEventListener_H__ */

Modified: code/trunk/src/libraries/core/WeakPtr.h
===================================================================
--- code/trunk/src/libraries/core/WeakPtr.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/WeakPtr.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -128,7 +128,7 @@
             }
 
             /// Destructor
-            inline ~WeakPtr()
+            inline virtual ~WeakPtr()
             {
                 this->unregisterAsDestructionListener(this->base_);
             }

Modified: code/trunk/src/libraries/core/command/CommandEvaluation.h
===================================================================
--- code/trunk/src/libraries/core/command/CommandEvaluation.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/command/CommandEvaluation.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -69,11 +69,11 @@
         time, for example to return an error message if it doesn't work.
 
         @remarks execCommand_ and hintCommand_ can be different in this case: There are multiple
-        commands avaliable, let's say "tcl", "tclexecute", and "tclquery". The user enters
-        "tcl", which is already a valid command. Now execCommand_ points to the "tcl"-command,
-        but hintCommand_ still points to the autocompletion command of CommandExecutor, because
-        the auto-completion list must still return the three possible commands, "tcl tclexecute tclquery"
-        because the user may want to execute "tclquery" and needs auto-completion.
+        commands avaliable, let's say "tcl" and "TclThreadManager". The user enters "tcl", which
+        is already a valid command. Now execCommand_ points to the "tcl"-command, but hintCommand_
+        still points to the autocompletion command of CommandExecutor, because the auto-completion
+        list must still return the two possible commands, "tcl TclThreadManager" because the user
+        may want to write "TclThreadManager ..." and needs auto-completion.
 
         @see See @ref CommandExecutorExample "this description" for an example.
     */

Modified: code/trunk/src/libraries/core/command/ConsoleCommand.h
===================================================================
--- code/trunk/src/libraries/core/command/ConsoleCommand.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/command/ConsoleCommand.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -316,6 +316,10 @@
     {
         inline void void__void(void) {}
         inline void void__string(const std::string&) {}
+
+        inline std::string string__bool(bool) { return ""; }
+        inline std::string string__string(const std::string&) { return ""; }
+        inline std::string string__uint_uint_bool(unsigned int, unsigned int, bool) { return ""; }
     }
 
     namespace AccessLevel

Modified: code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc
===================================================================
--- code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -45,13 +45,13 @@
 
 namespace orxonox
 {
-    SetConsoleCommand("source", source).argumentCompleter(0, autocompletion::files());
+//    SetConsoleCommand("source", source).argumentCompleter(0, autocompletion::files());  // disabled because we use the implementation in Tcl
     SetConsoleCommand("echo", echo);
-    SetConsoleCommand("puts", puts);
+//    SetConsoleCommand("puts", puts);                                                    // disabled because we use the implementation in Tcl
 
-    SetConsoleCommand("read", read).argumentCompleter(0, autocompletion::files());
-    SetConsoleCommand("append", append).argumentCompleter(0, autocompletion::files());
-    SetConsoleCommand("write", write).argumentCompleter(0, autocompletion::files());
+//    SetConsoleCommand("read", read).argumentCompleter(0, autocompletion::files());      // disabled because we use the implementation in Tcl
+//    SetConsoleCommand("append", append).argumentCompleter(0, autocompletion::files());  // disabled because we use the implementation in Tcl
+//    SetConsoleCommand("write", write).argumentCompleter(0, autocompletion::files());    // disabled because we use the implementation in Tcl
 
     SetConsoleCommand("calculate", calculate);
 

Modified: code/trunk/src/libraries/core/command/Shell.cc
===================================================================
--- code/trunk/src/libraries/core/command/Shell.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/command/Shell.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -45,10 +45,10 @@
 namespace orxonox
 {
     SetConsoleCommand("log",     OutputHandler::log    );
-    SetConsoleCommand("error",   OutputHandler::error  );
-    SetConsoleCommand("warning", OutputHandler::warning);
-    SetConsoleCommand("info",    OutputHandler::info   );
-    SetConsoleCommand("debug",   OutputHandler::debug  );
+    SetConsoleCommand("error",   OutputHandler::error  ).hide();
+    SetConsoleCommand("warning", OutputHandler::warning).hide();
+    SetConsoleCommand("info",    OutputHandler::info   ).hide();
+    SetConsoleCommand("debug",   OutputHandler::debug  ).hide();
 
     unsigned int Shell::cacheSize_s;
 

Modified: code/trunk/src/libraries/core/command/TclBind.cc
===================================================================
--- code/trunk/src/libraries/core/command/TclBind.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/command/TclBind.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -44,7 +44,7 @@
 namespace orxonox
 {
     SetConsoleCommand("tcl", &TclBind::tcl);
-    SetConsoleCommand("bgerror", &TclBind::bgerror);
+    SetConsoleCommand("bgerror", &TclBind::bgerror).hide();
 
     TclBind* TclBind::singletonPtr_s = 0;
 
@@ -90,15 +90,16 @@
             this->interpreter_ = this->createTclInterpreter();
 
             this->interpreter_->def("::orxonox::query", TclBind::tcl_query, Tcl::variadic());
+            this->interpreter_->def("::orxonox::execute", TclBind::tcl_execute, Tcl::variadic());
             this->interpreter_->def("::orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
-            this->interpreter_->def("execute", TclBind::tcl_execute, Tcl::variadic());
             this->interpreter_->def("::orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
 
             try
             {
-                this->interpreter_->eval("proc query        {args}    { ::orxonox::query $args }");
+                this->interpreter_->def("query", TclBind::tcl_query, Tcl::variadic());
+                this->interpreter_->def("execute", TclBind::tcl_execute, Tcl::variadic());
                 this->interpreter_->eval("proc crossquery   {id args} { ::orxonox::crossquery 0 $id $args }");
-                this->interpreter_->eval("proc crossexecute {id args} { ::orxonox::crossquery 0 $id $args }");
+                this->interpreter_->eval("proc crossexecute {id args} { ::orxonox::crossexecute 0 $id $args }");
                 this->interpreter_->eval("proc running      {}        { return 1 }");
                 this->interpreter_->eval("set id 0");
                 this->interpreter_->eval("rename exit ::tcl::exit; proc exit {} { execute exit }");
@@ -153,12 +154,35 @@
     std::string TclBind::tcl_query(Tcl::object const &args)
     {
         COUT(4) << "Tcl_query: " << args.get() << std::endl;
+        return TclBind::tcl_helper(args, true);
+    }
 
+    /**
+        @brief Callback: Used to send an Orxonox-command from Tcl to the CommandExecutor.
+    */
+    void TclBind::tcl_execute(Tcl::object const &args)
+    {
+        COUT(4) << "Tcl_execute: " << args.get() << std::endl;
+        TclBind::tcl_helper(args, false);
+    }
+
+    /**
+        @brief Helper function, used by tcl_query() and tcl_execute().
+    */
+    std::string TclBind::tcl_helper(Tcl::object const &args, bool bQuery)
+    {
         const std::string& command = stripEnclosingBraces(args.get());
 
         int error;
+        std::string result;
+
         CommandEvaluation evaluation = CommandExecutor::evaluate(command);
-        const std::string& result = evaluation.query(&error);
+
+        if (bQuery)
+            result = evaluation.query(&error).getString();
+        else
+            error = evaluation.execute();
+
         switch (error)
         {
             case CommandExecutor::Error:       COUT(1) << "Error: Can't execute command \"" << command << "\", command doesn't exist. (B)" << std::endl; break;
@@ -174,20 +198,6 @@
     }
 
     /**
-        @brief Callback: Used to send an Orxonox-command from Tcl to the CommandExecutor.
-    */
-    void TclBind::tcl_execute(Tcl::object const &args)
-    {
-        COUT(4) << "Tcl_execute: " << args.get() << std::endl;
-        const std::string& command = stripEnclosingBraces(args.get());
-
-        if (CommandExecutor::execute(command, false))
-        {
-            COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl;
-        }
-    }
-
-    /**
         @brief Console command, executes Tcl code. Can be used to bind Tcl-commands to a key, because native
         Tcl-commands can not be evaluated and are thus not supported by the key-binder.
     */
@@ -197,15 +207,10 @@
         {
             try
             {
-                const std::string& output = TclBind::getInstance().interpreter_->eval("uplevel #0 " + tclcode);
-                if (!output.empty())
-                {
-                    COUT(0) << "tcl> " << output << std::endl;
-                }
-                return output;
+                return TclBind::getInstance().interpreter_->eval("uplevel #0 " + tclcode);
             }
             catch (Tcl::tcl_error const &e)
-            {   COUT(1) << "tcl> Error: " << e.what() << std::endl;   }
+            {   COUT(1) << "Tcl error: " << e.what() << std::endl;   }
         }
 
         return "";

Modified: code/trunk/src/libraries/core/command/TclBind.h
===================================================================
--- code/trunk/src/libraries/core/command/TclBind.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/command/TclBind.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -125,6 +125,8 @@
         private:
             TclBind(const TclBind& other);      ///< Copy-constructor, not implemented
 
+            static std::string tcl_helper(Tcl::object const &args, bool bQuery);
+
             Tcl::interpreter* interpreter_;     ///< The wrapped Tcl interpreter
             std::string tclDataPath_;           ///< The path to the directory that contains the Orxonox-specific Tcl-files
             bool bSetTclDataPath_;              ///< True if tclDataPath_ was defined (after a call to setDataPath())

Modified: code/trunk/src/libraries/core/command/TclThreadManager.cc
===================================================================
--- code/trunk/src/libraries/core/command/TclThreadManager.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/command/TclThreadManager.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -54,8 +54,6 @@
 {
     const float TCLTHREADMANAGER_MAX_CPU_USAGE = 0.50f;
 
-    SetConsoleCommand("tclexecute", &TclThreadManager::execute).argumentCompleter(0, autocompletion::tclthreads());
-    SetConsoleCommand("tclquery",   &TclThreadManager::query  ).argumentCompleter(0, autocompletion::tclthreads());
     SetConsoleCommand("TclThreadManager", "create",  &TclThreadManager::create);
     SetConsoleCommand("TclThreadManager", "destroy", &TclThreadManager::destroy).argumentCompleter(0, autocompletion::tclthreads());
     SetConsoleCommand("TclThreadManager", "execute", &TclThreadManager::execute).argumentCompleter(0, autocompletion::tclthreads());

Modified: code/trunk/src/libraries/core/input/InputManager.cc
===================================================================
--- code/trunk/src/libraries/core/input/InputManager.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/input/InputManager.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -640,4 +640,20 @@
         statesByName_.erase(state->getName());
         state->destroy();
     }
+
+    bool InputManager::setMouseExclusive(const std::string& name, TriBool::Value value)
+    {
+        if (name == "empty")
+        {
+            COUT(2) << "InputManager: Changing the empty state is not allowed!" << std::endl;
+            return false;
+        }
+        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
+        {
+            it->second->setMouseExclusive(value);
+            return true;
+        }
+        return false;
+    }
 }

Modified: code/trunk/src/libraries/core/input/InputManager.h
===================================================================
--- code/trunk/src/libraries/core/input/InputManager.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/input/InputManager.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -162,6 +162,13 @@
             - The removal process is being postponed if InputManager::preUpdate() is currently running.
         */
         bool destroyState(const std::string& name); // tolua_export
+        /**
+        @brief
+            Changes the mouse mode of an input state.
+        @return
+            True if the call was successful, fals if the name was not found
+        */
+        bool setMouseExclusive(const std::string& name, TriBool::Value value); // tolua_export
 
         //-------------------------------
         // Various getters and setters

Modified: code/trunk/src/libraries/core/input/KeyBinder.cc
===================================================================
--- code/trunk/src/libraries/core/input/KeyBinder.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/input/KeyBinder.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -430,7 +430,13 @@
                             button->commands_[mode_index][c] = button->commands_[mode_index][c + 1];
                         // decrease counter
                         button->nCommands_[mode_index]--;
-                        // note: we don't replace the old array - it's not one element too large, but no one cares since nCommands_ defines the size
+                        // old array would not get deleted if nCommands_ is now 0
+                        // otherwise: nobody cares about an array that is one element too large - nCommands_ defines the size
+                        if (button->nCommands_[mode_index] == 0)
+                        {
+                            delete[] button->commands_[mode_index];
+                            button->commands_[mode_index] = 0;
+                        }
 
                         // decrement the index since we shifted the array and continue searching for more occurrences of the command
                         command_index--;

Modified: code/trunk/src/libraries/core/input/Keyboard.cc
===================================================================
--- code/trunk/src/libraries/core/input/Keyboard.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/input/Keyboard.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -35,18 +35,28 @@
     bool Keyboard::keyPressed(const OIS::KeyEvent& arg)
     {
         // update modifiers
-        if (arg.key == OIS::KC_RMENU    || arg.key == OIS::KC_LMENU)
-            modifiers_ |= KeyboardModifier::Alt;   // alt key
-        if (arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL)
-            modifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
-        if (arg.key == OIS::KC_RSHIFT   || arg.key == OIS::KC_LSHIFT)
-            modifiers_ |= KeyboardModifier::Shift; // shift key
+        switch (arg.key)
+        {
+            case OIS::KC_RMENU:
+            case OIS::KC_LMENU:
+                modifiers_ |= KeyboardModifier::Alt;   // alt key
+                break;
+            case OIS::KC_RCONTROL:
+            case OIS::KC_LCONTROL:
+                modifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
+                break;
+            case OIS::KC_RSHIFT:
+            case OIS::KC_LSHIFT:
+                modifiers_ |= KeyboardModifier::Shift; // shift key
+                break;
+            case OIS::KC_TAB:
+                // Do not distribute the alt+tab event (messes with the operating system)
+                if ((modifiers_ & KeyboardModifier::Alt) != 0)
+                    return true;
+            default:;
+        }
 
-        // Do not distribute the alt+tab event (messes with the operating system)
-        if ((modifiers_ & KeyboardModifier::Alt) != 0 && arg.key == OIS::KC_TAB)
-            return true;
-
-        KeyEvent evt(arg);
+        KeyEvent evt(static_cast<KeyCode::ByEnum>(arg.key), Keyboard::getKeyText(arg), 0);
         super::buttonPressed(evt);
         return true;
     }
@@ -55,15 +65,47 @@
     bool Keyboard::keyReleased(const OIS::KeyEvent& arg)
     {
         // update modifiers
-        if (arg.key == OIS::KC_RMENU    || arg.key == OIS::KC_LMENU)
-            modifiers_ &= ~KeyboardModifier::Alt;   // alt key
-        if (arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL)
-            modifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
-        if (arg.key == OIS::KC_RSHIFT   || arg.key == OIS::KC_LSHIFT)
-            modifiers_ &= ~KeyboardModifier::Shift; // shift key
+        switch (arg.key)
+        {
+            case OIS::KC_RMENU:
+            case OIS::KC_LMENU:
+                modifiers_ &= ~KeyboardModifier::Alt;   // alt key
+                break;
+            case OIS::KC_RCONTROL:
+            case OIS::KC_LCONTROL:
+                modifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
+                break;
+            case OIS::KC_RSHIFT:
+            case OIS::KC_LSHIFT:
+                modifiers_ &= ~KeyboardModifier::Shift; // shift key
+                break;
+            default:;
+        }
 
-        KeyEvent evt(arg);
+        KeyEvent evt(static_cast<KeyCode::ByEnum>(arg.key), Keyboard::getKeyText(arg), 0);
         super::buttonReleased(evt);
         return true;
     }
+
+    /// A map which returns the corresponding chars for some key codes
+    unsigned int Keyboard::getKeyText(const OIS::KeyEvent& arg)
+    {
+        switch (arg.key)
+        {
+            case OIS::KC_NUMPAD0:     return static_cast<unsigned int>('0');
+            case OIS::KC_NUMPAD1:     return static_cast<unsigned int>('1');
+            case OIS::KC_NUMPAD2:     return static_cast<unsigned int>('2');
+            case OIS::KC_NUMPAD3:     return static_cast<unsigned int>('3');
+            case OIS::KC_NUMPAD4:     return static_cast<unsigned int>('4');
+            case OIS::KC_NUMPAD5:     return static_cast<unsigned int>('5');
+            case OIS::KC_NUMPAD6:     return static_cast<unsigned int>('6');
+            case OIS::KC_NUMPAD7:     return static_cast<unsigned int>('7');
+            case OIS::KC_NUMPAD8:     return static_cast<unsigned int>('8');
+            case OIS::KC_NUMPAD9:     return static_cast<unsigned int>('9');
+            case OIS::KC_DECIMAL:     return static_cast<unsigned int>('.');
+            case OIS::KC_DIVIDE:      return static_cast<unsigned int>('/');
+            case OIS::KC_NUMPADENTER: return static_cast<unsigned int>('\n');
+            default:                  return arg.text;
+        }
+    }
 }

Modified: code/trunk/src/libraries/core/input/Keyboard.h
===================================================================
--- code/trunk/src/libraries/core/input/Keyboard.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/core/input/Keyboard.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -82,6 +82,8 @@
         //! Returns the class name as string
         static std::string getClassNameImpl() { return "Keyboard"; }
 
+        static unsigned int getKeyText(const OIS::KeyEvent& arg);
+
         //! Bit mask representing keyboard modifiers
         int modifiers_;
     };

Modified: code/trunk/src/libraries/network/Host.cc
===================================================================
--- code/trunk/src/libraries/network/Host.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/network/Host.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -37,10 +37,11 @@
 
 namespace orxonox {
 
+  static const std::string __CC_printRTT_group = "Stats";
   static const std::string __CC_printRTT_name = "printRTT";
 
   SetConsoleCommand("chat", &Host::Chat);
-  SetConsoleCommand(__CC_printRTT_name, &Host::printRTT);
+  SetConsoleCommand(__CC_printRTT_group, __CC_printRTT_name, &Host::printRTT);
 
   // Host*               Host::instance_=0;
   uint32_t            Host::clientID_s=0;
@@ -54,7 +55,7 @@
   {
   //   assert(instance_==0);
     instances_s.push_back(this);
-    ModifyConsoleCommand(__CC_printRTT_name).setObject(this);
+    ModifyConsoleCommand(__CC_printRTT_group, __CC_printRTT_name).setObject(this);
     this->bIsActive_ = false;
   }
 
@@ -66,7 +67,7 @@
   {
     assert( std::find( instances_s.begin(), instances_s.end(), this )!=instances_s.end() );
     instances_s.erase(std::find( instances_s.begin(), instances_s.end(), this ));
-    ModifyConsoleCommand(__CC_printRTT_name).setObject(0);
+    ModifyConsoleCommand(__CC_printRTT_group, __CC_printRTT_name).setObject(0);
   }
 
   /**

Modified: code/trunk/src/libraries/tools/ResourceLocation.cc
===================================================================
--- code/trunk/src/libraries/tools/ResourceLocation.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/tools/ResourceLocation.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -29,6 +29,7 @@
 #include "ResourceLocation.h"
 
 #include <OgreResourceGroupManager.h>
+#include <OgreException.h>
 #include <boost/filesystem.hpp>
 
 #include "util/Exception.h"

Modified: code/trunk/src/libraries/tools/Shader.cc
===================================================================
--- code/trunk/src/libraries/tools/Shader.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/tools/Shader.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -29,14 +29,8 @@
 #include "Shader.h"
 
 #include <OgreCompositorManager.h>
-#include <OgreCompositorInstance.h>
-#include <OgreSceneManager.h>
 #include <OgreRoot.h>
 #include <OgrePlugin.h>
-#include <OgreMaterial.h>
-#include <OgreTechnique.h>
-#include <OgrePass.h>
-#include <OgreMaterialManager.h>
 
 #include "core/CoreIncludes.h"
 #include "core/GameMode.h"
@@ -44,286 +38,204 @@
 
 namespace orxonox
 {
-    bool Shader::bLoadedCgPlugin_s = false;
-    Shader::MaterialMap Shader::parameters_s;
-
+    /**
+        @brief Initializes the values and sets the scene manager.
+    */
     Shader::Shader(Ogre::SceneManager* scenemanager) : compositorInstance_(0)
     {
         RegisterObject(Shader);
 
         this->scenemanager_ = scenemanager;
-        this->compositorInstance_ = 0;
         this->bVisible_ = true;
         this->bLoadCompositor_ = GameMode::showsGraphics();
-        this->bViewportInitialized_ = false;
+        this->registeredAsListener_ = false;
 
-        if (this->bLoadCompositor_ && Ogre::Root::getSingletonPtr())
-        {
-            Shader::bLoadedCgPlugin_s = false;
-            const Ogre::Root::PluginInstanceList& plugins = Ogre::Root::getSingleton().getInstalledPlugins();
-            for (size_t i = 0; i < plugins.size(); ++i)
-            {
-                if (plugins[i]->getName() == "Cg Program Manager")
-                {
-                    Shader::bLoadedCgPlugin_s = true;
-                    break;
-                }
-            }
-        }
+        static bool hasCgProgramManager = Shader::hasCgProgramManager();
 
-        this->bLoadCompositor_ &= Shader::bLoadedCgPlugin_s;
+        this->bLoadCompositor_ &= hasCgProgramManager;
     }
 
+    /**
+        @brief Removes the compositor and frees the resources.
+    */
     Shader::~Shader()
     {
-        if (this->compositorInstance_ && this->bLoadCompositor_)
-        {
-            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
-            assert(viewport);
-            Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->compositor_);
-        }
-
+        if (this->compositorInstance_ && GraphicsManager::getInstance().getViewport())
+            Ogre::CompositorManager::getSingleton().removeCompositor(GraphicsManager::getInstance().getViewport(), this->compositorName_);
     }
 
-    void Shader::setSceneManager(Ogre::SceneManager* scenemanager)
+    /**
+        @brief Inherited from ViewportEventListener - called if the camera changes.
+
+        Since the new camera could be in a different scene, the shader has to make sure
+        it deactivates or activates itself accordingly.
+
+        Additionally the shader has to be turned off and on even if the camera stays in
+        the same scene to fix a weird behavior of Ogre.
+    */
+    void Shader::cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera)
     {
-        this->scenemanager_ = scenemanager;
-        this->bViewportInitialized_ = false;
+        if (!this->bLoadCompositor_ || !this->scenemanager_)
+            return;
+
+        // load the compositor if not already done
+        if (!this->compositorName_.empty() && !this->compositorInstance_)
+            this->changedCompositorName(viewport);
+
+        // update compositor in viewport (shader should only be active if the current camera is in the same scene as the shader)
+
+        // Note:
+        // The shader needs also to be switched off and on after changing the camera in the
+        // same scene to avoid weird behaviour with active compositors while switching the
+        // camera (like freezing the image)
+        //
+        // Last known Ogre version needing this workaround:
+        // 1.4.8
+        // 1.7.2
+
+        if (oldCamera && this->scenemanager_ == oldCamera->getSceneManager())
+            Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, false);
+
+        if (viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager())
+            Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible());
     }
 
-    void Shader::tick(float dt)
+    /**
+        @brief Changes the compositor - default viewport.
+    */
+    void Shader::changedCompositorName()
     {
-        SUPER(Shader, tick, dt);
-
-        if (this->bLoadCompositor_ && !this->bViewportInitialized_ && this->scenemanager_ && this->scenemanager_->getCurrentViewport())
-        {
-            this->bViewportInitialized_ = true;
-            this->updateVisibility();
-        }
+        // For the moment, we get the viewport always from the graphics manager
+        // TODO: Try to support multiple viewports - note however that scenemanager_->getCurrentViewport() returns NULL
+        //       after switching to a camera in a different scene (only for the first time this scene is displayed though)
+        this->changedCompositorName(GraphicsManager::getInstance().getViewport());
     }
 
-    void Shader::changedCompositor()
+    /**
+        @brief Changes the compositor.
+    */
+    void Shader::changedCompositorName(Ogre::Viewport* viewport)
     {
         if (this->bLoadCompositor_)
         {
-            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
             assert(viewport);
-            if (!this->oldcompositor_.empty())
+            if (this->compositorInstance_)
             {
-                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositor_);
+                // remove the old compositor, remove the listener
+                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositorName_);
+                this->compositorInstance_->removeListener(this);
                 this->compositorInstance_ = 0;
             }
-            if (!this->compositor_.empty())
+            if (!this->compositorName_.empty())
             {
-                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositor_);
-                if (!this->compositorInstance_)
-                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositor_ << "\"." << std::endl;
-                Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositor_, this->bViewportInitialized_ && this->isVisible());
+                // add the new compositor
+                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositorName_);
+                if (this->compositorInstance_)
+                {
+                    // register as listener if required
+                    if (this->registeredAsListener_)
+                        this->compositorInstance_->addListener(this);
+                    // set visibility according to the isVisible() and the camera/viewport
+                    if (viewport->getCamera())
+                        Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible() && viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager());
+                }
+                else
+                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositorName_ << "\"." << std::endl;
             }
-            this->oldcompositor_ = this->compositor_;
+            this->oldcompositorName_ = this->compositorName_;
         }
     }
 
+    /**
+        @brief Changes the visibility of the shader. Doesn't free any resources if set to invisible.
+    */
     void Shader::updateVisibility()
     {
-        if (this->compositorInstance_ && this->scenemanager_)
-            this->compositorInstance_->setEnabled(this->scenemanager_->getCurrentViewport() && this->isVisible());
+        if (this->compositorInstance_)
+            Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, this->isVisible());
     }
 
-    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
+    /**
+        @brief Defines a new integer value for a given parameter. The parameter will be updated if the compositor is rendered the next time.
+    */
+    void Shader::setParameter(size_t technique, size_t pass, const std::string& parameter, int value)
     {
-        if (Shader::_setParameter(material, technique, pass, parameter, value))
-        {
-            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
-            {
-                this->compositorInstance_->setEnabled(false);
-                this->compositorInstance_->setEnabled(true);
-            }
-        }
+        ParameterContainer container = {technique, pass, parameter, value, 0.0f, MT_Type::Int};
+        this->parameters_.push_back(container);
+        this->addAsListener();
     }
 
-    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
+    /**
+        @brief Defines a new float value for a given parameter. The parameter will be updated if the compositor is rendered the next time.
+    */
+    void Shader::setParameter(size_t technique, size_t pass, const std::string& parameter, float value)
     {
-        if (Shader::_setParameter(material, technique, pass, parameter, value))
-        {
-            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
-            {
-                this->compositorInstance_->setEnabled(false);
-                this->compositorInstance_->setEnabled(true);
-            }
-        }
+        ParameterContainer container = {technique, pass, parameter, 0, value, MT_Type::Float};
+        this->parameters_.push_back(container);
+        this->addAsListener();
     }
 
-    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
+    /**
+        @brief Registers the shader as CompositorInstance::Listener at the compositor. Used to change parameters.
+    */
+    void Shader::addAsListener()
     {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
+        if (!this->registeredAsListener_)
         {
-            if (pointer->first)
-            {
-                if ((*static_cast<float*>(pointer->second)) != value)
-                {
-                    (*static_cast<float*>(pointer->second)) = value;
-                    return true;
-                }
-            }
-            else
-            {
-                if ((*static_cast<int*>(pointer->second)) != static_cast<int>(value))
-                {
-                    (*static_cast<int*>(pointer->second)) = static_cast<int>(value);
-                    return true;
-                }
-            }
+            this->registeredAsListener_ = true;
+            if (this->compositorInstance_)
+                this->compositorInstance_->addListener(this);
         }
-        return false;
     }
 
-    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
+    /**
+        @brief Inherited by Ogre::CompositorInstance::Listener, called whenever the material is rendered. Used to change parameters.
+    */
+    void Shader::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr)
     {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
+        // iterate through the list of parameters
+        for (std::list<ParameterContainer>::iterator it = this->parameters_.begin(); it != this->parameters_.end(); ++it)
         {
-            if (pointer->first)
+            Ogre::Technique* techniquePtr = materialPtr->getTechnique(it->technique_);
+            if (techniquePtr)
             {
-                if ((*static_cast<float*>(pointer->second)) != static_cast<float>(value))
+                Ogre::Pass* passPtr = techniquePtr->getPass(it->pass_);
+                if (passPtr)
                 {
-                    (*static_cast<float*>(pointer->second)) = static_cast<float>(value);
-                    return true;
+                    // change the value of the parameter depending on its type
+                    switch (it->valueType_)
+                    {
+                        case MT_Type::Int:
+                            passPtr->getFragmentProgramParameters()->setNamedConstant(it->parameter_, it->valueInt_);
+                            break;
+                        case MT_Type::Float:
+                            passPtr->getFragmentProgramParameters()->setNamedConstant(it->parameter_, it->valueFloat_);
+                            break;
+                        default:
+                            break;
+                    }
                 }
+                else
+                    COUT(2) << "Warning: No pass " << it->pass_ << " in technique " << it->technique_ << " in compositor \"" << this->compositorName_ << "\" or pass has no shader." << std::endl;
             }
             else
-            {
-                if ((*static_cast<int*>(pointer->second)) != value)
-                {
-                    (*static_cast<int*>(pointer->second)) = value;
-                    return true;
-                }
-            }
+                COUT(2) << "Warning: No technique " << it->technique_ << " in compositor \"" << this->compositorName_ << "\" or technique has no pass with shader." << std::endl;
         }
-        return false;
+        this->parameters_.clear();
     }
 
-    float Shader::getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
+    /**
+        @brief Detects if the Cg program manager plugin is active.
+    */
+    /* static */ bool Shader::hasCgProgramManager()
     {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
+        if (Ogre::Root::getSingletonPtr())
         {
-            if (pointer->first)
-                return (*static_cast<float*>(pointer->second));
-            else
-                return static_cast<float>(*static_cast<int*>(pointer->second));
+            const Ogre::Root::PluginInstanceList& plugins = Ogre::Root::getSingleton().getInstalledPlugins();
+            for (size_t i = 0; i < plugins.size(); ++i)
+                if (plugins[i]->getName() == "Cg Program Manager")
+                    return true;
         }
-        else
-            return 0;
+        return false;
     }
-
-    bool Shader::getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-            return pointer->first;
-        else
-            return false;
-    }
-
-    bool Shader::getParameterIsInt(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-            return (!pointer->first);
-        else
-            return false;
-    }
-
-    Shader::ParameterPointer* Shader::getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        if (!GameMode::showsGraphics() || !Shader::bLoadedCgPlugin_s)
-            return 0;
-
-        MaterialMap::iterator material_iterator = Shader::parameters_s.find(material);
-        if (material_iterator != Shader::parameters_s.end())
-        {
-            TechniqueVector& technique_vector = material_iterator->second;
-            if (technique < technique_vector.size())
-            {
-                PassVector& pass_vector = technique_vector[technique];
-                if (pass < pass_vector.size())
-                {
-                    ParameterMap& parameter_map = pass_vector[pass];
-                    ParameterMap::iterator parameter_iterator = parameter_map.find(parameter);
-
-                    if (parameter_iterator != parameter_map.end())
-                        return (&parameter_iterator->second);
-                    else
-                        COUT(2) << "Warning: No shader parameter \"" << parameter << "\" in pass " << pass << " in technique " << technique << " in material \"" << material << "\"." << std::endl;
-                }
-                else
-                    COUT(2) << "Warning: No pass " << pass << " in technique " << technique << " in material \"" << material << "\" or pass has no shader." << std::endl;
-            }
-            else
-                COUT(2) << "Warning: No technique " << technique << " in material \"" << material << "\" or technique has no pass with shader." << std::endl;
-        }
-        else
-        {
-            bool foundAtLeastOneShaderParameter = false;
-            Ogre::MaterialManager::ResourceMapIterator iterator = Ogre::MaterialManager::getSingleton().getResourceIterator();
-            Ogre::Material* material_pointer = 0;
-
-            while (iterator.hasMoreElements())
-            {
-                Ogre::Resource* resource = iterator.getNext().get();
-                if (resource->getName() == material)
-                    material_pointer = (Ogre::Material*)resource;
-            }
-
-            if (!material_pointer)
-            {
-                COUT(2) << "Warning: No material with name \"" << material << "\" found." << std::endl;
-                return 0;
-            }
-
-            for (unsigned int t = 0; t < material_pointer->getNumTechniques(); ++t)
-            {
-                Ogre::Technique* technique_pointer = material_pointer->getTechnique(t);
-                if (!technique_pointer)
-                    continue;
-
-                for (unsigned int p = 0; p < technique_pointer->getNumPasses(); ++p)
-                {
-                    Ogre::Pass* pass_pointer = technique_pointer->getPass(p);
-                    if (!pass_pointer)
-                        continue;
-
-                    if (!pass_pointer->getFragmentProgramName().empty())
-                    {
-                        Ogre::GpuProgramParameters* parameter_pointer = pass_pointer->getFragmentProgramParameters().get();
-                        if (!parameter_pointer)
-                            continue;
-
-                        const Ogre::GpuConstantDefinitionMap& constant_definitions = parameter_pointer->getConstantDefinitions().map;
-                        for (Ogre::GpuConstantDefinitionMap::const_iterator definition_iterator = constant_definitions.begin(); definition_iterator != constant_definitions.end(); ++definition_iterator)
-                        {
-                            void* temp = (definition_iterator->second.isFloat())
-                                            ? static_cast<void*>(parameter_pointer->getFloatPointer(definition_iterator->second.physicalIndex))
-                                            : static_cast<void*>(parameter_pointer->getIntPointer(definition_iterator->second.physicalIndex));
-                            ParameterPointer parameter_pointer = ParameterPointer(definition_iterator->second.isFloat(), temp);
-
-                            TechniqueVector& technique_vector = Shader::parameters_s[material];
-                            technique_vector.resize(technique + 1);
-                            PassVector& pass_vector = technique_vector[technique];
-                            pass_vector.resize(pass + 1);
-                            pass_vector[pass][definition_iterator->first] = parameter_pointer;
-                            foundAtLeastOneShaderParameter = true;
-                        }
-                    }
-                }
-            }
-
-            // recursive call if the material was added to the map
-            if (foundAtLeastOneShaderParameter)
-                return Shader::getParameterPointer(material, technique, pass, parameter);
-        }
-        return 0;
-    }
 }

Modified: code/trunk/src/libraries/tools/Shader.h
===================================================================
--- code/trunk/src/libraries/tools/Shader.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/tools/Shader.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -35,25 +35,25 @@
 #include <string>
 #include <vector>
 
+#include <OgreCompositorInstance.h>
+
+#include "util/MultiType.h"
 #include "util/OgreForwardRefs.h"
-#include "tools/interfaces/Tickable.h"
+#include "core/ViewportEventListener.h"
 
 namespace orxonox
 {
-    class _ToolsExport Shader : public Tickable
+    /**
+        @brief Shader is a wrapper class around Ogre::CompositorInstance. It provides some
+        functions to easily change the visibility and parameters for shader programs.
+    */
+    class _ToolsExport Shader : public ViewportEventListener, public Ogre::CompositorInstance::Listener
     {
-        typedef std::pair<bool, void*>                  ParameterPointer;
-        typedef std::map<std::string, ParameterPointer> ParameterMap;
-        typedef std::vector<ParameterMap>               PassVector;
-        typedef std::vector<PassVector>                 TechniqueVector;
-        typedef std::map<std::string, TechniqueVector>  MaterialMap;
-
         public:
             Shader(Ogre::SceneManager* scenemanager = 0);
             virtual ~Shader();
 
-            virtual void tick(float dt);
-
+            /// Defines if the shader is visible or not.
             inline void setVisible(bool bVisible)
             {
                 if (this->bVisible_ != bVisible)
@@ -62,47 +62,68 @@
                     this->updateVisibility();
                 }
             }
+            /// Returns whether or not the shader is visible.
             inline bool isVisible() const
                 { return this->bVisible_; }
             void updateVisibility();
 
-            inline void setCompositor(const std::string& compositor)
+            /// Defines the compositor's name (located in a .compositor file).
+            inline void setCompositorName(const std::string& name)
             {
-                if (this->compositor_ != compositor)
+                if (this->compositorName_ != name)
                 {
-                    this->compositor_ = compositor;
-                    this->changedCompositor();
+                    this->compositorName_ = name;
+                    this->changedCompositorName();
                 }
             }
-            inline const std::string& getCompositor() const
-                { return this->compositor_; }
-            void changedCompositor();
+            /// Returns the compositor's name.
+            inline const std::string& getCompositorName() const
+                { return this->compositorName_; }
+            void changedCompositorName();
+            void changedCompositorName(Ogre::Viewport* viewport);
 
-            void setSceneManager(Ogre::SceneManager* scenemanager);
+            /// Sets the scenemanager (usually provided in the constructor, but can be set later). Shouldn't be changed once it's set.
+            inline void setSceneManager(Ogre::SceneManager* scenemanager)
+                { this->scenemanager_ = scenemanager; }
+            /// Returns the scene manager.
             inline Ogre::SceneManager* getSceneManager() const
                 { return this->scenemanager_; }
 
-            void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
-            void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
+            virtual void cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera);
 
-            static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
-            static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
-            static float getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
-            static bool  getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
-            static bool  getParameterIsInt  (const std::string& material, size_t technique, size_t pass, const std::string& parameter);
-            static ParameterPointer* getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+            void setParameter(size_t technique, size_t pass, const std::string& parameter, float value);
+            void setParameter(size_t technique, size_t pass, const std::string& parameter, int value);
 
+            virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr);
+
         private:
-            Ogre::SceneManager* scenemanager_;
-            Ogre::CompositorInstance* compositorInstance_;
-            bool bVisible_;
-            bool bLoadCompositor_;
-            bool bViewportInitialized_;
-            std::string compositor_;
-            std::string oldcompositor_;
+            static bool hasCgProgramManager();
 
-            static MaterialMap parameters_s;
-            static bool bLoadedCgPlugin_s;
+            Ogre::SceneManager* scenemanager_;              ///< The scenemanager for which the shader is active
+            Ogre::CompositorInstance* compositorInstance_;  ///< The compositor instance representing the wrapped compositor
+            bool bVisible_;                                 ///< True if the shader should be visible
+            bool bLoadCompositor_;                          ///< True if the compositor should be loaded (usually false if no graphics)
+            std::string compositorName_;                    ///< The name of the current compositor
+            std::string oldcompositorName_;                 ///< The name of the previous compositor (used to unregister)
+
+        private:
+            void addAsListener();
+
+            /// Helper struct to store parameters for shader programs.
+            struct ParameterContainer
+            {
+                size_t technique_;          ///< The ID of the technique
+                size_t pass_;               ///< The ID of the pass
+                std::string parameter_;     ///< The name of the parameter
+
+                int valueInt_;              ///< The desired int value of the parameter
+                float valueFloat_;          ///< The desired float value of the parameter
+
+                MT_Type::Value valueType_;  ///< The type of the parameter (currently only int or float)
+            };
+
+            std::list<ParameterContainer> parameters_;  ///< The list of parameters that should be set on the next update
+            bool registeredAsListener_;                 ///< True if the shader should register itself as listener at the compositor
     };
 }
 

Modified: code/trunk/src/libraries/tools/Timer.cc
===================================================================
--- code/trunk/src/libraries/tools/Timer.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/tools/Timer.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -35,32 +35,63 @@
 
 #include <set>
 
+#include <boost/bimap.hpp>
+
 #include "util/Clock.h"
 #include "core/CoreIncludes.h"
 #include "core/command/ConsoleCommand.h"
 #include "core/command/CommandExecutor.h"
 #include "core/command/Functor.h"
+#include "tools/interfaces/TimeFactorListener.h"
 
 namespace orxonox
 {
     SetConsoleCommand("delay", &delay).argumentCompleter(1, autocompletion::command());
+    SetConsoleCommand("delayreal", &delayreal).argumentCompleter(1, autocompletion::command());
+    SetConsoleCommand("killdelay", &killdelay);
     SetConsoleCommand("killdelays", &killdelays);
 
-    static std::set<Timer*> delaytimerset;
+    static boost::bimap<unsigned int, Timer*> delaytimers;
+    static unsigned int delayHandleCounter = 0;
 
     /**
-        @brief Console-command: Calls another console command after @a delay seconds.
+        @brief Console-command: Calls another console command after @a delay seconds (game time).
         @param delay The delay in seconds
         @param command The console command
+        @return The handle of the delayed command, can be used as argument for killdelay()
     */
-    void delay(float delay, const std::string& command)
+    unsigned int delay(float delay, const std::string& command)
     {
-        Timer* delaytimer = new Timer();
-        delaytimerset.insert(delaytimer);
+        return addDelayedCommand(new Timer(), delay, command);
+    }
 
+    /**
+        @brief Console-command: Calls another console command after @a delay seconds (real time)
+        @param delay The delay in seconds
+        @param command The console command
+        @return The handle of the delayed command, can be used as argument for killdelay()
+    */
+    unsigned int delayreal(float delay, const std::string& command)
+    {
+        return addDelayedCommand(new RealTimer(), delay, command);
+    }
+
+    /**
+        @brief Helper function, used by delay() and delayreal() to add a delayed command.
+        @param timer The timer which will execute the command
+        @param delay The delay in seconds
+        @param command The console command
+        @return The handle of the delayed command, can be used as argument for killdelay()
+    */
+    unsigned int addDelayedCommand(Timer* timer, float delay, const std::string& command)
+    {
+        delaytimers.insert(boost::bimap<unsigned int, Timer*>::value_type(++delayHandleCounter, timer));
+
         const ExecutorStaticPtr& delayexecutor = createExecutor(createFunctor(&executeDelayedCommand));
-        delayexecutor->setDefaultValues(delaytimer, command);
-        delaytimer->setTimer(delay, false, delayexecutor);
+        delayexecutor->setDefaultValues(timer, command);
+        timer->setTimer(delay, false, delayexecutor);
+
+        return delayHandleCounter;
     }
 
     /**
@@ -72,7 +103,7 @@
     {
         CommandExecutor::execute(command);
         timer->destroy();
-        delaytimerset.erase(timer);
+        delaytimers.right.erase(timer);
     }
 
     /**
@@ -80,19 +111,32 @@
     */
     void killdelays()
     {
-        for (std::set<Timer*>::iterator it = delaytimerset.begin(); it != delaytimerset.end(); ++it)
-            (*it)->destroy();
+        for (boost::bimap<unsigned int, Timer*>::left_map::iterator it = delaytimers.left.begin(); it != delaytimers.left.end(); ++it)
+            it->second->destroy();
 
-        delaytimerset.clear();
+        delaytimers.clear();
     }
 
     /**
+        @brief Console-command: Kills a delayed command with given handle.
+    */
+    void killdelay(unsigned int handle)
+    {
+        boost::bimap<unsigned int, Timer*>::left_map::iterator it = delaytimers.left.find(handle);
+        if (it != delaytimers.left.end())
+        {
+            it->second->destroy();
+            delaytimers.left.erase(it);
+        }
+    }
+
+    /**
         @brief Constructor: Sets the default-values.
     */
     Timer::Timer()
     {
         this->init();
-        RegisterObject(Timer);
+        RegisterRootObject(Timer);
     }
 
     /**
@@ -105,7 +149,7 @@
     Timer::Timer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall)
     {
         this->init();
-        RegisterObject(Timer);
+        RegisterRootObject(Timer);
 
         this->setTimer(interval, bLoop, executor, bKillAfterCall);
     }
@@ -125,6 +169,14 @@
     }
 
     /**
+        @brief Returns the current time factor of the game.
+    */
+    float Timer::getTimeFactor()
+    {
+        return TimeFactorListener::getTimeFactor();
+    }
+
+    /**
         @brief Calls the executor and destroys the timer if requested.
     */
     void Timer::run()
@@ -167,4 +219,25 @@
             }
         }
     }
+
+    ///////////////
+    // RealTimer //
+    ///////////////
+    /// @copydoc Timer::Timer
+    RealTimer::RealTimer()
+    {
+        RegisterObject(RealTimer);
+    }
+
+    /// @copydoc Timer::Timer(float, bool, const ExecutorPtr&, bool)
+    RealTimer::RealTimer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall) : Timer(interval, bLoop, executor, bKillAfterCall)
+    {
+        RegisterObject(RealTimer);
+    }
+
+    /// Returns always 1 because RealTimer doesn't depend on the game time.
+    float RealTimer::getTimeFactor()
+    {
+        return 1;
+    }
 }

Modified: code/trunk/src/libraries/tools/Timer.h
===================================================================
--- code/trunk/src/libraries/tools/Timer.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/tools/Timer.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -80,20 +80,28 @@
 
 #include "core/OrxonoxClass.h"
 #include "core/command/Executor.h"
-#include "tools/interfaces/TimeFactorListener.h"
 
 namespace orxonox
 {
-    void delay(float delay, const std::string& command);
-    void killdelays();
+    unsigned int delay(float delay, const std::string& command);
+    unsigned int delayreal(float delay, const std::string& command);
+
+    unsigned int addDelayedCommand(Timer* timer, float delay, const std::string& command);
     void executeDelayedCommand(Timer* timer, const std::string& command);
 
+    void killdelay(unsigned int handle);
+    void killdelays();
+
     /**
-        @brief Timer is a helper class that executes a function after a given amount of time.
+        @brief Timer is a helper class that executes a function after a given amount of seconds in game-time.
 
         @see See @ref TimerExample "Timer.h" for an example.
+
+        The time interval of Timer depends on the game time, hence it stops if the game is paused or runs
+        slower/faster if the game-speed is modified. See RealTimer for a timer class which doesn't depend
+        on the game time.
     */
-    class _ToolsExport Timer : public TimeFactorListener
+    class _ToolsExport Timer : virtual public OrxonoxClass
     {
         public:
             Timer();
@@ -122,28 +130,28 @@
 
             void run();
 
-            /// Re-starts the Timer: The executor will be called after @a interval seconds.
+            /// Re-starts the timer: The executor will be called after @a interval seconds.
             inline void startTimer()
                 { this->bActive_ = true; this->time_ = this->interval_; }
-            /// Stops the Timer.
+            /// Stops the timer.
             inline void stopTimer()
                 { this->bActive_ = false; this->time_ = this->interval_; }
-            /// Pauses the Timer - it will continue with the actual state if you call unpauseTimer().
+            /// Pauses the timer - it will continue with the actual state if you call unpauseTimer().
             inline void pauseTimer()
                 { this->bActive_ = false; }
-            /// Unpauses the Timer - continues with the given state.
+            /// Unpauses the timer - continues with the given state.
             inline void unpauseTimer()
                 { this->bActive_ = true; }
-            /// Returns true if the Timer is active (neither stopped nor paused).
+            /// Returns true if the timer is active (neither stopped nor paused).
             inline bool isActive() const
                 { return this->bActive_; }
-            /// Returns the remaining time until the Timer calls the executor.
+            /// Returns the remaining time until the timer calls the executor.
             inline float getRemainingTime() const
                 { return static_cast<float>(this->time_ / 1000000.0f); }
-            /// Increases the remaining time of the Timer by the given amount of time (in seconds).
+            /// Increases the remaining time of the timer by the given amount of time (in seconds).
             inline void addTime(float time)
                 { if (time > 0.0f) this->time_ += static_cast<long long>(time * 1000000.0f); }
-            /// Decreases the remaining time of the Timer by the given amount of time (in seconds)
+            /// Decreases the remaining time of the timer by the given amount of time (in seconds)
             inline void removeTime(float time)
                 { if (time > 0.0f) this->time_ -= static_cast<long long>(time * 1000000.0f); }
             /// Changes the calling interval.
@@ -155,6 +163,9 @@
 
             void tick(const Clock& time);
 
+        protected:
+            virtual float getTimeFactor();
+
         private:
             void init();
 
@@ -162,11 +173,27 @@
 
             long long interval_;    //!< The time-interval in micro seconds
             bool bLoop_;            //!< If true, the executor gets called every @a interval seconds
-            bool bActive_;          //!< If true, the Timer ticks and calls the executor if the time's up
+            bool bActive_;          //!< If true, the timer ticks and calls the executor if the time's up
             bool bKillAfterCall_;   //!< If true the timer gets deleted after it expired and called the executor
 
             long long time_;        //!< Internal variable, counting the time untill the next executor-call
     };
+
+    /**
+        @brief RealTimer is a helper class that executes a function after a given amount of seconds in real-time.
+
+        The time interval of RealTimer doesn't depend on the game time, it will also call the function
+        if the game is paused. See Timer for a timer class that depends on the game time.
+    */
+    class _ToolsExport RealTimer : public Timer
+    {
+        public:
+            RealTimer();
+            RealTimer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall = false);
+
+        protected:
+            virtual float getTimeFactor();
+    };
 }
 
 #endif /* _Timer_H__ */

Modified: code/trunk/src/libraries/tools/ToolsPrereqs.h
===================================================================
--- code/trunk/src/libraries/tools/ToolsPrereqs.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/libraries/tools/ToolsPrereqs.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -84,6 +84,7 @@
     class BillboardSet;
     class Mesh;
     class ParticleInterface;
+    class RealTimer;
     class ResourceCollection;
     class ResourceLocation;
     class Shader;

Modified: code/trunk/src/modules/designtools/ScreenshotManager.cc
===================================================================
--- code/trunk/src/modules/designtools/ScreenshotManager.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/designtools/ScreenshotManager.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -24,33 +24,28 @@
     ScreenshotManager::ScreenshotManager()
     {
         Ogre::RenderWindow* pRenderWindow = GraphicsManager::getInstance().getRenderWindow();
-        int gridSize = 3;
-        std::string fileExtension = ".png";
-        bool overlayFlag = true;
 
         //set file extension for the Screenshot files
-        mFileExtension   = fileExtension;
+        this->mFileExtension_  = ".png";
         // the gridsize
-        mGridSize        = gridSize;
+        this->mGridSize_ = 3;
         // flag for overlay rendering
-        mDisableOverlays = overlayFlag;
+        this->mDisableOverlays_ = true;
         //get current window size
-        mWindowWidth   = pRenderWindow->getWidth();
-        mWindowHeight  = pRenderWindow->getHeight();
+        this->mWindowWidth_   = pRenderWindow->getWidth();
+        this->mWindowHeight_  = pRenderWindow->getHeight();
         //create temporary texture
-        mTempTex = Ogre::TextureManager::getSingleton().createManual("ScreenShotTex",
-                                                                  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D,
-                                                                    mWindowWidth, mWindowHeight,0, Ogre::PF_B8G8R8, Ogre::TU_RENDERTARGET);
+        this->mTempTex_ = Ogre::TextureManager::getSingleton().createManual("ScreenShotTex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, this->mWindowWidth_, this->mWindowHeight_, 0, Ogre::PF_B8G8R8, Ogre::TU_RENDERTARGET);
 
         //get The current Render Target of the temp Texture
-        mRT = mTempTex->getBuffer()->getRenderTarget();
+        this->mRT_ = this->mTempTex_->getBuffer()->getRenderTarget();
 
         //HardwarePixelBufferSharedPtr to the Buffer of the temp Texture
-        mBuffer = mTempTex->getBuffer();
+        this->mBuffer_ = this->mTempTex_->getBuffer();
 
         //create PixelBox
-            uint8_t* data_ = new uint8_t[(mWindowWidth * mGridSize) * (mWindowHeight * mGridSize) * 3];
-        mFinalPicturePB = Ogre::PixelBox(mWindowWidth * mGridSize,mWindowHeight * mGridSize,1,Ogre::PF_B8G8R8,data_);
+        uint8_t* data_ = new uint8_t[(this->mWindowWidth_ * this->mGridSize_) * (this->mWindowHeight_ * this->mGridSize_) * 3];
+        this->mFinalPicturePB_ = Ogre::PixelBox(this->mWindowWidth_ * this->mGridSize_, this->mWindowHeight_ * this->mGridSize_, 1, Ogre::PF_B8G8R8, data_);
 
     }
 
@@ -62,9 +57,13 @@
     }
 
 
-    /* Creates a screenshot with the given camera.
-    * @param camera Pointer to the camera "looking at" the scene of interest
-    * @param fileName the filename of the screenshot file.
+    /**
+    @brief
+        Creates a screenshot with the given camera.
+    @param camera
+        Pointer to the camera "looking at" the scene of interest
+    @param fileName
+        the filename of the screenshot file.
     */
     void ScreenshotManager::makeScreenshot() const
     {
@@ -72,11 +71,11 @@
         std::string fileName = PathConfig::getInstance().getLogPathString() + "screenshot_" + this->getTimestamp();
 
         //Remove all viewports, so the added Viewport(camera) ist the only
-        mRT->removeAllViewports();
-        mRT->addViewport(camera);
+        mRT_->removeAllViewports();
+        mRT_->addViewport(camera);
 
         //set the viewport settings
-        Ogre::Viewport *vp = mRT->getViewport(0);
+        Ogre::Viewport *vp = mRT_->getViewport(0);
         vp->setClearEveryFrame(true);
         vp->setOverlaysEnabled(false);
 
@@ -84,17 +83,17 @@
         bool enableOverlayFlag = GraphicsManager::getInstance().getViewport()->getOverlaysEnabled();
 
         // we disable overlay rendering if it is set in config file and the viewport setting is enabled
-        if(mDisableOverlays && enableOverlayFlag)
+        if(mDisableOverlays_ && enableOverlayFlag)
             GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(false);
 
-        if(mGridSize <= 1)
+        if(mGridSize_ <= 1)
         {
             // Simple case where the contents of the screen are taken directly
             // Also used when an invalid value is passed within gridSize (zero or negative grid size)
-            mRT->update();    //render
+            mRT_->update();    //render
 
             //write the file on the Harddisk
-            mRT->writeContentsToFile(fileName + "." + mFileExtension);
+            mRT_->writeContentsToFile(fileName + "." + mFileExtension_);
         }
         else
         {
@@ -104,15 +103,15 @@
             camera->getFrustumExtents(originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom);
 
             // compute the Stepsize for the drid
-            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / mGridSize;
-            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / mGridSize;
+            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / mGridSize_;
+            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / mGridSize_;
 
             // process each grid
             Ogre::Real frustumLeft, frustumRight, frustumTop, frustumBottom;
-            for (unsigned int nbScreenshots = 0; nbScreenshots < mGridSize * mGridSize; nbScreenshots++)
+            for (unsigned int nbScreenshots = 0; nbScreenshots < mGridSize_ * mGridSize_; nbScreenshots++)
             {
-                int y = nbScreenshots / mGridSize;
-                int x = nbScreenshots - y * mGridSize;
+                int y = nbScreenshots / mGridSize_;
+                int x = nbScreenshots - y * mGridSize_;
 
                 // Shoggoth frustum extents setting
                 // compute the new frustum extents
@@ -126,13 +125,13 @@
 
                 // ignore time duration between frames
                 Ogre::Root::getSingletonPtr()->clearEventTimes();
-                mRT->update();    //render
+                mRT_->update();    //render
 
                 //define the current
-                Ogre::Box subBox = Ogre::Box(x* mWindowWidth,y * mWindowHeight,x * mWindowWidth + mWindowWidth, y * mWindowHeight + mWindowHeight);
+                Ogre::Box subBox = Ogre::Box(x* mWindowWidth_,y * mWindowHeight_,x * mWindowWidth_ + mWindowWidth_, y * mWindowHeight_ + mWindowHeight_);
                 //copy the content from the temp buffer into the final picture PixelBox
                 //Place the tempBuffer content at the right position
-                mBuffer->blitToMemory(mFinalPicturePB.getSubVolume(subBox));
+                mBuffer_->blitToMemory(mFinalPicturePB_.getSubVolume(subBox));
 
             }
 
@@ -141,9 +140,9 @@
 
             Ogre::Image finalImage; //declare the final Image Object
             //insert the PixelBox data into the Image Object
-            finalImage = finalImage.loadDynamicImage(static_cast<unsigned char*>(mFinalPicturePB.data), mFinalPicturePB.getWidth(),mFinalPicturePB.getHeight(),Ogre::PF_B8G8R8);
+            finalImage = finalImage.loadDynamicImage(static_cast<unsigned char*>(mFinalPicturePB_.data), mFinalPicturePB_.getWidth(), mFinalPicturePB_.getHeight(),Ogre::PF_B8G8R8);
             // Save the Final image to a file
-            finalImage.save(fileName + "." + mFileExtension);
+            finalImage.save(fileName + "." + mFileExtension_);
 
         }
 
@@ -156,6 +155,29 @@
         Ogre::Root::getSingletonPtr()->clearEventTimes();
     }
 
+    /**
+    @brief
+        Set the size of the grid.
+    @param size
+        The size of the grid.
+    */
+    void ScreenshotManager::setGridSize(unsigned int size)
+    {
+        if(size == this->mGridSize_)
+            return;
+
+        this->mGridSize_ = size;
+        // New PixelBox for the changed size.
+        uint8_t* data_ = new uint8_t[(this->mWindowWidth_ * this->mGridSize_) * (this->mWindowHeight_ * this->mGridSize_) * 3];
+        this->mFinalPicturePB_ = Ogre::PixelBox(this->mWindowWidth_ * this->mGridSize_, this->mWindowHeight_ * this->mGridSize_, 1, Ogre::PF_B8G8R8, data_);
+    }
+
+    /**
+    @brief
+        Get a timestamp for the curent time instant.
+    @return
+        Returns a string with the timestamp.
+    */
     std::string ScreenshotManager::getTimestamp()
     {
         struct tm *pTime;

Modified: code/trunk/src/modules/designtools/ScreenshotManager.h
===================================================================
--- code/trunk/src/modules/designtools/ScreenshotManager.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/designtools/ScreenshotManager.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -19,50 +19,45 @@
 namespace orxonox
 {
 
-
-    /* Class encapsulates Screenshot functionality and provides a method for making multi grid screenshots.
-    *  pRenderWindow:    Pointer to the render window.  This could be "mWindow" from the ExampleApplication,
-    *              the window automatically created obtained when calling
-    *              Ogre::Root::getSingletonPtr()->initialise(false) and retrieved by calling
-    *              "Ogre::Root::getSingletonPtr()->getAutoCreatedWindow()", or the manually created
-    *              window from calling "mRoot->createRenderWindow()".
-    *  gridSize:      The magnification factor.  A 2 will create a 2x2 grid, doubling the size of the
-                screenshot.  A 3 will create a 3x3 grid, tripling the size of the screenshot.
-    *  fileExtension:    The extension of the screenshot file name, hence the type of graphics file to generate.
-    *              To generate "MyScreenshot.png" this parameter would contain ".png".
+    /**
+    @brief
+        Class encapsulates Screenshot functionality and provides a method for making multi grid screenshots.
     */
     class ScreenshotManager : public OrxonoxClass, public Singleton<ScreenshotManager>
     {
         friend class Singleton<ScreenshotManager>;
 
-    public:
-        ScreenshotManager();
-        ~ScreenshotManager();
+        public:
+            ScreenshotManager();
+            virtual ~ScreenshotManager();
 
-      /* Creates a screenshot with the given camera.
-        * @param camera Pointer to the camera "looking at" the scene of interest
-        * @param fileName the filename of the screenshot file.
-      */
-        void makeScreenshot() const;
+            void makeScreenshot() const; //!< Creates a screenshot with the given camera.
 
-        static void makeScreenshot_s()
-            { getInstance().makeScreenshot(); }
+            /**
+            @brief Creates a screenshot with a given size.
+            @param size Size is factor by which the current screen size is scaled.
+            */
+            static void makeScreenshot_s(unsigned int size)
+                { getInstance().setGridSize(size); getInstance().makeScreenshot(); }
 
-    protected:
-        static std::string getTimestamp();
+            void setGridSize(unsigned int size); //!< Set the size of the grid.
 
-        std::string    mFileExtension;
-        unsigned int   mGridSize, mWindowWidth, mWindowHeight;
-        bool           mDisableOverlays;
-        //temp texture with current screensize
-        Ogre::TexturePtr mTempTex;
-        Ogre::RenderTexture* mRT;
-        Ogre::HardwarePixelBufferSharedPtr mBuffer;
-        //PixelBox for a large Screenshot, if grid size is > 1
-        Ogre::PixelBox  mFinalPicturePB;
-        uint8_t* data_;
+        protected:
+            static std::string getTimestamp();
 
-        static ScreenshotManager* singletonPtr_s;
+            std::string mFileExtension_;
+            unsigned int mGridSize_; //!< The magnification factor.  A 2 will create a 2x2 grid, doubling the size of the screenshot.  A 3 will create a 3x3 grid, tripling the size of the screenshot.
+            unsigned int mWindowWidth_, mWindowHeight_;
+            bool mDisableOverlays_;
+            //! temp texture with current screensize
+            Ogre::TexturePtr mTempTex_;
+            Ogre::RenderTexture* mRT_;
+            Ogre::HardwarePixelBufferSharedPtr mBuffer_;
+            //! PixelBox for a large Screenshot, if grid size is > 1
+            Ogre::PixelBox  mFinalPicturePB_;
+            uint8_t* data_;
+
+            static ScreenshotManager* singletonPtr_s;
     };
 
 }

Modified: code/trunk/src/modules/designtools/SkyboxGenerator.cc
===================================================================
--- code/trunk/src/modules/designtools/SkyboxGenerator.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/designtools/SkyboxGenerator.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -58,7 +58,7 @@
         RegisterRootObject(SkyboxGenerator);
 
         this->setConfigValues();
-        takeScreenshot_ = false;
+        this->takeScreenshot_ = false;
         this->captionsRemoved_ = false;
     }
 

Modified: code/trunk/src/modules/notifications/NotificationManager.cc
===================================================================
--- code/trunk/src/modules/notifications/NotificationManager.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/notifications/NotificationManager.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -102,8 +102,12 @@
     void NotificationManager::preDestroy(void)
     {
         // Destroys all NotificationQueues that have been registered with the NotificationManager.
-        for(std::map<const std::string, NotificationQueue*>::iterator it = this->queues_.begin(); it != this->queues_.end(); it++)
+        std::map<const std::string, NotificationQueue*>::iterator it = this->queues_.begin();
+        while(it != this->queues_.end())
+        {
             it->second->destroy(true);
+            it = this->queues_.begin();
+        }
 
         this->queues_.clear();
     }
@@ -297,12 +301,12 @@
             delete map;
         }
 
+        COUT(4) << "NotificationListener '" << identifier << "' unregistered with the NotificationManager." << std::endl;
+
         // Remove the NotificationListener from the list of NotificationListeners.
         this->listenerList_.erase(listener);
         // Remove the Notifications list that was associated with the input NotificationListener.
         this->notificationLists_.erase(identifier);
-
-        COUT(4) << "NotificationListener unregistered with the NotificationManager." << std::endl;
     }
 
     /**
@@ -360,6 +364,7 @@
     */
     bool NotificationManager::registerQueue(NotificationQueue* queue)
     {
+        COUT(4) << "NotificationQueue '" << queue->getName() << "' registered with the NotificationManager." << std::endl;
         return this->queues_.insert(std::pair<const std::string, NotificationQueue*>(queue->getName(), queue)).second;
     }
 
@@ -371,6 +376,7 @@
     */
     void NotificationManager::unregisterQueue(NotificationQueue* queue)
     {
+        COUT(4) << "NotificationQueue '" << queue->getName() << "' unregistered with the NotificationManager." << std::endl;
         this->queues_.erase(queue->getName());
     }
 

Modified: code/trunk/src/modules/notifications/NotificationQueue.cc
===================================================================
--- code/trunk/src/modules/notifications/NotificationQueue.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/notifications/NotificationQueue.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -136,6 +136,8 @@
         if(GameMode::showsGraphics() && !noGraphics)
             GUIManager::getInstance().getLuaState()->doString("NotificationLayer.removeQueue(\"" + this->getName() +  "\")");
 
+        COUT(3) << "NotificationQueue '" << this->getName() << "' destroyed." << std::endl;
+
         this->OrxonoxClass::destroy();
     }
 
@@ -166,9 +168,8 @@
             // Iterate through all elements whose creation time is smaller than the current time minus the display time.
             while(it != this->ordering_.upper_bound(&this->timeLimit_))
             {
-                std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator temp = it;
-                it++;
-                this->remove(temp); // Remove the Notifications that have expired.
+                this->remove(it); // Remove the Notifications that have expired.
+                it = this->ordering_.begin();
             }
 
             this->tickTime_ = this->tickTime_ - (int)this->tickTime_; // Reset time counter.
@@ -247,6 +248,8 @@
         // Push the Notification to the GUI.
         if(GameMode::showsGraphics())
             GUIManager::getInstance().getLuaState()->doString("NotificationLayer.pushNotification(\"" + this->getName() + "\", \"" + notification->getMessage() + "\")");
+
+        COUT(5) << "Notification \"" << notification->getMessage() << "\" pushed to NotificationQueue '" << this->getName() << "'" << endl;
     }
 
     /**
@@ -258,11 +261,13 @@
         NotificationContainer* container = this->notifications_.back();
         // Get all the NotificationContainers that were sent the same time the NotificationContainer we want to pop was sent.
         std::pair<std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator, std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator> iterators = this->ordering_.equal_range(container);
+
         // Iterate through all suspects and remove the container as soon as we find it.
         for(std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator it = iterators.first; it != iterators.second; it++)
         {
             if(container == *it)
             {
+                COUT(5) << "Notification \"" << (*it)->notification->getMessage() << "\" popped from NotificationQueue '" << this->getName() << "'" << endl;
                 this->ordering_.erase(it);
                 break;
             }
@@ -289,6 +294,9 @@
         std::vector<NotificationContainer*>::iterator it = std::find(this->notifications_.begin(), this->notifications_.end(), *containerIterator);
         // Get the index at which the Notification is.
         std::vector<NotificationContainer*>::difference_type index = it - this->notifications_.begin ();
+
+        COUT(5) << "Notification \"" << (*it)->notification->getMessage() << "\" removed from NotificationQueue '" << this->getName() << "'" << endl;
+
         this->ordering_.erase(containerIterator);
         this->notifications_.erase(it);
 
@@ -309,6 +317,7 @@
     */
     void NotificationQueue::clear(bool noGraphics)
     {
+        COUT(4) << "Clearing NotificationQueue " << this->getName() << "." << endl;
         this->ordering_.clear();
         // Delete all NotificationContainers in the list.
         for(std::vector<NotificationContainer*>::iterator it = this->notifications_.begin(); it != this->notifications_.end(); it++)
@@ -371,7 +380,7 @@
 
     /**
     @brief
-        Produces all targets of the NotificationQueue concatinated as string, with kommas (',') as seperators.
+        Produces all targets of the NotificationQueue concatinated as string, with commas (',') as seperators.
     @return
         Returns the targets as a string.
     */

Modified: code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -53,7 +53,7 @@
         RegisterObject(DistanceMultiTrigger);
 
         this->distance_ = 100.0f;
-        this->targetName_ = BLANKSTRING;
+        this->targetName_ = "";
         this->singleTargetMode_ = false;
     }
 
@@ -180,7 +180,7 @@
     void DistanceMultiTrigger::setTargetName(const std::string& targetname)
     {
         // If the targetname is no blank string single-target mode is enabled.
-        if(targetname.compare(BLANKSTRING) != 0)
+        if(targetname != "")
             this->singleTargetMode_ = true;
         else
             this->singleTargetMode_ = false;

Modified: code/trunk/src/modules/objects/triggers/DistanceTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceTrigger.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/objects/triggers/DistanceTrigger.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -49,7 +49,7 @@
 
     this->distance_ = 100;
     this->targetMask_.exclude(Class(BaseObject));
-    this->targetName_ = BLANKSTRING;
+    this->targetName_ = "";
     this->singleTargetMode_ = false;
   }
 

Modified: code/trunk/src/modules/objects/triggers/DistanceTrigger.h
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceTrigger.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/objects/triggers/DistanceTrigger.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -69,7 +69,7 @@
       void removeTargets(const std::string& targets);
 
       inline void setTargetName(const std::string& targetname)
-        { if(targetname.compare(BLANKSTRING) != 0) this->singleTargetMode_ = true; else this->singleTargetMode_ = false; this->targetName_ = targetname; }
+        { if(targetname != "") this->singleTargetMode_ = true; else this->singleTargetMode_ = false; this->targetName_ = targetname; }
       inline const std::string& getTargetName(void)
         { return this->targetName_; }
 

Modified: code/trunk/src/modules/overlays/OverlaysPrereqs.h
===================================================================
--- code/trunk/src/modules/overlays/OverlaysPrereqs.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/overlays/OverlaysPrereqs.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -88,6 +88,7 @@
     class HUDTimer;
     class KillMessage;
     class LastManStandingInfos;
+    class PauseNotice;
     class TeamBaseMatchScore;
     class UnderAttackHealthBar;
 

Modified: code/trunk/src/modules/overlays/hud/CMakeLists.txt
===================================================================
--- code/trunk/src/modules/overlays/hud/CMakeLists.txt	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/overlays/hud/CMakeLists.txt	2011-03-15 20:47:11 UTC (rev 8079)
@@ -15,4 +15,5 @@
   GametypeStaticMessage.cc
   GametypeFadingMessage.cc
   LastManStandingInfos.cc
+  PauseNotice.cc
 )

Copied: code/trunk/src/modules/overlays/hud/PauseNotice.cc (from rev 8078, code/branches/usability/src/modules/overlays/hud/PauseNotice.cc)
===================================================================
--- code/trunk/src/modules/overlays/hud/PauseNotice.cc	                        (rev 0)
+++ code/trunk/src/modules/overlays/hud/PauseNotice.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -0,0 +1,59 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 2
+ *   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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PauseNotice.h"
+
+#include "core/CoreIncludes.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateFactory(PauseNotice);
+
+    PauseNotice::PauseNotice(BaseObject* creator) : OverlayText(creator)
+    {
+        RegisterObject(PauseNotice);
+
+        this->owner_ = 0;
+    }
+
+    void PauseNotice::changedOwner()
+    {
+        SUPER(PauseNotice, changedOwner);
+
+        this->owner_ = orxonox_cast<PlayerInfo*>(this->getOwner());
+    }
+
+    void PauseNotice::changedTimeFactor(float factor_new, float factor_old)
+    {
+        if (factor_new == 0)
+            this->setCaption("Paused");
+        else
+            this->setCaption("");
+    }
+}

Copied: code/trunk/src/modules/overlays/hud/PauseNotice.h (from rev 8078, code/branches/usability/src/modules/overlays/hud/PauseNotice.h)
===================================================================
--- code/trunk/src/modules/overlays/hud/PauseNotice.h	                        (rev 0)
+++ code/trunk/src/modules/overlays/hud/PauseNotice.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -0,0 +1,53 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 2
+ *   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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PauseNotice_H__
+#define _PauseNotice_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "tools/interfaces/TimeFactorListener.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport PauseNotice : public OverlayText, public TimeFactorListener
+    {
+        public:
+            PauseNotice(BaseObject* creator);
+
+            virtual void changedOwner();
+
+        protected:
+            virtual void changedTimeFactor(float factor_new, float factor_old);
+
+        private:
+            PlayerInfo* owner_;
+    };
+}
+#endif /* _PauseNotice_H__ */

Modified: code/trunk/src/modules/pickup/PickupRepresentation.cc
===================================================================
--- code/trunk/src/modules/pickup/PickupRepresentation.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/pickup/PickupRepresentation.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -155,7 +155,7 @@
         if(this->spawnerRepresentation_ == NULL)
         {
             COUT(4) << "PickupRepresentation: No spawner representation found." << std::endl;
-            if(this->spawnerTemplate_ == BLANKSTRING)
+            if(this->spawnerTemplate_ == "")
             {
                 COUT(4) << "PickupRepresentation: Spawner template is empty." << std::endl;
                 // If neither spawnerRepresentation nor spawnerTemplate was specified

Modified: code/trunk/src/modules/questsystem/QuestItem.cc
===================================================================
--- code/trunk/src/modules/questsystem/QuestItem.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/questsystem/QuestItem.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -86,7 +86,7 @@
     */
     void QuestItem::setId(const std::string & id)
     {
-        if(id.compare(BLANKSTRING) == 0) // Checks whether the id is a valid id.
+        if(id == "") // Checks whether the id is a valid id.
         {
             COUT(2) << "Invalid id. QuestItem id {" << id << "} could not be set." << std::endl;
             return;

Modified: code/trunk/src/modules/questsystem/QuestManager.cc
===================================================================
--- code/trunk/src/modules/questsystem/QuestManager.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/questsystem/QuestManager.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -90,7 +90,7 @@
 
     /**
     @brief
-        Registers a Quest with the QuestManager to make it globally accessable.
+        Registers a Quest with the QuestManager to make it globally accessible.
         Uses it's id to make sure to be able to be identify and retrieve it later.
     @param quest
         The Quest that is to be registered.
@@ -128,7 +128,7 @@
 
     /**
     @brief
-        Registers a QuestHint with the QuestManager to make it globally accessable.
+        Registers a QuestHint with the QuestManager to make it globally accessible.
         Uses it's id to make sure to be able to be identify and retrieve it later.
     @param hint
         The QuestHint to be registered.
@@ -177,7 +177,7 @@
     */
     Quest* QuestManager::findQuest(const std::string & questId)
     {
-        if(questId.compare(BLANKSTRING) == 1) // Check vor validity of the given id.
+        if(questId == "") // Check for validity of the given id.
             ThrowException(Argument, "Invalid questId.");
 
         Quest* quest;
@@ -206,7 +206,7 @@
     */
     QuestHint* QuestManager::findHint(const std::string & hintId)
     {
-        if(hintId.compare(BLANKSTRING) == 1) // Check vor validity of the given id.
+        if(hintId == "") // Check for validity of the given id.
             ThrowException(Argument, "Invalid hintId.");
 
         QuestHint* hint;

Modified: code/trunk/src/modules/questsystem/effects/AddQuestHint.cc
===================================================================
--- code/trunk/src/modules/questsystem/effects/AddQuestHint.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/questsystem/effects/AddQuestHint.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -85,7 +85,7 @@
     */
     bool AddQuestHint::setHintId(const std::string & id)
     {
-        if(id.compare(BLANKSTRING) == 0)
+        if(id == "")
         {
             COUT(2) << "Invalid id. QuestItem id {" << id << "} could not be set." << std::endl;
             return false;

Modified: code/trunk/src/modules/questsystem/effects/ChangeQuestStatus.cc
===================================================================
--- code/trunk/src/modules/questsystem/effects/ChangeQuestStatus.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/modules/questsystem/effects/ChangeQuestStatus.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -80,7 +80,7 @@
     */
     bool ChangeQuestStatus::setQuestId(const std::string & id)
     {
-        if(id.compare(BLANKSTRING) == 0)
+        if(id == "")
         {
             COUT(2) << "Invalid id. QuestItem id {" << id << "} could not be set." << std::endl;
             return false;

Modified: code/trunk/src/orxonox/CameraManager.cc
===================================================================
--- code/trunk/src/orxonox/CameraManager.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/CameraManager.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -28,33 +28,30 @@
 
 #include "CameraManager.h"
 
+#include <cassert>
+
 #include <OgreSceneManager.h>
 #include <OgreViewport.h>
 #include <OgreCompositorManager.h>
 
-#include "util/StringUtils.h"
 #include "util/ScopedSingletonManager.h"
 #include "core/GameMode.h"
 #include "core/GraphicsManager.h"
-#include "core/GUIManager.h"
 #include "core/ObjectList.h"
 #include "tools/Shader.h"
 #include "graphics/Camera.h"
-#include "Scene.h"
 
 namespace orxonox
 {
     ManageScopedSingleton(CameraManager, ScopeID::Graphics, false);
 
     CameraManager::CameraManager()
-        : viewport_(GraphicsManager::getInstance().getViewport())
     {
         assert(GameMode::showsGraphics());
     }
 
     CameraManager::~CameraManager()
     {
-        GUIManager::getInstance().setCamera(0);
     }
 
     Camera* CameraManager::getActiveCamera() const
@@ -94,6 +91,8 @@
             // set new focus if possible
             if (!this->cameraList_.empty())
                 this->cameraList_.front()->setFocus();
+            else
+                this->useCamera(NULL);
         }
         else
             this->cameraList_.remove(camera);
@@ -101,27 +100,6 @@
 
     void CameraManager::useCamera(Ogre::Camera* camera)
     {
-        // This workaround is needed to avoid weird behaviour with active compositors while
-        // switching the camera (like freezing the image)
-        //
-        // Last known Ogre version needing this workaround:
-        // 1.4.8
-        // 1.7.2
-
-        // deactivate all compositors
-        {
-            Ogre::ResourceManager::ResourceMapIterator iterator = Ogre::CompositorManager::getSingleton().getResourceIterator();
-            while (iterator.hasMoreElements())
-                Ogre::CompositorManager::getSingleton().setCompositorEnabled(this->viewport_, iterator.getNext()->getName(), false);
-        }
-
-        this->viewport_->setCamera(camera);
-        GUIManager::getInstance().setCamera(camera);
-
-        // reactivate all visible compositors
-        {
-            for (ObjectList<Shader>::iterator it = ObjectList<Shader>::begin(); it != ObjectList<Shader>::end(); ++it)
-                it->updateVisibility();
-        }
+        GraphicsManager::getInstance().setCamera(camera);
     }
 }

Modified: code/trunk/src/orxonox/CameraManager.h
===================================================================
--- code/trunk/src/orxonox/CameraManager.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/CameraManager.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -37,12 +37,10 @@
 
 #include "OrxonoxPrereqs.h"
 
-#include <cassert>
 #include <list>
 #include "util/OgreForwardRefs.h"
 #include "util/Singleton.h"
 #include "core/OrxonoxClass.h"
-#include "core/SmartPtr.h"
 
 namespace orxonox
 {
@@ -64,7 +62,6 @@
             CameraManager(const CameraManager&); // don't use
 
             std::list<Camera*>    cameraList_;
-            Ogre::Viewport*       viewport_;
 
             static CameraManager* singletonPtr_s;
     };

Modified: code/trunk/src/orxonox/ChatInputHandler.cc
===================================================================
--- code/trunk/src/orxonox/ChatInputHandler.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/ChatInputHandler.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -27,18 +27,27 @@
  */
 
 #include "ChatInputHandler.h"
-#include "util/ScopedSingletonManager.h"
-#include "core/CoreIncludes.h"
-#include "core/GUIManager.h"
-#include "core/CorePrereqs.h"
-#include "core/command/ConsoleCommand.h"
+
+#include <cassert>
+#include <string>
 #include <CEGUIWindow.h>
+#include <CEGUIWindowManager.h>
 #include <elements/CEGUIListbox.h>
 #include <elements/CEGUIListboxItem.h>
 #include <elements/CEGUIListboxTextItem.h>
-#include <CEGUIWindowManager.h>
-#include <string>
 
+#include "util/ScopedSingletonManager.h"
+#include "core/CoreIncludes.h"
+#include "core/GUIManager.h"
+#include "core/command/ConsoleCommand.h"
+#include "core/input/InputBuffer.h"
+#include "core/input/InputManager.h"
+#include "core/input/InputState.h"
+#include "network/Host.h"
+
+#include "PlayerManager.h"
+#include "infos/PlayerInfo.h"
+
 namespace orxonox
 {
   /* singleton */
@@ -73,6 +82,13 @@
     this->inputState->setKeyHandler(this->inpbuf);
   }
 
+  ChatInputHandler::~ChatInputHandler()
+  {
+    /* Clean up */
+    InputManager::getInstance().destroyState("chatinput");
+    delete this->inpbuf;
+  }
+
   /* configure input buffer, sub for the constructor */
   void ChatInputHandler::configureInputBuffer()
   {
@@ -124,24 +140,21 @@
     // three loops: red tones, blue tones and green tones
     // reds
     for( i = 0; i < NumberOfColors/3; ++i )
-    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
-      assert( this->text_colors[ i ] );
+    { this->text_colors[ i ] = CEGUI::colour( red, green, blue );
       green += 0.2f, blue += 0.2f;
     }
 
     // greens
     red = 0.5, green = 1, blue = 0.5;
     for( ; i < NumberOfColors*2/3; ++i )
-    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
-      assert( this->text_colors[ i ] );
+    { this->text_colors[ i ] = CEGUI::colour( red, green, blue );
       red += 0.2f, blue += 0.2f;
     }
 
     // blues
     red = 0.5, green = 0.5, blue = 1;
     for( ; i < NumberOfColors; ++i )
-    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
-      assert( this->text_colors[ i ] );
+    { this->text_colors[ i ] = CEGUI::colour( red, green, blue );
       red += 0.2f, green += 0.2f;
     }
   }
@@ -195,7 +208,7 @@
     hash = hash % this->NumberOfColors;
 
     /* set the color according to the hash */
-    tocolor->setTextColours( *(this->text_colors[ hash ]) );
+    tocolor->setTextColours( this->text_colors[ hash ] );
   }
 
   /* handle incoming chat */

Modified: code/trunk/src/orxonox/ChatInputHandler.h
===================================================================
--- code/trunk/src/orxonox/ChatInputHandler.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/ChatInputHandler.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -29,30 +29,15 @@
 #ifndef _ChatInputHandler_H__
 #define _ChatInputHandler_H__
 
-/* std includes */
-#include <deque>
+#include <OrxonoxPrereqs.h>
+
 #include <string>
-#include <fstream>
-#include <iostream>
-#include <cassert>
 #include <CEGUIForwardRefs.h>
+#include <CEGUIcolour.h>
 
-/* project includes */
-#include <OrxonoxPrereqs.h>
-#include <core/BaseObject.h>
-#include <core/PathConfig.h>
+#include "util/Singleton.h"
+#include "network/ChatListener.h"
 
-#include "core/input/InputBuffer.h"
-#include "core/input/InputManager.h"
-#include "core/input/InputState.h"
-
-#include <network/ChatListener.h>
-#include <PlayerManager.h>
-#include <infos/PlayerInfo.h>
-
-#include "../libraries/network/Host.h"
-#include <util/Singleton.h>
-
 namespace orxonox // tolua_export
 { // tolua_export
   /* class to handle chat using an InputBuffer */
@@ -69,7 +54,7 @@
 
       /* colors for nickname coloring */
       static const int NumberOfColors = 10;
-      CEGUI::colour *text_colors[ NumberOfColors ];
+      CEGUI::colour text_colors[ NumberOfColors ];
 
       /** input state */
       InputState *inputState;
@@ -109,6 +94,7 @@
     public:
       /** constructor */
       ChatInputHandler();
+      ~ChatInputHandler();
       friend class Singleton<ChatInputHandler>;
 
       static ChatInputHandler& getInstance(void) { return Singleton<ChatInputHandler>::getInstance(); }  // tolua_export

Modified: code/trunk/src/orxonox/LevelInfo.h
===================================================================
--- code/trunk/src/orxonox/LevelInfo.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/LevelInfo.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -108,7 +108,7 @@
             @brief Get the XML-filename of the Level.
             @return Returns the XML-filename (including *.oxw extension) of the Level.
             */
-            inline const std::string& getXMLFilename(void) { return this->xmlfilename_; } // tolua_export
+            inline const std::string& getXMLFilename(void) const { return this->xmlfilename_; } // tolua_export
 
         protected:
             /**
@@ -211,7 +211,11 @@
     struct LevelInfoCompare
     {
         bool operator() (const LevelInfoItem* lhs, const LevelInfoItem* rhs) const
-            { return getLowercase(lhs->getName()).compare(getLowercase(rhs->getName())) < 0; }
+            {
+                if(getLowercase(lhs->getName()).compare(getLowercase(rhs->getName())) == 0)
+                    return getLowercase(lhs->getXMLFilename()).compare(getLowercase(rhs->getXMLFilename())) < 0;
+                return getLowercase(lhs->getName()).compare(getLowercase(rhs->getName())) < 0;
+            }
     };
     
 } // tolua_export

Modified: code/trunk/src/orxonox/LevelManager.cc
===================================================================
--- code/trunk/src/orxonox/LevelManager.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/LevelManager.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -74,6 +74,10 @@
 
     LevelManager::~LevelManager()
     {
+        // Delete all the LevelInfoItem objects because the LevelManager created them
+        std::set<LevelInfoItem*, LevelInfoCompare>::iterator it = availableLevels_.begin();
+        for (; it != availableLevels_.end(); ++it)
+            delete *it;
     }
 
     /**
@@ -236,36 +240,56 @@
     */
     void LevelManager::compileAvailableLevelList()
     {
+        // Get all files matching the level criteria
         Ogre::StringVectorPtr levels = Resource::findResourceNames("*.oxw");
-        // Iterate over all *.oxw level files.
+
+        // We only want to load as little as possible
+        ClassTreeMask mask;
+        mask.exclude(Class(BaseObject));
+        mask.include(Class(LevelInfo));
+
+        // Iterate over all the found *.oxw files
         COUT(3) << "Loading LevelInfos..." << std::endl;
+        std::set<std::string> names;
         for (Ogre::StringVector::const_iterator it = levels->begin(); it != levels->end(); ++it)
         {
-            //TODO: Replace with tag?
+            // TODO: Replace with tag?
             if (it->find("old/") != 0)
             {
-                size_t pos = it->find(".oxw");
+                LevelInfoItem* info = NULL;
 
                 // Load the LevelInfo object from the level file.
-                bool infoExists = false;
                 XMLFile file = XMLFile(*it);
-                ClassTreeMask mask = ClassTreeMask();
-                mask.exclude(ClassIdentifier<BaseObject>::getIdentifier());
-                mask.include(ClassIdentifier<LevelInfo>::getIdentifier());
-                Loader::load(&file, mask, false);
-                // Iterate over all LevelInfos.
+                Loader::load(&file, mask, false, true);
+
+                // Find the LevelInfo object we've just loaded (if there was one)
                 for(ObjectList<LevelInfo>::iterator item = ObjectList<LevelInfo>::begin(); item != ObjectList<LevelInfo>::end(); ++item)
+                    if(item->getXMLFilename() == *it)
+                        info = item->copy();
+
+                // We don't need the loaded stuff anymore
+                Loader::unload(&file);
+
+                if(info == NULL) 
                 {
-                    LevelInfoItem* info = item->copy();
-                    if(info->getXMLFilename() == *it) // If the LevelInfo for this level exists we insert it into the list of available levels.
-                    {
-                        this->availableLevels_.insert(info);
-                        infoExists = true;
-                    }
+                    // Create a default LevelInfoItem object that merely contains the name
+                    std::string filenameWOExtension = it->substr(0, it->find(".oxw"));
+                    info = new LevelInfoItem(filenameWOExtension, *it);
                 }
-                Loader::unload(&file, mask);
-                if(!infoExists) // If the LevelInfo for this level doesn't exist, we create a new one and insert it into the list of available levels.
-                    this->availableLevels_.insert(new LevelInfoItem(it->substr(0, pos), *it));
+
+                // Warn about levels with the same name.
+                if(!names.insert(info->getName()).second)
+                    COUT(2) << "Warning: Multiple levels (" << info->getXMLFilename() << ") with name '" << info->getName() << "' found!" << std::endl;
+
+                // Warn about multiple items so that it gets fixed quickly
+                if(availableLevels_.find(info) != availableLevels_.end())
+                {
+                    COUT(2) << "Warning: Multiple levels (" << info->getXMLFilename() << ") with same name '" << info->getName() << "' and filename found! Exluding..." << std::endl;
+                    // Delete LevelInfoItem to avoid a dangling pointer
+                    delete info;
+                }
+                else
+                    this->availableLevels_.insert(info);
             }
         }
     }

Modified: code/trunk/src/orxonox/LevelManager.h
===================================================================
--- code/trunk/src/orxonox/LevelManager.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/LevelManager.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -111,7 +111,7 @@
 
             // Helpers to allow fast access to the availableLevels list.
             unsigned int nextIndex_; //! The next expected index to be accessed.
-            std::set<LevelInfoItem*, LevelInfoCompare>::iterator nextLevel_; //! The nex expected Level to be accessed.
+            std::set<LevelInfoItem*, LevelInfoCompare>::iterator nextLevel_; //! The next expected Level to be accessed.
 
             // config values
             std::string defaultLevelName_;

Modified: code/trunk/src/orxonox/controllers/HumanController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/HumanController.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/controllers/HumanController.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -60,6 +60,7 @@
     SetConsoleCommand("HumanController", "killBots",               &HumanController::killBots      ).addShortcut().defaultValues(0);
     SetConsoleCommand("HumanController", "cycleNavigationFocus",   &HumanController::cycleNavigationFocus).addShortcut();
     SetConsoleCommand("HumanController", "releaseNavigationFocus", &HumanController::releaseNavigationFocus).addShortcut();
+    SetConsoleCommand("HumanController", "myposition",             &HumanController::myposition    ).addShortcut();
 
     CreateUnloadableFactory(HumanController);
 
@@ -199,9 +200,22 @@
 
     void HumanController::toggleGodMode()
     {
-        HumanController::getLocalControllerSingleton()->setGodMode( !HumanController::getLocalControllerSingleton()->getGodMode() );
+        if (HumanController::localController_s)
+            HumanController::localController_s->setGodMode(!HumanController::localController_s->getGodMode());
     }
 
+    void HumanController::myposition()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+        {
+            const Vector3& position = HumanController::localController_s->controllableEntity_->getPosition();
+            const Quaternion& orientation = HumanController::localController_s->controllableEntity_->getOrientation();
+
+            COUT(0) << "position=\"" << position.x << ", " << position.y << ", " << position.z << "\" ";
+            COUT(0) << "orientation=\"" << orientation.w << ", " << orientation.x << ", " << orientation.y << ", " << orientation.z << "\"" << std::endl;
+        }
+    }
+
     void HumanController::addBots(unsigned int amount)
     {
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_ && HumanController::localController_s->controllableEntity_->getGametype())

Modified: code/trunk/src/orxonox/controllers/HumanController.h
===================================================================
--- code/trunk/src/orxonox/controllers/HumanController.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/controllers/HumanController.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -72,6 +72,7 @@
 
             static void suicide();
             static void toggleGodMode();
+            static void myposition();
 
             static void addBots(unsigned int amount);
             static void killBots(unsigned int amount = 0);

Modified: code/trunk/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/gamestates/GSLevel.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -45,6 +45,7 @@
 
 #include "LevelManager.h"
 #include "PlayerManager.h"
+#include "GSRoot.h"
 
 namespace orxonox
 {
@@ -54,7 +55,7 @@
     static const std::string __CC_changeGame_name = "changeGame";
 
     SetConsoleCommand(__CC_startMainMenu_name, &GSLevel::startMainMenu).deactivate();
-    SetConsoleCommand(__CC_changeGame_name, &GSLevel::changeGame).defaultValues(BLANKSTRING).deactivate();
+    SetConsoleCommand(__CC_changeGame_name, &GSLevel::changeGame).defaultValues("").deactivate();
 
     GSLevel::GSLevel(const GameStateInfo& info)
         : GameState(info)
@@ -155,9 +156,11 @@
         // call the loader
         COUT(0) << "Loading level..." << std::endl;
         startFile_ = new XMLFile(LevelManager::getInstance().getDefaultLevel());
-        Loader::open(startFile_);
+        bool loaded = Loader::open(startFile_);
 
         Core::getInstance().updateLastLevelTimestamp();
+        if(!loaded)
+            GSRoot::delayedStartMainMenu();
     }
 
     void GSLevel::unloadLevel()
@@ -201,7 +204,7 @@
     */
     /*static*/ void GSLevel::changeGame(const std::string& level)
     {
-        if(level != BLANKSTRING)
+        if(level != "")
             LevelManager::getInstance().setDefaultLevel(level);
 
         // HACK

Modified: code/trunk/src/orxonox/gamestates/GSMainMenu.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSMainMenu.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/gamestates/GSMainMenu.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -56,10 +56,10 @@
     static const std::string __CC_startDedicated_name       = "startDedicated";
     static const std::string __CC_setMainMenuSoundPath_name = "setMMSoundPath";
 
-    SetConsoleCommand(__CC_startStandalone_name,      &GSMainMenu::startStandalone).defaultValues(BLANKSTRING).deactivate();
-    SetConsoleCommand(__CC_startServer_name,          &GSMainMenu::startServer    ).defaultValues(BLANKSTRING).deactivate();
-    SetConsoleCommand(__CC_startClient_name,          &GSMainMenu::startClient    ).defaultValues(BLANKSTRING).deactivate();
-    SetConsoleCommand(__CC_startDedicated_name,       &GSMainMenu::startDedicated ).defaultValues(BLANKSTRING).deactivate();
+    SetConsoleCommand(__CC_startStandalone_name,      &GSMainMenu::startStandalone).defaultValues("").deactivate();
+    SetConsoleCommand(__CC_startServer_name,          &GSMainMenu::startServer    ).defaultValues("").deactivate();
+    SetConsoleCommand(__CC_startClient_name,          &GSMainMenu::startClient    ).defaultValues("").deactivate();
+    SetConsoleCommand(__CC_startDedicated_name,       &GSMainMenu::startDedicated ).defaultValues("").deactivate();
     SetConsoleCommand(__CC_setMainMenuSoundPath_name, &GSMainMenu::setMainMenuSoundPath).hide();
 
     GSMainMenu::GSMainMenu(const GameStateInfo& info)
@@ -95,10 +95,9 @@
     void GSMainMenu::activate()
     {
         // show main menu
+        GraphicsManager::getInstance().setCamera(this->camera_);
         GUIManager::getInstance().showGUI("MainMenu", true);
-        GUIManager::getInstance().setCamera(this->camera_);
         GUIManager::getInstance().setBackgroundImage("MainMenuBackground", "Background");
-        GraphicsManager::getInstance().setCamera(this->camera_);
 
         InputManager::getInstance().enterState("MainMenuHackery");
 
@@ -128,10 +127,9 @@
 
         InputManager::getInstance().leaveState("MainMenuHackery");
 
-        GUIManager::getInstance().setCamera(0);
+        GraphicsManager::getInstance().setCamera(0);
         GUIManager::getInstance().setBackgroundImage("");
         GUIManager::hideGUI("MainMenu");
-        GraphicsManager::getInstance().setCamera(0);
 
         ModifyConsoleCommand(__CC_startStandalone_name).deactivate();
         ModifyConsoleCommand(__CC_startServer_name    ).deactivate();
@@ -177,7 +175,7 @@
     */
     void GSMainMenu::startStandalone(const std::string& level)
     {
-        if(level != BLANKSTRING)
+        if(level != "")
             LevelManager::getInstance().setDefaultLevel(level);
 
         // HACK
@@ -193,7 +191,7 @@
     */
     void GSMainMenu::startServer(const std::string& level)
     {
-        if(level != BLANKSTRING)
+        if(level != "")
             LevelManager::getInstance().setDefaultLevel(level);
 
         // HACK
@@ -209,7 +207,7 @@
     */
     void GSMainMenu::startClient(const std::string& destination)
     {
-        if(destination != BLANKSTRING)
+        if(destination != "")
             Client::getInstance()->setDestination(destination, NETWORK_PORT);
 
         // HACK
@@ -225,7 +223,7 @@
     */
     void GSMainMenu::startDedicated(const std::string& level)
     {
-        if(level != BLANKSTRING)
+        if(level != "")
             LevelManager::getInstance().setDefaultLevel(level);
 
         // HACK

Modified: code/trunk/src/orxonox/gamestates/GSMainMenu.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSMainMenu.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/gamestates/GSMainMenu.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -52,10 +52,10 @@
         const std::string& getMainMenuSoundPath();
         void setMainMenuSoundPath(const std::string& path);
 
-        static void startStandalone(const std::string& level = BLANKSTRING); //!< Start a level in standalone mode.
-        static void startServer(const std::string& level = BLANKSTRING); //!< Start a level in server mode.
-        static void startClient(const std::string& destination = BLANKSTRING); //!< Connect to a game as client.
-        static void startDedicated(const std::string& level = BLANKSTRING); //!< Start a level in dedicated mode.
+        static void startStandalone(const std::string& level = ""); //!< Start a level in standalone mode.
+        static void startServer(const std::string& level = ""); //!< Start a level in server mode.
+        static void startClient(const std::string& destination = ""); //!< Connect to a game as client.
+        static void startDedicated(const std::string& level = ""); //!< Start a level in dedicated mode.
         static void startIOConsole();
 
     private:

Modified: code/trunk/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSRoot.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/gamestates/GSRoot.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -37,15 +37,21 @@
 #include "tools/Timer.h"
 #include "tools/interfaces/Tickable.h"
 
+#include "GSLevel.h"
+
 namespace orxonox
 {
     DeclareGameState(GSRoot, "root", false, false);
 
     static const std::string __CC_setTimeFactor_name = "setTimeFactor";
+    static const std::string __CC_setPause_name = "setPause";
     static const std::string __CC_pause_name = "pause";
 
+    /*static*/ bool GSRoot::startMainMenu_s = false;
+
     SetConsoleCommand("printObjects", &GSRoot::printObjects).hide();
     SetConsoleCommand(__CC_setTimeFactor_name, &GSRoot::setTimeFactor).accessLevel(AccessLevel::Master).defaultValues(1.0);
+    SetConsoleCommand(__CC_setPause_name,      &GSRoot::setPause     ).accessLevel(AccessLevel::Master).hide();
     SetConsoleCommand(__CC_pause_name,         &GSRoot::pause        ).accessLevel(AccessLevel::Master);
 
     registerStaticNetworkFunction(&TimeFactorListener::setTimeFactor);
@@ -82,17 +88,25 @@
         TimeFactorListener::setTimeFactor(1.0f);
 
         ModifyConsoleCommand(__CC_setTimeFactor_name).setObject(this);
+        ModifyConsoleCommand(__CC_setPause_name).setObject(this);
         ModifyConsoleCommand(__CC_pause_name).setObject(this);
     }
 
     void GSRoot::deactivate()
     {
         ModifyConsoleCommand(__CC_setTimeFactor_name).setObject(0);
+        ModifyConsoleCommand(__CC_setPause_name).setObject(0);
         ModifyConsoleCommand(__CC_pause_name).setObject(0);
     }
 
     void GSRoot::update(const Clock& time)
     {
+        if(startMainMenu_s)
+        {
+            delayedStartMainMenu();
+            startMainMenu_s = false;
+        }
+
         for (ObjectList<Timer>::iterator it = ObjectList<Timer>::begin(); it; )
         {
             Timer* object = *it;
@@ -156,9 +170,27 @@
         }
     }
 
+    void GSRoot::setPause(bool pause)
+    {
+        if (GameMode::isMaster())
+        {
+            if (pause != this->bPaused_)
+                this->pause();
+        }
+    }
+
     void GSRoot::changedTimeFactor(float factor_new, float factor_old)
     {
         if (!GameMode::isStandalone())
             callStaticNetworkFunction(&TimeFactorListener::setTimeFactor, CLIENTID_UNKNOWN, factor_new);
     }
+
+    /*static*/ void GSRoot::delayedStartMainMenu(void)
+    {
+        if(!startMainMenu_s)
+            startMainMenu_s = true;
+        else
+            GSLevel::startMainMenu();
+    }
+
 }

Modified: code/trunk/src/orxonox/gamestates/GSRoot.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSRoot.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/gamestates/GSRoot.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -50,14 +50,18 @@
         // this has to be public because proteced triggers a bug in msvc
         // when taking the function address.
         void setTimeFactor(float factor);
+        void setPause(bool pause);
         void pause();
 
+        static void delayedStartMainMenu(void);
+
     protected:
         virtual void changedTimeFactor(float factor_new, float factor_old);
 
     private:
         bool                  bPaused_;
         float                 timeFactorPauseBackup_;
+        static bool           startMainMenu_s;
     };
 }
 

Modified: code/trunk/src/orxonox/gametypes/Gametype.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/Gametype.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/gametypes/Gametype.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -29,6 +29,7 @@
 #include "Gametype.h"
 
 #include "util/Math.h"
+#include "core/Core.h"
 #include "core/CoreIncludes.h"
 #include "core/ConfigValueIncludes.h"
 #include "core/GameMode.h"
@@ -385,7 +386,11 @@
                     }
                     if (allplayersready && hashumanplayers)
                     {
-                        this->gtinfo_->startCountdown_ = this->initialStartCountdown_;
+                        // If in developer's mode, there is no start countdown.
+                        if(Core::getInstance().inDevMode())
+                            this->gtinfo_->startCountdown_ = 0;
+                        else
+                            this->gtinfo_->startCountdown_ = this->initialStartCountdown_;
                         this->gtinfo_->bStartCountdownRunning_ = true;
                     }
                 }

Modified: code/trunk/src/orxonox/graphics/Camera.cc
===================================================================
--- code/trunk/src/orxonox/graphics/Camera.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/graphics/Camera.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -68,12 +68,13 @@
 
         this->bHasFocus_ = false;
         this->bDrag_ = false;
-        this->nearClipDistance_ = 1;
         this->lastDtLagged_ = false;
 
         this->setSyncMode(0x0);
 
         this->setConfigValues();
+
+        this->configvaluecallback_changedFovAndAspectRatio();
         this->configvaluecallback_changedNearClipDistance();
     }
 
@@ -81,8 +82,6 @@
     {
         if (this->isInitialized())
         {
-            if (GUIManager::getInstance().getCamera() == this->camera_)
-                GUIManager::getInstance().setCamera(NULL);
             this->releaseFocus();
 
             this->cameraNode_->detachAllObjects();
@@ -98,14 +97,44 @@
 
     void Camera::setConfigValues()
     {
-        SetConfigValue(nearClipDistance_, 1.0f).callback(this, &Camera::configvaluecallback_changedNearClipDistance);
+        SetConfigValue(fov_, 80.0f)
+            .description("Horizontal field of view in degrees")
+            .callback(this, &Camera::configvaluecallback_changedFovAndAspectRatio);
+        SetConfigValue(aspectRatio_, 1.0f)
+            .description("Aspect ratio of pixels (width / height)")
+            .callback(this, &Camera::configvaluecallback_changedFovAndAspectRatio);
+        SetConfigValue(nearClipDistance_, 1.0f)
+            .description("Distance from the camera where close objects will be clipped")
+            .callback(this, &Camera::configvaluecallback_changedNearClipDistance);
     }
 
+    /**
+        @brief Update FOV and the aspect ratio of the camera after the config values or the window's size have changed.
+    */
+    void Camera::configvaluecallback_changedFovAndAspectRatio()
+    {
+        // the aspect ratio of the window (width / height) has to be multiplied with the pixels aspect ratio (this->aspectRatio_)
+        float aspectRatio = this->aspectRatio_ * this->getWindowWidth() / this->getWindowHeight();
+        this->camera_->setAspectRatio(aspectRatio);
+
+        // Since we use horizontal FOV, we have to calculate FOVy by dividing by the aspect ratio and using some tangents
+        Radian fovy(2 * atan(tan(Degree(this->fov_).valueRadians() / 2) / aspectRatio));
+        this->camera_->setFOVy(fovy);
+    }
+
     void Camera::configvaluecallback_changedNearClipDistance()
     {
         this->camera_->setNearClipDistance(this->nearClipDistance_);
     }
 
+    /**
+        @brief Inherited from WindowEventListener.
+    */
+    void Camera::windowResized(unsigned int newWidth, unsigned int newHeight)
+    {
+        this->configvaluecallback_changedFovAndAspectRatio();
+    }
+
     void Camera::tick(float dt)
     {
         SUPER(Camera, tick, dt);

Modified: code/trunk/src/orxonox/graphics/Camera.h
===================================================================
--- code/trunk/src/orxonox/graphics/Camera.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/graphics/Camera.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -32,13 +32,14 @@
 #include "OrxonoxPrereqs.h"
 
 #include "util/OgreForwardRefs.h"
+#include "core/WindowEventListener.h"
 #include "tools/interfaces/Tickable.h"
 #include "tools/interfaces/TimeFactorListener.h"
 #include "worldentities/StaticEntity.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport Camera : public StaticEntity, public Tickable, public TimeFactorListener
+    class _OrxonoxExport Camera : public StaticEntity, public Tickable, public TimeFactorListener, public WindowEventListener
     {
         friend class CameraManager;
 
@@ -65,14 +66,20 @@
         private:
             void removeFocus();
             void setFocus();
+
+            void configvaluecallback_changedFovAndAspectRatio();
             void configvaluecallback_changedNearClipDistance();
 
+            void windowResized(unsigned int newWidth, unsigned int newHeight);
+
             Ogre::Camera*    camera_;
             Ogre::SceneNode* cameraNode_;
             float            nearClipDistance_;
             bool             bHasFocus_;
             bool             bDrag_;
             bool             lastDtLagged_;
+            float            fov_;
+            float            aspectRatio_;
     };
 }
 

Modified: code/trunk/src/orxonox/graphics/GlobalShader.cc
===================================================================
--- code/trunk/src/orxonox/graphics/GlobalShader.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/graphics/GlobalShader.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -60,13 +60,13 @@
     {
         SUPER(GlobalShader, XMLPort, xmlelement, mode);
 
-        XMLPortParamExtern(GlobalShader, Shader, &this->shader_, "compositor", setCompositor, getCompositor, xmlelement, mode);
+        XMLPortParamExtern(GlobalShader, Shader, &this->shader_, "compositor", setCompositorName, getCompositorName, xmlelement, mode);
     }
 
     void GlobalShader::registerVariables()
     {
         registerVariable(this->bVisible_,                                         VariableDirection::ToClient, new NetworkCallback<GlobalShader>(this, &GlobalShader::changedVisibility));
-        registerVariable(const_cast<std::string&>(this->shader_.getCompositor()), VariableDirection::ToClient, new NetworkCallback<Shader>(&this->shader_, &Shader::changedCompositor));
+        registerVariable(const_cast<std::string&>(this->shader_.getCompositorName()), VariableDirection::ToClient, new NetworkCallback<Shader>(&this->shader_, &Shader::changedCompositorName));
     }
 
     void GlobalShader::changedVisibility()

Modified: code/trunk/src/orxonox/graphics/GlobalShader.h
===================================================================
--- code/trunk/src/orxonox/graphics/GlobalShader.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/graphics/GlobalShader.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -52,7 +52,6 @@
 
         private:
             void registerVariables();
-            void changedCompositor();
 
             Shader shader_;
     };

Modified: code/trunk/src/orxonox/graphics/Model.cc
===================================================================
--- code/trunk/src/orxonox/graphics/Model.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/graphics/Model.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -59,7 +59,7 @@
 
     void Model::setConfigValues()
     {
-        SetConfigValueExternal(bGlobalEnableLod_, "GraphicsSettings", "enableModelLoD", true)
+        SetConfigValueExternal(bGlobalEnableLod_, "GraphicsSettings", "enableMeshLoD", true)
             .description("Enable level of detail for models");
     }
 

Modified: code/trunk/src/orxonox/items/Engine.cc
===================================================================
--- code/trunk/src/orxonox/items/Engine.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/items/Engine.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -101,7 +101,11 @@
 
     void Engine::setConfigValues()
     {
-        SetConfigValue(blurStrength_, 3.0f);
+        SetConfigValueExternal(bEnableMotionBlur_, "GraphicsSettings", "enableMotionBlur", true)
+            .description("Enable or disable the motion blur effect when moving very fast")
+            .callback(this, &Engine::changedEnableMotionBlur);
+        SetConfigValueExternal(blurStrength_, "GraphicsSettings", "blurStrength", 3.0f)
+            .description("Defines the strength of the motion blur effect");
     }
 
     void Engine::registerVariables()
@@ -203,14 +207,19 @@
             this->ship_->setBoost(false);
         this->ship_->setSteeringDirection(Vector3::ZERO);
 
-        if (!this->boostBlur_ && this->ship_->hasLocalController() && this->ship_->hasHumanController())
+        if (this->bEnableMotionBlur_ && !this->boostBlur_ && this->ship_->hasLocalController() && this->ship_->hasHumanController())
         {
             this->boostBlur_ = new Shader(this->ship_->getScene()->getSceneManager());
-            this->boostBlur_->setCompositor("Radial Blur");
+            this->boostBlur_->setCompositorName("Radial Blur");
         }
 
         if (this->boostBlur_ && this->maxSpeedFront_ != 0 && this->boostFactor_ != 1)
-            this->boostBlur_->setParameter("Ogre/Compositor/Radial_Blur", 0, 0, "sampleStrength", this->blurStrength_ * clamp((-velocity.z - this->maxSpeedFront_) / ((this->boostFactor_ - 1) * this->maxSpeedFront_), 0.0f, 1.0f));
+        {
+            float blur = this->blurStrength_ * clamp((-velocity.z - this->maxSpeedFront_) / ((this->boostFactor_ - 1) * this->maxSpeedFront_), 0.0f, 1.0f);
+
+            this->boostBlur_->setVisible(blur > 0);
+            this->boostBlur_->setParameter(0, 0, "sampleStrength", blur);
+        }
     }
 
     void Engine::changedActivity()
@@ -256,4 +265,13 @@
     {
         return this->ship_->getWorldPosition();
     }
+
+    void Engine::changedEnableMotionBlur()
+    {
+        if (!this->bEnableMotionBlur_)
+        {
+            this->boostBlur_->destroy();
+            this->boostBlur_ = 0;
+        }
+    }
 }

Modified: code/trunk/src/orxonox/items/Engine.h
===================================================================
--- code/trunk/src/orxonox/items/Engine.h	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/items/Engine.h	2011-03-15 20:47:11 UTC (rev 8079)
@@ -126,6 +126,7 @@
         private:
             void registerVariables();
             void networkcallback_shipID();
+            void changedEnableMotionBlur();
 
             SpaceShip* ship_;
             unsigned int shipID_;
@@ -149,6 +150,7 @@
 
             Shader* boostBlur_;
             float blurStrength_;
+            bool bEnableMotionBlur_;
     };
 }
 

Modified: code/trunk/src/orxonox/overlays/InGameConsole.cc
===================================================================
--- code/trunk/src/orxonox/overlays/InGameConsole.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/overlays/InGameConsole.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -59,8 +59,8 @@
     const int LINES = 30;
     const float CHAR_WIDTH = 7.45f; // fix this please - determine the char-width dynamically
 
-    SetConsoleCommand("InGameConsole", "openConsole", &InGameConsole::openConsole).addShortcut();
-    SetConsoleCommand("InGameConsole", "closeConsole", &InGameConsole::closeConsole).addShortcut();
+    SetConsoleCommand("InGameConsole", "openConsole", &InGameConsole::openConsole);
+    SetConsoleCommand("InGameConsole", "closeConsole", &InGameConsole::closeConsole);
 
     ManageScopedSingleton(InGameConsole, ScopeID::Graphics, false);
 

Modified: code/trunk/src/orxonox/sound/AmbientSound.cc
===================================================================
--- code/trunk/src/orxonox/sound/AmbientSound.cc	2011-03-15 20:09:58 UTC (rev 8078)
+++ code/trunk/src/orxonox/sound/AmbientSound.cc	2011-03-15 20:47:11 UTC (rev 8079)
@@ -28,6 +28,7 @@
 
 #include "AmbientSound.h"
 
+#include "core/CoreIncludes.h"
 #include "core/GameMode.h"
 #include "core/Resource.h"
 #include "SoundManager.h"
@@ -37,6 +38,8 @@
     AmbientSound::AmbientSound()
         : bPlayOnLoad_(false)
     {
+        RegisterObject(AmbientSound);
+
         // Ambient sounds always fade in
         this->setVolume(0);
     }




More information about the Orxonox-commit mailing list