Browse Source

Makes the graphics menu in the stock UI mostly functional again
Adds sanity check to editing of gameasset script action in asset browser
Updates module template file
Updates visualizers
Fixes checking of popup menu items
Adds stub for TerrainMaterialAsset

Areloch 6 years ago
parent
commit
d720eb8ccd
100 changed files with 9376 additions and 37 deletions
  1. 316 0
      Engine/source/T3D/assets/TerrainMaterialAsset.cpp
  2. 108 0
      Engine/source/T3D/assets/TerrainMaterialAsset.h
  3. 6 0
      Engine/source/gui/editor/guiPopupMenuCtrl.cpp
  4. 2 2
      Templates/BaseGame/game/core/clientServer/scripts/client/connectionToServer.cs
  5. 3 0
      Templates/BaseGame/game/core/clientServer/scripts/server/levelInfo.cs
  6. 1 0
      Templates/BaseGame/game/core/clientServer/scripts/server/server.cs
  7. 143 0
      Templates/BaseGame/game/core/gameObjects/datablocks/defaultDatablocks.cs
  8. BIN
      Templates/BaseGame/game/core/gameObjects/images/camera.png
  9. BIN
      Templates/BaseGame/game/core/gameObjects/images/defaultParticle.png
  10. BIN
      Templates/BaseGame/game/core/gameObjects/images/defaultRoadTextureOther.png
  11. BIN
      Templates/BaseGame/game/core/gameObjects/images/defaultRoadTextureTop.png
  12. BIN
      Templates/BaseGame/game/core/gameObjects/images/defaultpath.png
  13. BIN
      Templates/BaseGame/game/core/gameObjects/images/defaultpath_normal.png
  14. BIN
      Templates/BaseGame/game/core/gameObjects/images/green.jpg
  15. BIN
      Templates/BaseGame/game/core/gameObjects/images/ribTex.png
  16. 78 0
      Templates/BaseGame/game/core/gameObjects/materials/materials.cs
  17. BIN
      Templates/BaseGame/game/core/gameObjects/shapes/camera.dts
  18. 112 0
      Templates/BaseGame/game/core/gameObjects/shapes/materials.cs
  19. BIN
      Templates/BaseGame/game/core/gameObjects/shapes/noshape.dts
  20. BIN
      Templates/BaseGame/game/core/gameObjects/shapes/octahedron.dts
  21. BIN
      Templates/BaseGame/game/core/gameObjects/shapes/simplecone.dts
  22. BIN
      Templates/BaseGame/game/core/gameObjects/shapes/unit_capsule.dts
  23. BIN
      Templates/BaseGame/game/core/gameObjects/shapes/unit_cube.dts
  24. BIN
      Templates/BaseGame/game/core/gameObjects/shapes/unit_sphere.dts
  25. 105 0
      Templates/BaseGame/game/data/ExampleModule/ExampleModule.cs
  26. 25 0
      Templates/BaseGame/game/data/ExampleModule/ExampleModule.module
  27. 7 0
      Templates/BaseGame/game/data/ExampleModule/GUIs/ExampleGUI.asset.taml
  28. 9 0
      Templates/BaseGame/game/data/ExampleModule/GUIs/ExampleGUI.cs
  29. 7 0
      Templates/BaseGame/game/data/ExampleModule/GUIs/ExampleGUI.gui
  30. 9 0
      Templates/BaseGame/game/data/ExampleModule/components/ExampleComponent.asset.taml
  31. 26 0
      Templates/BaseGame/game/data/ExampleModule/components/ExampleComponent.cs
  32. 0 0
      Templates/BaseGame/game/data/ExampleModule/datablocks/ExampleDatablock.cs
  33. 8 0
      Templates/BaseGame/game/data/ExampleModule/levels/ExampleLevel.asset.taml
  34. 99 0
      Templates/BaseGame/game/data/ExampleModule/levels/ExampleLevel.mis
  35. 6 0
      Templates/BaseGame/game/data/ExampleModule/postFXs/ExamplePostEffect.asset.taml
  36. 96 0
      Templates/BaseGame/game/data/ExampleModule/postFXs/ExamplePostEffect.cs
  37. 6 0
      Templates/BaseGame/game/data/ExampleModule/scripts/ExampleGamemodeScript.asset.taml
  38. 128 0
      Templates/BaseGame/game/data/ExampleModule/scripts/ExampleGamemodeScript.cs
  39. 73 0
      Templates/BaseGame/game/data/ExampleModule/scripts/default.keybinds.cs
  40. 204 0
      Templates/BaseGame/game/data/ExampleModule/scripts/inputCommands.cs
  41. 7 0
      Templates/BaseGame/game/data/ExampleModule/source/ExampleCppObject.asset.taml
  42. 0 0
      Templates/BaseGame/game/data/ExampleModule/source/ExampleCppObject.cpp
  43. 0 0
      Templates/BaseGame/game/data/ExampleModule/source/ExampleCppObject.h
  44. 18 0
      Templates/BaseGame/game/data/ExampleModule/source/ExampleModule.cpp
  45. 122 0
      Templates/BaseGame/game/data/gameUI/GUIs/playGui.cs
  46. 50 0
      Templates/BaseGame/game/data/gameUI/GUIs/playGui.gui
  47. 14 0
      Templates/BaseGame/game/data/gameUI/gameUI.cs
  48. 15 0
      Templates/BaseGame/game/data/gameUI/gameUI.module
  49. 55 35
      Templates/BaseGame/game/data/ui/UI.cs
  50. 34 0
      Templates/BaseGame/game/data/ui/datablocks/guiSounds.cs
  51. 293 0
      Templates/BaseGame/game/data/ui/guis/FileDialog.gui
  52. 159 0
      Templates/BaseGame/game/data/ui/guis/IODropdownDlg.ed.gui
  53. 230 0
      Templates/BaseGame/game/data/ui/guis/RecordingsDlg.gui
  54. 374 0
      Templates/BaseGame/game/data/ui/guis/chooseLevelDlg.cs
  55. 272 0
      Templates/BaseGame/game/data/ui/guis/chooseLevelDlg.gui
  56. 102 0
      Templates/BaseGame/game/data/ui/guis/controlsMenuSetting.taml
  57. 123 0
      Templates/BaseGame/game/data/ui/guis/graphicsMenuSettingsCtrl.taml
  58. 142 0
      Templates/BaseGame/game/data/ui/guis/graphicsMenuSettingsSlider.taml
  59. 244 0
      Templates/BaseGame/game/data/ui/guis/guiMusicPlayer.cs
  60. 192 0
      Templates/BaseGame/game/data/ui/guis/guiMusicPlayer.gui
  61. 143 0
      Templates/BaseGame/game/data/ui/guis/joinServerMenu.cs
  62. 455 0
      Templates/BaseGame/game/data/ui/guis/joinServerMenu.gui
  63. 102 0
      Templates/BaseGame/game/data/ui/guis/loadingGui.gui
  64. 41 0
      Templates/BaseGame/game/data/ui/guis/mainMenu.cs
  65. 234 0
      Templates/BaseGame/game/data/ui/guis/mainMenu.gui
  66. 60 0
      Templates/BaseGame/game/data/ui/guis/messageBoxOK.gui
  67. 75 0
      Templates/BaseGame/game/data/ui/guis/messageBoxYesNo.gui
  68. 557 0
      Templates/BaseGame/game/data/ui/guis/netGraphGui.gui
  69. 1417 0
      Templates/BaseGame/game/data/ui/guis/optionsDlg.gui
  70. 665 0
      Templates/BaseGame/game/data/ui/guis/optionsMenu.cs
  71. 247 0
      Templates/BaseGame/game/data/ui/guis/optionsMenu.gui
  72. 30 0
      Templates/BaseGame/game/data/ui/guis/pauseMenu.cs
  73. 153 0
      Templates/BaseGame/game/data/ui/guis/pauseMenu.gui
  74. 367 0
      Templates/BaseGame/game/data/ui/guis/profiler.cs
  75. 324 0
      Templates/BaseGame/game/data/ui/guis/profiler.gui
  76. 125 0
      Templates/BaseGame/game/data/ui/guis/remapConfirmDlg.gui
  77. 122 0
      Templates/BaseGame/game/data/ui/guis/remapDlg.gui
  78. 157 0
      Templates/BaseGame/game/data/ui/guis/startupGui.cs
  79. 79 0
      Templates/BaseGame/game/data/ui/guis/startupGui.gui
  80. BIN
      Templates/BaseGame/game/data/ui/images/BackgroundImage.png
  81. BIN
      Templates/BaseGame/game/data/ui/images/ScreenBrightness_Dark.png
  82. BIN
      Templates/BaseGame/game/data/ui/images/ScreenBrightness_Light.png
  83. BIN
      Templates/BaseGame/game/data/ui/images/Torque-3D-logo-shortcut.png
  84. BIN
      Templates/BaseGame/game/data/ui/images/Torque-3D-logo-w.png
  85. BIN
      Templates/BaseGame/game/data/ui/images/Torque-3D-logo.png
  86. BIN
      Templates/BaseGame/game/data/ui/images/Torque-3D-logo_alt.png
  87. BIN
      Templates/BaseGame/game/data/ui/images/background-dark.png
  88. BIN
      Templates/BaseGame/game/data/ui/images/background.png
  89. BIN
      Templates/BaseGame/game/data/ui/images/buttontab.png
  90. BIN
      Templates/BaseGame/game/data/ui/images/chatHudBorderArray.png
  91. BIN
      Templates/BaseGame/game/data/ui/images/checkbox.png
  92. BIN
      Templates/BaseGame/game/data/ui/images/clear-btn_d.png
  93. BIN
      Templates/BaseGame/game/data/ui/images/clear-btn_h.png
  94. BIN
      Templates/BaseGame/game/data/ui/images/clear-btn_n.png
  95. BIN
      Templates/BaseGame/game/data/ui/images/collapse-toolbar_d.png
  96. BIN
      Templates/BaseGame/game/data/ui/images/collapse-toolbar_h.png
  97. BIN
      Templates/BaseGame/game/data/ui/images/collapse-toolbar_n.png
  98. BIN
      Templates/BaseGame/game/data/ui/images/defaultCursor.png
  99. BIN
      Templates/BaseGame/game/data/ui/images/dropDown.png
  100. BIN
      Templates/BaseGame/game/data/ui/images/dropdown-button-arrow.png

+ 316 - 0
Engine/source/T3D/assets/TerrainMaterialAsset.cpp

@@ -0,0 +1,316 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef TERRAINMATERIALASSET_H
+#include "TerrainMaterialAsset.h"
+#endif
+
+#ifndef _ASSET_MANAGER_H_
+#include "assets/assetManager.h"
+#endif
+
+#ifndef _CONSOLETYPES_H_
+#include "console/consoleTypes.h"
+#endif
+
+#ifndef _TAML_
+#include "persistence/taml/taml.h"
+#endif
+
+#ifndef _ASSET_PTR_H_
+#include "assets/assetPtr.h"
+#endif
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_CONOBJECT(TerrainMaterialAsset);
+
+ConsoleType(TerrainMaterialAssetPtr, TypeTerrainMaterialAssetPtr, TerrainMaterialAsset, ASSET_ID_FIELD_PREFIX)
+
+//-----------------------------------------------------------------------------
+
+ConsoleGetType(TypeTerrainMaterialAssetPtr)
+{
+   // Fetch asset Id.
+   return (*((AssetPtr<TerrainMaterialAsset>*)dptr)).getAssetId();
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleSetType(TypeTerrainMaterialAssetPtr)
+{
+   // Was a single argument specified?
+   if (argc == 1)
+   {
+      // Yes, so fetch field value.
+      const char* pFieldValue = argv[0];
+
+      // Fetch asset pointer.
+      AssetPtr<TerrainMaterialAsset>* pAssetPtr = dynamic_cast<AssetPtr<TerrainMaterialAsset>*>((AssetPtrBase*)(dptr));
+
+      // Is the asset pointer the correct type?
+      if (pAssetPtr == NULL)
+      {
+         // No, so fail.
+         //Con::warnf("(TypeMaterialAssetPtr) - Failed to set asset Id '%d'.", pFieldValue);
+         return;
+      }
+
+      // Set asset.
+      pAssetPtr->setAssetId(pFieldValue);
+
+      return;
+   }
+
+   // Warn.
+   Con::warnf("(TypeTerrainMaterialAssetPtr) - Cannot set multiple args to a single asset.");
+}
+
+//-----------------------------------------------------------------------------
+
+TerrainMaterialAsset::TerrainMaterialAsset()
+{
+   mScriptFile = StringTable->EmptyString();
+   mMatDefinitionName = StringTable->EmptyString();
+}
+
+//-----------------------------------------------------------------------------
+
+TerrainMaterialAsset::~TerrainMaterialAsset()
+{
+}
+
+//-----------------------------------------------------------------------------
+
+void TerrainMaterialAsset::initPersistFields()
+{
+   // Call parent.
+   Parent::initPersistFields();
+
+   //addField("shaderGraph", TypeRealString, Offset(mShaderGraphFile, TerrainMaterialAsset), "");
+   addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, TerrainMaterialAsset),
+      &setScriptFile, &getScriptFile, "Path to the file containing the material definition.");
+
+   addField("materialDefinitionName", TypeString, Offset(mMatDefinitionName, TerrainMaterialAsset), "Name of the material definition this asset is for.");
+}
+
+void TerrainMaterialAsset::initializeAsset()
+{
+   // Call parent.
+   Parent::initializeAsset();
+
+   compileShader();
+
+   if (!Platform::isFullPath(mScriptFile))
+      mScriptFile = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptFile;
+
+   if (Platform::isFile(mScriptFile))
+      Con::executeFile(mScriptFile, false, false);
+}
+
+void TerrainMaterialAsset::onAssetRefresh()
+{
+   mScriptFile = expandAssetFilePath(mScriptFile);
+
+   if (Platform::isFile(mScriptFile))
+      Con::executeFile(mScriptFile, false, false);
+
+   if (mMatDefinitionName != StringTable->EmptyString())
+   {
+      TerrainMaterial* matDef;
+      if (!Sim::findObject(mMatDefinitionName, matDef))
+      {
+         Con::errorf("TerrainMaterialAsset: Unable to find the Material %s", mMatDefinitionName);
+         return;
+      }
+
+      //matDef->reload();
+   }
+}
+
+void TerrainMaterialAsset::setScriptFile(const char* pScriptFile)
+{
+   // Sanity!
+   AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
+
+   // Fetch image file.
+   pScriptFile = StringTable->insert(pScriptFile);
+
+   // Update.
+   mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
+
+   // Refresh the asset.
+   refreshAsset();
+}
+
+//------------------------------------------------------------------------------
+
+void TerrainMaterialAsset::compileShader()
+{
+}
+
+void TerrainMaterialAsset::copyTo(SimObject* object)
+{
+   // Call to parent.
+   Parent::copyTo(object);
+}
+
+DefineEngineMethod(TerrainMaterialAsset, compileShader, void, (), , "Compiles the material's generated shader, if any. Not yet implemented\n")
+{
+   object->compileShader();
+}
+
+//-----------------------------------------------------------------------------
+// GuiInspectorTypeAssetId
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetPtr);
+
+ConsoleDocClass(GuiInspectorTypeTerrainMaterialAssetPtr,
+   "@brief Inspector field type for Material Asset Objects\n\n"
+   "Editor use only.\n\n"
+   "@internal"
+);
+
+void GuiInspectorTypeTerrainMaterialAssetPtr::consoleInit()
+{
+   Parent::consoleInit();
+
+   ConsoleBaseType::getType(TypeTerrainMaterialAssetPtr)->setInspectorFieldType("GuiInspectorTypeTerrainMaterialAssetPtr");
+}
+
+GuiControl* GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl()
+{
+   // Create base filename edit controls
+   mUseHeightOverride = true;
+   mHeightOverride = 100;
+
+   mMatEdContainer = new GuiControl();
+   mMatEdContainer->registerObject();
+
+   addObject(mMatEdContainer);
+
+   // Create "Open in ShapeEditor" button
+   mMatPreviewButton = new GuiBitmapButtonCtrl();
+
+   const char* matAssetId = getData();
+
+   TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset< TerrainMaterialAsset>(matAssetId);
+
+   TerrainMaterial* materialDef = nullptr;
+
+   char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
+
+   /*if (!Sim::findObject(matAsset->getMaterialDefinitionName(), materialDef))
+   {
+      Con::errorf("GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl() - unable to find material in asset");
+   }
+   else
+   {
+      mMatPreviewButton->setBitmap(materialDef->mDiffuseMapFilename[0]);
+   }*/
+
+   mMatPreviewButton->setPosition(0, 0);
+   mMatPreviewButton->setExtent(100,100);
+
+   // Change filespec
+   char szBuffer[512];
+   dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"TerrainMaterialAsset\", \"AssetBrowser.changeAsset\", %d, %s);",
+      mInspector->getComponentGroupTargetId(), mCaption);
+   mMatPreviewButton->setField("Command", szBuffer);
+
+   mMatPreviewButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
+   mMatPreviewButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
+   mMatPreviewButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
+
+   StringBuilder strbld;
+   strbld.append(matAsset->getMaterialDefinitionName());
+   strbld.append("\n");
+   strbld.append("Open this file in the Material Editor");
+
+   mMatPreviewButton->setDataField(StringTable->insert("tooltip"), NULL, strbld.data());
+
+   _registerEditControl(mMatPreviewButton);
+   //mMatPreviewButton->registerObject();
+   mMatEdContainer->addObject(mMatPreviewButton);
+
+   mMatAssetIdTxt = new GuiTextEditCtrl();
+   mMatAssetIdTxt->registerObject();
+   mMatAssetIdTxt->setActive(false);
+
+   mMatAssetIdTxt->setText(matAssetId);
+
+   mMatAssetIdTxt->setBounds(100, 0, 150, 18);
+   mMatEdContainer->addObject(mMatAssetIdTxt);
+
+   return mMatEdContainer;
+}
+
+bool GuiInspectorTypeTerrainMaterialAssetPtr::updateRects()
+{
+   S32 dividerPos, dividerMargin;
+   mInspector->getDivider(dividerPos, dividerMargin);
+   Point2I fieldExtent = getExtent();
+   Point2I fieldPos = getPosition();
+
+   mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y);
+   mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y);
+
+   bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
+
+   if (mMatEdContainer != nullptr)
+   {
+      mMatPreviewButton->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
+   }
+
+   if (mMatPreviewButton != nullptr)
+   {
+      mMatPreviewButton->resize(Point2I::Zero, Point2I(100, 100));
+   }
+
+   if (mMatAssetIdTxt != nullptr)
+   {
+      mMatAssetIdTxt->resize(Point2I(100, 0), Point2I(mEditCtrlRect.extent.x - 100, 18));
+   }
+
+   return resized;
+}
+
+void GuiInspectorTypeTerrainMaterialAssetPtr::setMaterialAsset(String assetId)
+{
+   mTargetObject->setDataField(mCaption, "", assetId);
+
+   //force a refresh
+   SimObject* obj = mInspector->getInspectObject();
+   mInspector->inspectObject(obj);
+}
+
+DefineEngineMethod(GuiInspectorTypeTerrainMaterialAssetPtr, setMaterialAsset, void, (String assetId), (""),
+   "Gets a particular shape animation asset for this shape.\n"
+   "@param animation asset index.\n"
+   "@return Shape Animation Asset.\n")
+{
+   if (assetId == String::EmptyString)
+      return;
+
+   return object->setMaterialAsset(assetId);
+}

+ 108 - 0
Engine/source/T3D/assets/TerrainMaterialAsset.h

@@ -0,0 +1,108 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+#ifndef TERRAINMATERIALASSET_H
+#define TERRAINMATERIALASSET_H
+
+#ifndef _ASSET_BASE_H_
+#include "assets/assetBase.h"
+#endif
+
+#ifndef _ASSET_DEFINITION_H_
+#include "assets/assetDefinition.h"
+#endif
+
+#ifndef _STRINGUNIT_H_
+#include "string/stringUnit.h"
+#endif
+
+#ifndef _ASSET_FIELD_TYPES_H_
+#include "assets/assetFieldTypes.h"
+#endif
+
+#ifndef _GFXDEVICE_H_
+#include "gfx/gfxDevice.h"
+#endif
+
+#ifndef _GUI_INSPECTOR_TYPES_H_
+#include "gui/editor/guiInspectorTypes.h"
+#endif
+
+#include "terrain/terrMaterial.h"
+
+//-----------------------------------------------------------------------------
+class TerrainMaterialAsset : public AssetBase
+{
+   typedef AssetBase Parent;
+
+   StringTableEntry        mScriptFile;
+   StringTableEntry        mMatDefinitionName;
+
+public:
+   TerrainMaterialAsset();
+   virtual ~TerrainMaterialAsset();
+
+   /// Engine.
+   static void initPersistFields();
+   virtual void copyTo(SimObject* object);
+
+   void compileShader();
+
+   StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; }
+
+   void                    setScriptFile(const char* pScriptFile);
+   inline StringTableEntry getScriptFile(void) const { return mScriptFile; };
+
+   /// Declare Console Object.
+   DECLARE_CONOBJECT(TerrainMaterialAsset);
+
+protected:
+   virtual void initializeAsset();
+   virtual void onAssetRefresh(void);
+
+   static bool setScriptFile(void *obj, const char *index, const char *data) { static_cast<TerrainMaterialAsset*>(obj)->setScriptFile(data); return false; }
+   static const char* getScriptFile(void* obj, const char* data) { return static_cast<TerrainMaterialAsset*>(obj)->getScriptFile(); }
+};
+
+DefineConsoleType(TypeTerrainMaterialAssetPtr, TerrainMaterialAsset)
+
+//-----------------------------------------------------------------------------
+// TypeAssetId GuiInspectorField Class
+//-----------------------------------------------------------------------------
+class GuiInspectorTypeTerrainMaterialAssetPtr : public GuiInspectorField
+{
+   typedef GuiInspectorField Parent;
+public:
+
+   GuiControl*       mMatEdContainer;
+   GuiBitmapButtonCtrl  *mMatPreviewButton;
+   GuiTextEditCtrl *mMatAssetIdTxt;
+
+   DECLARE_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetPtr);
+   static void consoleInit();
+
+   virtual GuiControl* constructEditControl();
+   virtual bool updateRects();
+   void setMaterialAsset(String assetId);
+};
+
+#endif // _ASSET_BASE_H_
+

+ 6 - 0
Engine/source/gui/editor/guiPopupMenuCtrl.cpp

@@ -169,6 +169,12 @@ void GuiPopupMenuTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool s
       PrimBuild::vertex2i(left, bottom);
       PrimBuild::end();*/
    }
+
+   //check if we're checked
+   if (mPopup->mMenuItems[cell.y].mIsChecked)
+   {
+      GFX->getDrawUtil()->draw2DSquare(Point2F(offset.x + mCellSize.y / 2, offset.y + mCellSize.y / 2), 5);
+   }
 }
 
 bool GuiPopupMenuTextListCtrl::onKeyDown(const GuiEvent &event)

+ 2 - 2
Templates/BaseGame/game/core/clientServer/scripts/client/connectionToServer.cs

@@ -32,7 +32,7 @@ function GameConnection::onConnectionAccepted(%this)
    // datablocks and objects are ghosted over.
    physicsInitWorld( "client" ); 
    
-   callOnModules("onCreateClient", "Game");
+   callOnModules("onCreateClientConnection", "Game");
 }
 
 function GameConnection::initialControlSet(%this)
@@ -134,5 +134,5 @@ function disconnectedCleanup()
    // We can now delete the client physics simulation.
    physicsDestroyWorld( "client" );    
    
-   callOnModules("onDestroyClient", "Game");
+   callOnModules("onDestroyClientConnection", "Game");
 }

+ 3 - 0
Templates/BaseGame/game/core/clientServer/scripts/server/levelInfo.cs

@@ -140,6 +140,9 @@ function parseMissionGroupForIds( %className, %childGroup )
    else
       %currentGroup = %childGroup;
       
+   if(!isObject(%currentGroup))
+      return "";
+      
    for(%i = 0; %i < (%currentGroup).getCount(); %i++)
    {      
       if( (%currentGroup).getObject(%i).getClassName() $= %className )

+ 1 - 0
Templates/BaseGame/game/core/clientServer/scripts/server/server.cs

@@ -242,6 +242,7 @@ function destroyServer()
    
    //Get our modules so we can exec any specific server-side loading/handling
    callOnModules("onDestroyGameServer", "Game");
+   callOnModules("onDestroyGameServer", "Core");
    
    // Save any server settings
    %prefPath = getPrefpath();

+ 143 - 0
Templates/BaseGame/game/core/gameObjects/datablocks/defaultDatablocks.cs

@@ -0,0 +1,143 @@
+datablock ReflectorDesc( DefaultCubeDesc )
+{  
+   texSize = 256;
+   nearDist = 0.1;
+   farDist = 1000.0;
+   objectTypeMask = 0xFFFFFFFF;
+   detailAdjust = 1.0;
+   priority = 1.0;
+   maxRateMs = 15;
+   useOcclusionQuery = true;
+};
+
+datablock ParticleEmitterNodeData(DefaultEmitterNodeData)
+{
+   timeMultiple = 1;
+};
+
+
+datablock ParticleData(DefaultParticle)
+{
+   textureName = "core/gameObjects/images/defaultParticle";
+   dragCoefficient = 0.498534;
+   gravityCoefficient = 0;
+   inheritedVelFactor = 0.499022;
+   constantAcceleration = 0.0;
+   lifetimeMS = 1313;
+   lifetimeVarianceMS = 500;
+   useInvAlpha = true;
+   spinRandomMin = -360;
+   spinRandomMax = 360;
+   spinSpeed = 1;
+
+   colors[0] = "0.992126 0.00787402 0.0314961 1";
+   colors[1] = "1 0.834646 0 0.645669";
+   colors[2] = "1 0.299213 0 0.330709";
+   colors[3] = "0.732283 1 0 0";
+   
+   sizes[0] = 0;
+   sizes[1] = 0.497467;
+   sizes[2] = 0.73857;
+   sizes[3] = 0.997986;
+   
+   times[0] = 0.0;
+   times[1] = 0.247059;
+   times[2] = 0.494118;
+   times[3] = 1;
+   
+   animTexName = "core/gameObjects/images/defaultParticle";
+};
+
+datablock ParticleEmitterData(DefaultEmitter)
+{
+   ejectionPeriodMS = "50";
+   ejectionVelocity = "1";
+   velocityVariance = "0";
+   ejectionOffset = "0.2";
+   thetaMax = "40";
+   particles = "DefaultParticle";
+   blendStyle = "ADDITIVE";
+   softParticles = "0";
+   softnessDistance = "1";
+};
+
+//-----------------------------------------------------------------------------
+// DefaultTrigger is used by the mission editor.  This is also an example
+// of trigger methods and callbacks.
+
+datablock TriggerData(DefaultTrigger)
+{
+   // The period is value is used to control how often the console
+   // onTriggerTick callback is called while there are any objects
+   // in the trigger.  The default value is 100 MS.
+   tickPeriodMS = 100;
+};
+
+datablock TriggerData(ClientTrigger : DefaultTrigger)
+{
+   clientSide = true;
+};
+
+datablock RibbonNodeData(DefaultRibbonNodeData)
+{
+   timeMultiple = 1.0;
+};
+
+//ribbon data////////////////////////////////////////
+
+datablock RibbonData(BasicRibbon)
+{
+   size[0] = 0.5;
+   color[0] = "1.0 0.0 0.0 1.0";
+   position[0] = 0.0;
+ 
+   size[1] = 0.0;
+   color[1] = "1.0 0.0 0.0 0.0";
+   position[1] = 1.0;
+ 
+   RibbonLength = 40;
+   fadeAwayStep = 0.1;
+   UseFadeOut = true;
+   RibbonMaterial = BasicRibbonMat;
+
+   category = "FX";
+};
+
+datablock RibbonData(TexturedRibbon)
+{
+   RibbonMaterial = TexturedRibbonMat;
+   size[0] = 0.5;
+   color[0] = "1.0 1.0 1.0 1.0";
+   position[0] = 0.0;
+ 
+   size[1] = 0.5;
+   color[1] = "1.0 1.0 1.0 1.0";
+   position[1] = 1.0;
+ 
+   RibbonLength = 40;
+   fadeAwayStep = 0.1;
+   UseFadeOut = true;
+   tileScale = 1;
+   fixedTexCoords = true;
+   TexcoordsRelativeToDistance = true;
+
+   category = "FX";
+};
+
+datablock MissionMarkerData(WayPointMarker)
+{
+   category = "Misc";
+   shapeFile = "core/gameObjects/shapes/octahedron.dts";
+};
+
+datablock MissionMarkerData(SpawnSphereMarker)
+{
+   category = "Misc";
+   shapeFile = "core/gameObjects/shapes/octahedron.dts";
+};
+
+datablock MissionMarkerData(CameraBookmarkMarker)
+{
+   category = "Misc";
+   shapeFile = "core/gameObjects/shapes/camera.dts";
+};

BIN
Templates/BaseGame/game/core/gameObjects/images/camera.png


BIN
Templates/BaseGame/game/core/gameObjects/images/defaultParticle.png


BIN
Templates/BaseGame/game/core/gameObjects/images/defaultRoadTextureOther.png


BIN
Templates/BaseGame/game/core/gameObjects/images/defaultRoadTextureTop.png


BIN
Templates/BaseGame/game/core/gameObjects/images/defaultpath.png


BIN
Templates/BaseGame/game/core/gameObjects/images/defaultpath_normal.png


BIN
Templates/BaseGame/game/core/gameObjects/images/green.jpg


BIN
Templates/BaseGame/game/core/gameObjects/images/ribTex.png


+ 78 - 0
Templates/BaseGame/game/core/gameObjects/materials/materials.cs

@@ -0,0 +1,78 @@
+new ShaderData( BasicRibbonShader )
+{
+   DXVertexShaderFile   = $Core::CommonShaderPath @ "/ribbons/basicRibbonShaderV.hlsl";
+   DXPixelShaderFile    = $Core::CommonShaderPath @ "/ribbons/basicRibbonShaderP.hlsl";
+ 
+   OGLVertexShaderFile   = $Core::CommonShaderPath @ "/ribbons/gl/basicRibbonShaderV.glsl";
+   OGLPixelShaderFile    = $Core::CommonShaderPath @ "/ribbons/gl/basicRibbonShaderP.glsl";
+ 
+   samplerNames[0] = "$ribTex";
+ 
+   pixVersion = 2.0;
+};
+ 
+singleton CustomMaterial( BasicRibbonMat )
+{
+   shader = BasicRibbonShader;
+   version = 2.0;
+   
+   emissive[0] = true;
+   
+   doubleSided = true;
+   translucent = true;
+   BlendOp = AddAlpha;
+   translucentBlendOp = AddAlpha;
+   
+   preload = true;
+};
+
+new ShaderData( TexturedRibbonShader )
+{
+   DXVertexShaderFile   = $Core::CommonShaderPath @ "/ribbons/texRibbonShaderV.hlsl";
+   DXPixelShaderFile    = $Core::CommonShaderPath @ "/ribbons/texRibbonShaderP.hlsl";
+   
+   OGLVertexShaderFile   = $Core::CommonShaderPath @ "/ribbons/gl/texRibbonShaderV.glsl";
+   OGLPixelShaderFile    = $Core::CommonShaderPath @ "/ribbons/gl/texRibbonShaderP.glsl";
+   
+   samplerNames[0] = "$ribTex";
+   
+   pixVersion = 2.0;
+};
+ 
+singleton CustomMaterial( TexturedRibbonMat )
+{
+   shader = TexturedRibbonShader;
+   version = 2.0;
+   
+   emissive[0] = true;
+   
+   doubleSided = true;
+   translucent = true;
+   BlendOp = AddAlpha;
+   translucentBlendOp = AddAlpha;
+
+   sampler["ribTex"] = "core/gameObjects/images/ribTex.png";
+   
+   preload = true;
+};
+
+singleton Material(DefaultDecalRoadMaterial)
+{
+   diffuseMap[0] = "core/gameObjects/images/defaultRoadTextureTop.png";
+   mapTo = "unmapped_mat";
+   materialTag0 = "RoadAndPath";
+};
+
+singleton Material(DefaultRoadMaterialTop)
+{
+   mapTo = "unmapped_mat";
+   diffuseMap[0] = "core/gameObjects/images/defaultRoadTextureTop.png";
+   materialTag0 = "RoadAndPath";
+};
+
+singleton Material(DefaultRoadMaterialOther)
+{
+   mapTo = "unmapped_mat";
+   diffuseMap[0] = "core/gameObjects/images/defaultRoadTextureOther.png";
+   materialTag0 = "RoadAndPath";
+};

BIN
Templates/BaseGame/game/core/gameObjects/shapes/camera.dts


+ 112 - 0
Templates/BaseGame/game/core/gameObjects/shapes/materials.cs

@@ -0,0 +1,112 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+singleton Material(OctahedronMat)
+{
+   mapTo = "green";
+
+   diffuseMap[0] = "core/gameObjects/images/camera";
+
+   translucent = "1";
+   translucentBlendOp = "LerpAlpha";
+   emissive = "0";
+   castShadows = "0";
+
+   colorMultiply[0] = "0 1 0 1";
+};
+
+//--- camera.dts MATERIALS BEGIN ---
+singleton Material(CameraMat)
+{
+   mapTo = "pasted__phongE1";
+
+	diffuseMap[0] = "core/gameObjects/images/camera";
+
+	diffuseColor[0] = "0 0.627451 1 1";
+	specular[0] = "1 1 1 1";
+	specularPower[0] = 211;
+	pixelSpecular[0] = 1;
+	emissive[0] = 1;
+
+	doubleSided = 1;
+	translucent = true;
+	translucentBlendOp = "LerpAlpha";
+   castShadows = false;
+   materialTag0 = "Miscellaneous";
+};
+
+//--- camera.dts MATERIALS END ---
+//--- noshape.dts MATERIALS BEGIN ---
+singleton Material(noshape_NoShape)
+{
+   mapTo = "NoShape";
+
+	diffuseMap[0] = "";
+
+	diffuseColor[0] = "0.8 0.003067 0 .8";
+	emissive[0] = 0;
+
+	doubleSided = false;
+	translucent = 1;
+	translucentBlendOp = "LerpAlpha";
+	castShadows = false;
+};
+
+//--- noshape.dts MATERIALS END ---
+
+//--- noshapetext.dae MATERIALS BEGIN ---
+singleton Material(noshapetext_lambert1)
+{
+   mapTo = "lambert1";
+
+	diffuseMap[0] = "";
+
+	diffuseColor[0] = "0.4 0.4 0.4 1";
+	specular[0] = "1 1 1 1";
+	specularPower[0] = 8;
+	pixelSpecular[0] = false;
+	emissive[0] = true;
+
+	doubleSided = false;
+	translucent = false;
+	translucentBlendOp = "None";
+};
+
+singleton Material(noshapetext_noshape_mat)
+{
+   mapTo = "noshape_mat";
+
+	diffuseMap[0] = "";
+
+	diffuseColor[0] = "0.4 0.3504 0.363784 0.33058";
+	specular[0] = "1 1 1 1";
+	specularPower[0] = 8;
+	pixelSpecular[0] = false;
+	emissive[0] = true;
+
+	doubleSided = false;
+	translucent = true;
+	translucentBlendOp = "None";
+};
+
+//--- noshapetext.dae MATERIALS END ---
+

BIN
Templates/BaseGame/game/core/gameObjects/shapes/noshape.dts


BIN
Templates/BaseGame/game/core/gameObjects/shapes/octahedron.dts


BIN
Templates/BaseGame/game/core/gameObjects/shapes/simplecone.dts


BIN
Templates/BaseGame/game/core/gameObjects/shapes/unit_capsule.dts


BIN
Templates/BaseGame/game/core/gameObjects/shapes/unit_cube.dts


BIN
Templates/BaseGame/game/core/gameObjects/shapes/unit_sphere.dts


+ 105 - 0
Templates/BaseGame/game/data/ExampleModule/ExampleModule.cs

@@ -0,0 +1,105 @@
+//This is our create function. It's pointed to, by name, via a field defined in 
+//the ExampleModule.module file, which contains our module definition. It is called
+//when the module is initially loaded by the engine. Generally, only common, base-level
+//stuff is created(or destroyed, in the companion function), like things utilized or 
+//shared on both the client and server, or things that need to be loaded before anything
+//else.
+function ExampleModule::onCreate(%this)
+{
+
+}
+
+//Similar to the create function, this is defined in thye module file, and called 
+//when the module is destroyed, usually as part of the game shutting down.
+function ExampleModule::onDestroy(%this)
+{
+
+}
+
+//This is called when the server part of the application is initially created. Torque3D
+//assumes, even in a single player context, that there is ultimately a 'server' and a 'client'
+//So during initial launch and startup of the engine, the server side is initialized in
+//core/clientServer/scripts/server/server.cs - in the initServer() function where this is called. 
+//This is called on all modules that have this function defined. This is important for 
+//any persistant parts of the server that always need to run such as gameplay scripts
+//
+//Importantly, when the gane session server is created, several functions are called to as part of the gamemode logic
+//The script below contains the callbacks so the gamemode can actually be set up, but the server-side callbacks in question:
+//ExampleGameMode::onMissionStart
+//ExampleGameMode::onMissionEnded
+//ExampleGameMode::onMissionReset
+//Are called during the startup, shut down, and resetting of any and all active gamemodes, as informed by the loaded scenes
+//when the game server is processed.
+//These callbacks are activated in core/clientServer/scripts/server/levelLoad.cs
+function FPSGameplay::initServer(%this)
+{
+   //This script contains our ExampleGameMode logic
+   exec("./scripts/ExampleGamemodeScript.cs");
+}
+
+//This is called when a game session server is actually created so the game may be played. It's called 
+//from core/clientServer/scripts/server/server.cs - in the createServer() function, which is called when 
+//A game session is actually launched, and the server is generated so game clients can connect to it.
+//This is utilized to set up common things that need to be set up each time the game session server is 
+//created, such as common variables, datablocks to be transmitted to the client, etc.
+function ExampleModule::onCreateGameServer(%this)
+{
+   //In particular, the default client/server module handles the transmission of datablocks from 
+   //server to client automatically as part of the connection and prepping process alongside
+   //validation and tramission of level objects. It does this in an abstracted way by adding
+   //the file paths to a master DatablockFilesList array as per below. When the server is created in 
+   //onServerCreated(), it loads the datablocks via this array, and when when the server goes
+   //to pass data to the client, it iterates over this list and processes it, ensuring all datablocks
+   //are the most up to date possible for transmission to the connecting client
+   %this.registerDatablock("./datablocks/ExampleDatablock.cs");
+}
+
+//This is called when a game session server is destroyed, when the game shuts down. It's called from
+//core/clientServer/scripts/server/server.cs - in the destroyServer() function, which just cleans up anything
+//The module may have set up as part of the game server being created.
+function ExampleModule::onDestroyGameServer(%this)
+{
+   
+}
+
+//Similar to initServer, this is called during the initial launch of the application and the client component
+//is set up. The difference is that the client may not actually be created, such as in the case for dedicated servers
+//Where no UI or gameplay interface is required. It's called from core/clientServer/scripts/client/client.cs - 
+//in the initClient() function. It sets up common elements that the client will always need, such as scripts, GUIs
+//and the like
+function ExampleModule::initClient(%this)
+{
+   //client scripts
+   //Here, we exec out keybind scripts so the player is able to move when they get into a game
+   exec("./scripts/default.keybinds.cs");
+   
+   %prefPath = getPrefpath();
+   if(isFile(%prefPath @ "/keybinds.cs"))
+      exec(%prefPath @ "/keybinds.cs");
+      
+   exec("./scripts/inputCommands.cs");
+}
+
+//This is called when a game session client successfuly connects to a game server. 
+//It's called from core/clientServer/scripts/client/connectionToServer.cs - in the GameConnection::onConnectionAccepted() function
+//It's used for any client-side specific game session stuff that the client needs to load or pass to the server, such as profile data
+//account progress, preferences, etc.
+//
+//When a client is connected, the gamemode logic also has a callback activated - ExampleGameMode::onClientEnterGame().
+function ExampleModule::onCreateClientConnection(%this)
+{
+   //This will push our keybind movemap onto the input stack, so we can control our camera in our ExampleGameMode
+   ExampleMoveMap.push();
+}
+
+//This is called when a client game session disconnects from a game server
+//It's called from core/clientServer/scripts/client/connectionToServer.cs - in the disconnectedCleanup() function
+//It's used to clean up and potentially write out any client-side stuff that needs housekeeping when disconnecting for any reason.
+//It will be called if the connection is manually terminated, or lost due to any sort of connection issue.
+//
+//When a client disconnects, the gamemode logic has a callback activated - ExampleGameMode::onClientLeaveGame().
+function ExampleModule::onDestroyClientConnection(%this)
+{
+   //This will pop the keybind, cleaning it up from the input stack, as it no longer applies
+   ExampleMoveMap.pop();
+}

+ 25 - 0
Templates/BaseGame/game/data/ExampleModule/ExampleModule.module

@@ -0,0 +1,25 @@
+<ModuleDefinition
+    canSave="true"
+    canSaveDynamicFields="true"
+    ModuleId="ExampleModule"
+    VersionId="1"
+    Group="Game"
+    scriptFile="ExampleModule.cs"
+    CreateFunction="onCreate"
+    DestroyFunction="onDestroy">
+    <DeclaredAssets
+        canSave="true"
+        canSaveDynamicFields="true"
+        Extension="asset.taml"
+        Recurse="true" />
+    <AutoloadAssets
+        canSave="true"
+        canSaveDynamicFields="true"
+        AssetType="ComponentAsset"
+        Recurse="true" />
+    <AutoloadAssets
+        canSave="true"
+        canSaveDynamicFields="true"
+        AssetType="GUIAsset"
+        Recurse="true" />
+</ModuleDefinition>

+ 7 - 0
Templates/BaseGame/game/data/ExampleModule/GUIs/ExampleGUI.asset.taml

@@ -0,0 +1,7 @@
+<GUIAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="ExampleGUI"
+    scriptFile="@assetFile=ExampleGUI.gui"
+    GUIFile="@assetFile=ExampleGUI.gui"
+    VersionId="1" />

+ 9 - 0
Templates/BaseGame/game/data/ExampleModule/GUIs/ExampleGUI.cs

@@ -0,0 +1,9 @@
+function ExampleGUI::onWake(%this)
+{
+    
+}
+
+function ExampleGUI::onSleep(%this)
+{
+    
+}

+ 7 - 0
Templates/BaseGame/game/data/ExampleModule/GUIs/ExampleGUI.gui

@@ -0,0 +1,7 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(ExampleGUI) 
+{
+    position = "0 0";
+	extent = "100 100";
+};
+//--- OBJECT WRITE END ---

+ 9 - 0
Templates/BaseGame/game/data/ExampleModule/components/ExampleComponent.asset.taml

@@ -0,0 +1,9 @@
+<ComponentAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="ExampleComponent"
+    componentName="ExampleComponent"
+    componentClass="Component"
+    description="An example script component."
+    scriptFile="@assetFile=ExampleComponent.cs"
+    VersionId="1" />

+ 26 - 0
Templates/BaseGame/game/data/ExampleModule/components/ExampleComponent.cs

@@ -0,0 +1,26 @@
+//onAdd is called when the component is created and then added to it's owner entity.
+//You would also add any script-defined component fields via addComponentField().
+function ExampleComponent::onAdd(%this)
+{
+    
+}
+//onAdd is called when the component is removed and deleted from it's owner entity.
+function ExampleComponent::onRemove(%this)
+{
+    
+}
+//onClientConnect is called any time a new client connects to the server.
+function ExampleComponent::onClientConnect(%this, %client)
+{
+    
+}
+//onClientDisconnect is called any time a client disconnects from the server.
+function ExampleComponent::onClientDisonnect(%this, %client)
+{
+
+}
+//update is called when the component does an update tick.
+function ExampleComponent::Update(%this)
+{
+    
+}

+ 0 - 0
Templates/BaseGame/game/data/ExampleModule/datablocks/ExampleDatablock.cs


+ 8 - 0
Templates/BaseGame/game/data/ExampleModule/levels/ExampleLevel.asset.taml

@@ -0,0 +1,8 @@
+<LevelAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="ExampleLevel"
+    LevelFile="ExampleLevel.mis"
+    LevelName="Example Level"
+    LevelDescription="An example level asset"
+    VersionId="1" />

+ 99 - 0
Templates/BaseGame/game/data/ExampleModule/levels/ExampleLevel.mis

@@ -0,0 +1,99 @@
+//--- OBJECT WRITE BEGIN ---
+new Scene(EditorTemplateLevel) {
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      cdTrack = "2";
+      CTF_scoreLimit = "5";
+      enabled = "1";
+      musicTrack = "lush";
+      gameModeName="ExampleGameMode";
+
+   new LevelInfo(TheLevelInfo) {
+      nearClip = "0.1";
+      visibleDistance = "1000";
+      visibleGhostDistance = "0";
+      decalBias = "0.0015";
+      fogColor = "0.6 0.6 0.7 1";
+      fogDensity = "0";
+      fogDensityOffset = "700";
+      fogAtmosphereHeight = "0";
+      canvasClearColor = "0 0 0 255";
+      ambientLightBlendPhase = "1";
+      ambientLightBlendCurve = "0 0 -1 -1";
+      advancedLightmapSupport = "0";
+      soundAmbience = "AudioAmbienceDefault";
+      soundDistanceModel = "Linear";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+         desc0 = "A blank room template that acts as a starting point.";
+         enabled = "1";
+         levelName = "Blank Room Template";
+   };
+   new SkyBox(theSky) {
+      Material = "BlankSkyMat";
+      drawBottom = "0";
+      fogBandHeight = "0";
+      position = "0 0 0";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   new Sun(theSun) {
+      azimuth = "230.396";
+      elevation = "45";
+      color = "0.968628 0.901961 0.901961 1";
+      ambient = "0.337255 0.533333 0.619608 1";
+      brightness = "1";
+      castShadows = "1";
+      staticRefreshFreq = "250";
+      dynamicRefreshFreq = "8";
+      coronaEnabled = "1";
+      coronaScale = "0.5";
+      coronaTint = "1 1 1 1";
+      coronaUseLightColor = "1";
+      flareScale = "1";
+      attenuationRatio = "0 1 1";
+      shadowType = "PSSM";
+      texSize = "1024";
+      overDarkFactor = "3000 1500 750 250";
+      shadowDistance = "200";
+      shadowSoftness = "0.25";
+      numSplits = "4";
+      logWeight = "0.9";
+      fadeStartDistance = "0";
+      lastSplitTerrainOnly = "0";
+      representedInLightmap = "0";
+      shadowDarkenColor = "0 0 0 -1";
+      includeLightmappedGeometryInShadow = "0";
+      position = "0 0 0";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+         bias = "0.1";
+         Blur = "1";
+         enabled = "1";
+         height = "1024";
+         lightBleedFactor = "0.8";
+         minVariance = "0";
+         pointShadowType = "PointShadowType_Paraboloid";
+         shadowBox = "-100 -100 -100 100 100 100";
+         splitFadeDistances = "1 1 1 1";
+         width = "3072";
+   };
+   new GroundPlane() {
+      squareSize = "128";
+      scaleU = "25";
+      scaleV = "25";
+      Material = "Grid_512_Grey";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+         enabled = "1";
+         position = "0 0 0";
+         rotation = "1 0 0 0";
+         scale = "1 1 1";
+   };
+};
+//--- OBJECT WRITE END ---
+

+ 6 - 0
Templates/BaseGame/game/data/ExampleModule/postFXs/ExamplePostEffect.asset.taml

@@ -0,0 +1,6 @@
+<PostEffectAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="ExamplePostEffect"
+    scriptFile="@assetFile=ExamplePostEffect.cs"
+    VersionId="1" />

+ 96 - 0
Templates/BaseGame/game/data/ExampleModule/postFXs/ExamplePostEffect.cs

@@ -0,0 +1,96 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+singleton ShaderData( ExamplePostEffect_Shader )
+{
+   DXVertexShaderFile 	= $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+   DXPixelShaderFile 	= $Core:modulePath @ "ExamplePostEffectP.hlsl";   
+   OGLVertexShaderFile  = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+   OGLPixelShaderFile   = $Core:modulePath @ "ExamplePostEffectP.glsl";
+   
+   samplerNames[0] = "$inputTex";
+   
+   pixVersion = 3.0;
+};
+
+singleton GFXStateBlockData( ExamplePostEffect_StateBlock )
+{
+   samplersDefined = true;
+   samplerStates[0] = SamplerClampLinear;
+   samplerStates[1] = SamplerClampLinear;
+   samplerStates[2] = SamplerClampLinear;
+   samplerStates[3] = SamplerClampLinear;
+   
+   blendDefined = true;
+   blendDest = GFXBlendOne;
+   blendSrc = GFXBlendZero;
+   
+   zDefined = true;
+   zEnable = false;
+   zWriteEnable = false;
+   
+   cullDefined = true;
+   cullMode = GFXCullNone;
+};
+
+
+function ExamplePostEffect::setShaderConsts( %this )
+{
+}
+
+function ExamplePostEffect::preProcess( %this )
+{
+}
+
+function ExamplePostEffect::onEnabled( %this )
+{
+   return true;
+}
+
+function ExamplePostEffect::onDisabled( %this )
+{
+}
+
+singleton PostEffect( ExamplePostEffect )
+{
+   isEnabled = false;
+   allowReflectPass = false;
+
+   // Resolve the HDR before we render any editor stuff
+   // and before we resolve the scene to the backbuffer.
+   renderTime = "PFXBeforeBin";
+   renderBin = "EditorBin";
+   renderPriority = 9999;
+      
+   // The bright pass generates a bloomed version of 
+   // the scene for pixels which are brighter than a 
+   // fixed threshold value.
+   //
+   // This is then used in the final HDR combine pass
+   // at the end of this post effect chain.
+   shader = ExamplePostEffect_Shader;
+   stateBlock = ExamplePostEffect_StateBlock;
+   texture[0] = "$backBuffer";
+   target = "$outTex";
+   targetFormat = "GFXFormatR16G16B16A16F"; 
+   targetScale = "1 1";
+};

+ 6 - 0
Templates/BaseGame/game/data/ExampleModule/scripts/ExampleGamemodeScript.asset.taml

@@ -0,0 +1,6 @@
+<ScriptAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="ExampleGamemodeScript"
+    scriptFile="@assetFile=ExampleGamemodeScript.cs"
+    VersionId="1" />

+ 128 - 0
Templates/BaseGame/game/data/ExampleModule/scripts/ExampleGamemodeScript.cs

@@ -0,0 +1,128 @@
+//-----------------------------------------------------------------------------
+// The server has started up so do some game start up
+//-----------------------------------------------------------------------------
+
+//This file implements game mode logic for an Example gamemode. The primary functions:
+//ExampleGameMode::onMissionStart
+//ExampleGameMode::onMissionReset
+//ExampleGameMode::onMissionEnd
+//Are the primary hooks for the server to start, restart and end any active gamemodes
+//onMissionStart, for example is called from core/clientServer/scripts/server/levelLoad.cs
+//It's called once the server has successfully loaded the level, and has parsed
+//through any active scenes to get GameModeNames defined by them. It then iterates
+//over them and calls these callbacks to envoke gamemode behaviors. This allows multiple
+//gamemodes to be in effect at one time. Modules can implement as many gamemodes as you want.
+//
+//For levels that can be reused for multiple gammodes, the general setup would be a primary level file
+//with the Scene in it having the main geometry, weapons, terrain, etc. You would then have subScenes that
+//each contain what's necessary for the given gamemode, such as a subScene that just adds the flags and capture
+//triggers for a CTF mode. The subscene would then have it's GameModeName defined to run the CTF gamemode logic
+//and the levelLoad code will execute it.
+
+//This function is called when the level finishes loading. It sets up the initial configuration, variables and
+//spawning and dynamic objects, timers or rules needed for the gamemode to run
+function ExampleGameMode::onMissionStart()
+{
+   //set up the game and game variables
+   ExampleGameMode::initGameVars();
+
+   if ($Game::Running)
+   {
+      error("onMissionStart: End the game first!");
+      return;
+   }
+
+   // Start the game timer
+   if ($Game::Duration)
+      $Game::Schedule = schedule($Game::Duration * 1000, "onGameDurationEnd");
+      
+   $Game::Running = true;
+   
+   $Game = ExampleGameMode;
+}
+
+//This function is called when the level ends. It can be envoked due to the gamemode ending
+//but is also kicked off when the game server is shut down as a form of cleanup for anything the gamemode
+//created or is managing like the above mentioned dynamic objects or timers
+function ExampleGameMode::onMissionEnded()
+{
+   if (!$Game::Running)
+   {
+      error("onMissionEnded: No game running!");
+      return;
+   }
+
+   // Stop any game timers
+   cancel($Game::Schedule);
+
+   $Game::Running = false;
+   $Game = "";
+}
+
+//This function is called in the event the server resets and is used to re-initialize the gamemode
+function ExampleGameMode::onMissionReset()
+{
+   // Called by resetMission(), after all the temporary mission objects
+   // have been deleted.
+   ExampleGameMode::initGameVars();
+}
+
+//This sets up our gamemode's duration time
+function ExampleGameMode::initGameVars()
+{
+   // Set the gameplay parameters
+   $Game::Duration = 30 * 60;
+}
+
+//This is called when the timer runs out, allowing the gamemode to end
+function ExampleGameMode::onGameDurationEnd()
+{
+   //we don't end if we're currently editing the level
+   if ($Game::Duration && !(EditorIsActive() && GuiEditorIsActive()))
+      ExampleGameMode::onMissionEnded();
+}
+
+//This is called when a client enters the game server. It's used to spawn a player object
+//set up any client-specific properties such as saved configs, values, their name, etc
+//These callbacks are activated in core/clientServer/scripts/server/levelDownload.cs
+function ExampleGameMode::onClientEnterGame(%client)
+{
+   //Set the player name based on the client's connection data
+   %client.setPlayerName(%client.connectData);
+
+   //In this example, we just spawn a camera
+   if (!isObject(%client.camera))
+   {
+      if(!isObject(Observer))
+      {
+         datablock CameraData(Observer)
+         {
+            mode = "Observer";
+         };  
+      }
+      
+      %client.camera = spawnObject("Camera", Observer);
+   }
+
+   // If we have a camera then set up some properties
+   if (isObject(%client.camera))
+   {
+      MissionCleanup.add( %this.camera );
+      %client.camera.scopeToClient(%client);
+
+      %client.setControlObject(%client.camera);
+
+      %client.camera.setTransform("0 0 1 0 0 0 0");
+   }
+}
+
+//This is called when the player leaves the game server. It's used to clean up anything that
+//was spawned or setup for the client when it connected, in onClientEnterGame
+//These callbacks are activated in core/clientServer/scripts/server/levelDownload.cs
+function ExampleGameMode::onClientLeaveGame(%client)
+{
+   // Cleanup the camera
+   if (isObject(%client.camera))
+      %client.camera.delete();
+
+}

+ 73 - 0
Templates/BaseGame/game/data/ExampleModule/scripts/default.keybinds.cs

@@ -0,0 +1,73 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+if ( isObject( ExampleMoveMap ) )
+   ExampleMoveMap.delete();
+new ActionMap(ExampleMoveMap);
+
+//------------------------------------------------------------------------------
+// Non-remapable binds
+//------------------------------------------------------------------------------
+ExampleMoveMap.bind( keyboard, F2, showPlayerList );
+
+ExampleMoveMap.bind(keyboard, "ctrl h", hideHUDs);
+
+ExampleMoveMap.bind(keyboard, "alt p", doScreenShotHudless);
+
+ExampleMoveMap.bindCmd(keyboard, "escape", "", "disconnect();");
+
+//------------------------------------------------------------------------------
+// Movement Keys
+//------------------------------------------------------------------------------
+ExampleMoveMap.bind( keyboard, a, moveleft );
+ExampleMoveMap.bind( keyboard, d, moveright );
+ExampleMoveMap.bind( keyboard, left, moveleft );
+ExampleMoveMap.bind( keyboard, right, moveright );
+
+ExampleMoveMap.bind( keyboard, w, moveforward );
+ExampleMoveMap.bind( keyboard, s, movebackward );
+ExampleMoveMap.bind( keyboard, up, moveforward );
+ExampleMoveMap.bind( keyboard, down, movebackward );
+
+ExampleMoveMap.bind( keyboard, e, moveup );
+ExampleMoveMap.bind( keyboard, c, movedown );
+
+ExampleMoveMap.bind( keyboard, space, jump );
+ExampleMoveMap.bind( mouse, xaxis, yaw );
+ExampleMoveMap.bind( mouse, yaxis, pitch );
+
+ExampleMoveMap.bind( gamepad, thumbrx, "D", "-0.23 0.23", gamepadYaw );
+ExampleMoveMap.bind( gamepad, thumbry, "D", "-0.23 0.23", gamepadPitch );
+ExampleMoveMap.bind( gamepad, thumblx, "D", "-0.23 0.23", gamePadMoveX );
+ExampleMoveMap.bind( gamepad, thumbly, "D", "-0.23 0.23", gamePadMoveY );
+
+ExampleMoveMap.bind( gamepad, btn_a, jump );
+ExampleMoveMap.bindCmd( gamepad, btn_back, "disconnect();", "" );
+
+//------------------------------------------------------------------------------
+// Misc.
+//------------------------------------------------------------------------------
+GlobalActionMap.bind(keyboard, "tilde", toggleConsole);
+GlobalActionMap.bindCmd(keyboard, "alt k", "cls();","");
+GlobalActionMap.bindCmd(keyboard, "alt enter", "", "Canvas.attemptFullscreenToggle();");
+GlobalActionMap.bindCmd(keyboard, "F1", "", "contextHelp();");
+ExampleMoveMap.bindCmd(keyboard, "n", "toggleNetGraph();", "");

+ 204 - 0
Templates/BaseGame/game/data/ExampleModule/scripts/inputCommands.cs

@@ -0,0 +1,204 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+function escapeFromGame()
+{
+   disconnect();
+}
+
+$movementSpeed = 1; // m/s
+
+function setSpeed(%speed)
+{
+   if(%speed)
+      $movementSpeed = %speed;
+}
+
+function moveleft(%val)
+{
+   $mvLeftAction = %val * $movementSpeed;
+}
+
+function moveright(%val)
+{
+   $mvRightAction = %val * $movementSpeed;
+}
+
+function moveforward(%val)
+{
+   $mvForwardAction = %val * $movementSpeed;
+}
+
+function movebackward(%val)
+{
+   $mvBackwardAction = %val * $movementSpeed;
+}
+
+function moveup(%val)
+{
+   %object = ServerConnection.getControlObject();
+   
+   if(%object.isInNamespaceHierarchy("Camera"))
+      $mvUpAction = %val * $movementSpeed;
+}
+
+function movedown(%val)
+{
+   %object = ServerConnection.getControlObject();
+   
+   if(%object.isInNamespaceHierarchy("Camera"))
+      $mvDownAction = %val * $movementSpeed;
+}
+
+function turnLeft( %val )
+{
+   $mvYawRightSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
+}
+
+function turnRight( %val )
+{
+   $mvYawLeftSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
+}
+
+function panUp( %val )
+{
+   $mvPitchDownSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
+}
+
+function panDown( %val )
+{
+   $mvPitchUpSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
+}
+
+function getMouseAdjustAmount(%val)
+{
+   // based on a default camera FOV of 90'
+   return(%val * ($cameraFov / 90) * 0.01) * $pref::Input::LinkMouseSensitivity;
+}
+
+function getGamepadAdjustAmount(%val)
+{
+   // based on a default camera FOV of 90'
+   return(%val * ($cameraFov / 90) * 0.01) * 10.0;
+}
+
+function yaw(%val)
+{
+   %yawAdj = getMouseAdjustAmount(%val);
+   if(ServerConnection.isControlObjectRotDampedCamera())
+   {
+      // Clamp and scale
+      %yawAdj = mClamp(%yawAdj, -m2Pi()+0.01, m2Pi()-0.01);
+      %yawAdj *= 0.5;
+   }
+
+   $mvYaw += %yawAdj;
+}
+
+function pitch(%val)
+{
+   %pitchAdj = getMouseAdjustAmount(%val);
+   if(ServerConnection.isControlObjectRotDampedCamera())
+   {
+      // Clamp and scale
+      %pitchAdj = mClamp(%pitchAdj, -m2Pi()+0.01, m2Pi()-0.01);
+      %pitchAdj *= 0.5;
+   }
+
+   $mvPitch += %pitchAdj;
+}
+
+function jump(%val)
+{
+   $mvTriggerCount2++;
+}
+
+function gamePadMoveX( %val )
+{
+   if(%val > 0)
+   {
+      $mvRightAction = %val * $movementSpeed;
+      $mvLeftAction = 0;
+   }
+   else
+   {
+      $mvRightAction = 0;
+      $mvLeftAction = -%val * $movementSpeed;
+   }
+}
+
+function gamePadMoveY( %val )
+{
+   if(%val > 0)
+   {
+      $mvForwardAction = %val * $movementSpeed;
+      $mvBackwardAction = 0;
+   }
+   else
+   {
+      $mvForwardAction = 0;
+      $mvBackwardAction = -%val * $movementSpeed;
+   }
+}
+
+function gamepadYaw(%val)
+{
+   %yawAdj = getGamepadAdjustAmount(%val);
+   if(ServerConnection.isControlObjectRotDampedCamera())
+   {
+      // Clamp and scale
+      %yawAdj = mClamp(%yawAdj, -m2Pi()+0.01, m2Pi()-0.01);
+      %yawAdj *= 0.5;
+   }
+
+   if(%yawAdj > 0)
+   {
+      $mvYawLeftSpeed = %yawAdj;
+      $mvYawRightSpeed = 0;
+   }
+   else
+   {
+      $mvYawLeftSpeed = 0;
+      $mvYawRightSpeed = -%yawAdj;
+   }
+}
+
+function gamepadPitch(%val)
+{
+   %pitchAdj = getGamepadAdjustAmount(%val);
+   if(ServerConnection.isControlObjectRotDampedCamera())
+   {
+      // Clamp and scale
+      %pitchAdj = mClamp(%pitchAdj, -m2Pi()+0.01, m2Pi()-0.01);
+      %pitchAdj *= 0.5;
+   }
+
+   if(%pitchAdj > 0)
+   {
+      $mvPitchDownSpeed = %pitchAdj;
+      $mvPitchUpSpeed = 0;
+   }
+   else
+   {
+      $mvPitchDownSpeed = 0;
+      $mvPitchUpSpeed = -%pitchAdj;
+   }
+}

+ 7 - 0
Templates/BaseGame/game/data/ExampleModule/source/ExampleCppObject.asset.taml

@@ -0,0 +1,7 @@
+<CppAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="ExampleCppObject"
+    codeFile="@assetFile=data/ExampleModule/source/ExampleCppObject.cpp"
+    headerFile="@assetFile=data/ExampleModule/source/ExampleCppObject.h"
+    VersionId="1" />

+ 0 - 0
Templates/BaseGame/game/data/ExampleModule/source/ExampleCppObject.cpp


+ 0 - 0
Templates/BaseGame/game/data/ExampleModule/source/ExampleCppObject.h


+ 18 - 0
Templates/BaseGame/game/data/ExampleModule/source/ExampleModule.cpp

@@ -0,0 +1,18 @@
+#include "core/module.h"
+#include "console/engineAPI.h"
+
+MODULE_BEGIN(ExampleModule_Module)
+
+MODULE_INIT_AFTER(Sim)
+MODULE_SHUTDOWN_BEFORE(Sim)
+
+MODULE_INIT
+{
+	// Setup anything needed when the engine initializes here
+}
+MODULE_SHUTDOWN
+{
+	// Cleanup anything that was initialized before here
+}
+MODULE_END;
+

+ 122 - 0
Templates/BaseGame/game/data/gameUI/GUIs/playGui.cs

@@ -0,0 +1,122 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// PlayGui is the main TSControl through which the game is viewed.
+// The PlayGui also contains the hud controls.
+//-----------------------------------------------------------------------------
+
+function PlayGui::onWake(%this)
+{
+   // Turn off any shell sounds...
+   // sfxStop( ... );
+
+   $enableDirectInput = "1";
+   activateDirectInput();
+
+   // Message hud dialog
+   if ( isObject( MainChatHud ) )
+   {
+      Canvas.pushDialog( MainChatHud );
+      chatHud.attach(HudMessageVector);
+   }      
+   
+   // just update the action map here
+   if(isObject(moveMap))
+      moveMap.push();
+
+   // hack city - these controls are floating around and need to be clamped
+   if ( isFunction( "refreshCenterTextCtrl" ) )
+      schedule(0, 0, "refreshCenterTextCtrl");
+   if ( isFunction( "refreshBottomTextCtrl" ) )
+      schedule(0, 0, "refreshBottomTextCtrl");
+}
+
+function PlayGui::onSleep(%this)
+{
+   if ( isObject( MainChatHud ) )
+      Canvas.popDialog( MainChatHud );
+   
+   // pop the keymaps
+   if(isObject(moveMap))
+      moveMap.pop();
+}
+
+function PlayGui::clearHud( %this )
+{
+   Canvas.popDialog( MainChatHud );
+
+   while ( %this.getCount() > 0 )
+      %this.getObject( 0 ).delete();
+}
+
+//-----------------------------------------------------------------------------
+
+function refreshBottomTextCtrl()
+{
+   BottomPrintText.position = "0 0";
+}
+
+function refreshCenterTextCtrl()
+{
+   CenterPrintText.position = "0 0";
+}
+
+/*function PlayGui::onRightMouseDown(%this)
+{
+   %this.nocursor = true;
+   Canvas.checkCursor();
+}
+
+function PlayGui::onRightMouseUp(%this)
+{
+   %this.nocursor = false;
+   Canvas.checkCursor();
+}*/
+
+/*function PlayGui::onInputEvent(%this, %device, %action, %state)
+{
+   if(%device $= "mouse0" && %action $= "button1")
+   {
+      if(%state == 1)
+      {
+         %this.nocursor = true;
+         Canvas.checkCursor();
+      }
+      else 
+      {
+         %this.nocursor = false;
+         Canvas.checkCursor();
+      }
+   }
+   else if(%device $= "keyboard")
+   {
+      if(%action $= "w")
+         moveforward(%state);
+      else if(%action $= "a")
+         moveleft(%state);
+      else if(%action $= "s")
+         movebackward(%state);
+      else if(%action $= "d")
+         moveright(%state);
+   }
+}*/

+ 50 - 0
Templates/BaseGame/game/data/gameUI/GUIs/playGui.gui

@@ -0,0 +1,50 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GameTSCtrl(PlayGui) {
+      cameraZRot = "0";
+      forceFOV = "0";
+      reflectPriority = "1";
+      renderStyle = "standard";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "0 0";
+      extent = "1920 1080";
+      minExtent = "8 8";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+         enabled = "1";
+         helpTag = "0";
+         noCursor = "1";
+
+   new GuiBitmapCtrl(LagIcon) {
+      bitmap = "data/ui/art/lagIcon.png";
+      color = "255 255 255 255";
+      wrap = "0";
+      position = "572 3";
+      extent = "32 32";
+      minExtent = "8 8";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiDefaultProfile";
+      visible = "0";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      hidden = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+};
+//--- OBJECT WRITE END ---

+ 14 - 0
Templates/BaseGame/game/data/gameUI/gameUI.cs

@@ -0,0 +1,14 @@
+function gameUI::create( %this )
+{
+   if (!$Server::Dedicated)
+   {
+      //guis
+      exec("./GUIs/playGui.gui");
+      exec("./GUIs/playGui.cs");
+   }
+}
+
+function gameUI::destroy( %this )
+{
+   
+}

+ 15 - 0
Templates/BaseGame/game/data/gameUI/gameUI.module

@@ -0,0 +1,15 @@
+<ModuleDefinition
+	ModuleId="gameUI"
+	VersionId="1"
+	Description="Basic Game GUI."
+	ScriptFile="gameUI.cs"
+	CreateFunction="create"
+	DestroyFunction="destroy"
+	Group="Game"
+	Dependencies="UI=1">
+	<DeclaredAssets
+        canSave="true"
+        canSaveDynamicFields="true"
+        Extension="asset.taml"
+        Recurse="true" />
+</ModuleDefinition>

+ 55 - 35
Templates/BaseGame/game/data/ui/UI.cs

@@ -19,56 +19,76 @@ function UI::create( %this )
    
    // Use our prefs to configure our Canvas/Window
    configureCanvas();
-   
+}
+
+function UI::destroy( %this )
+{
+}
+
+function UI::initServer(%this){}
+
+function UI::onCreateServer(%this){}
+
+function UI::onDestroyServer(%this){}
+
+function UI::initClient(%this)
+{
    //Load UI stuff
    //we need to load this because some of the menu profiles use the sounds here
-   exec("./scripts/datablocks/guiSounds.cs");
+   exec("./datablocks/guiSounds.cs");
    
    //Profiles
    exec("./scripts/profiles.cs");
    
    //Now gui files
-   exec("./scripts/guis/mainMenu.gui");
-   exec("./scripts/guis/chooseLevelDlg.gui");
-   exec("./scripts/guis/joinServerMenu.gui");
-   exec("./scripts/guis/loadingGui.gui");
-   exec("./scripts/guis/optionsMenu.gui");
-   exec("./scripts/guis/pauseMenu.gui");
-   exec("./scripts/guis/remapDlg.gui");
-   exec("./scripts/guis/remapConfirmDlg.gui");
-   
-   exec("./scripts/guis/profiler.gui");
-   exec("./scripts/guis/netGraphGui.gui");
-   exec("./scripts/guis/RecordingsDlg.gui");
-   exec("./scripts/guis/FileDialog.gui");
-   exec("./scripts/guis/guiMusicPlayer.gui");
-   exec("./scripts/guis/startupGui.gui");
-   
-   //Load gui companion scripts
-   exec("./scripts/chooseLevelDlg.cs");
+   exec("./guis/mainMenu.gui");
+   exec("./guis/mainMenu.cs");
+   
+   exec("./guis/chooseLevelDlg.gui");
+   exec("./guis/chooseLevelDlg.cs");
+   
+   exec("./guis/joinServerMenu.gui");
+   exec("./guis/joinServerMenu.cs");
+   
+   exec("./guis/loadingGui.gui");
+   
+   exec("./guis/optionsMenu.gui");
+   exec("./guis/optionsMenu.cs");
+   
+   exec("./guis/pauseMenu.gui");
+   exec("./guis/pauseMenu.cs");
+   
+   exec("./guis/remapDlg.gui");
+   exec("./guis/remapConfirmDlg.gui");
+   
+   exec("./guis/profiler.gui");
+   exec("./guis/profiler.cs");
+   
+   exec("./guis/netGraphGui.gui");
+   exec("./guis/RecordingsDlg.gui");
+   
+   //exec("./guis/FileDialog.gui");
+   //exec("./guis/FileDialog.cs");
+   
+   exec("./guis/guiMusicPlayer.gui");
+   exec("./guis/guiMusicPlayer.cs");
+   
+   exec("./guis/startupGui.gui");
+   exec("./guis/startupGui.cs");
+   
+   //Load scripts
    exec("./scripts/optionsList.cs");
-   exec("./scripts/optionsMenu.cs");
    exec("./scripts/graphicsMenu.cs");
    exec("./scripts/controlsMenu.cs");
-   exec("./scripts/chooseLevelDlg.cs");
-   exec("./scripts/mainMenu.cs");
-   exec("./scripts/joinServerMenu.cs");
-   exec("./scripts/pauseMenu.cs");
    exec("./scripts/messageBoxes.cs");
    exec("./scripts/help.cs");
    exec("./scripts/cursors.cs");
-   exec("./scripts/profiler.cs");
-   exec("./scripts/FileDialog.cs");
-   exec("./scripts/GuiTreeViewCtrl.cs");
-   exec("./scripts/guiMusicPlayer.cs");
-   exec("./scripts/startupGui.cs");
    
-   %dbList = new ArrayObject(LevelFilesList);
+   //exec("./scripts/GuiTreeViewCtrl.cs");
    
    loadStartup();
 }
 
-function Game::destroy( %this )
-{
-   
-}
+function UI::onCreateClientConnection(%this){}
+
+function UI::onDestroyClientConnection(%this){}

+ 34 - 0
Templates/BaseGame/game/data/ui/datablocks/guiSounds.cs

@@ -0,0 +1,34 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+singleton SFXProfile(menuButtonPressed)
+{
+   preload = true;
+   description = AudioGui;
+   fileName = "data/ui/sounds/buttonClick";
+};
+
+singleton SFXProfile(menuButtonHover)
+{
+   preload = true;
+   description = AudioGui;
+   fileName = "data/ui/sounds/buttonHover";
+};

+ 293 - 0
Templates/BaseGame/game/data/ui/guis/FileDialog.gui

@@ -0,0 +1,293 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(PlatformFileDialog) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+
+   new GuiWindowCtrl() {
+      text = "";
+      resizeWidth = "1";
+      resizeHeight = "1";
+      canMove = "1";
+      canClose = "1";
+      canMinimize = "1";
+      canMaximize = "1";
+      canCollapse = "0";
+      closeCommand = "PlatformFileDialog.cancel();";
+      edgeSnap = "1";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "135 113";
+      extent = "727 623";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiWindowProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      internalName = "window";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiControl() {
+         position = "2 16";
+         extent = "717 37";
+         minExtent = "8 2";
+         horizSizing = "width";
+         vertSizing = "bottom";
+         profile = "ToolsGuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "ToolsGuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiBitmapButtonCtrl() {
+            bitmap = "tools/gui/images/folderUp";
+            bitmapMode = "Stretched";
+            autoFitExtents = "0";
+            useModifiers = "0";
+            useStates = "1";
+            groupNum = "0";
+            buttonType = "PushButton";
+            useMouseEvents = "0";
+            position = "9 9";
+            extent = "20 19";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "ToolsGuiButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "PlatformFileDialog.navigateUp();";
+            tooltipProfile = "ToolsGuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "folderUpButton";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            maxLength = "1024";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "36 9";
+            extent = "666 18";
+            minExtent = "8 2";
+            horizSizing = "width";
+            vertSizing = "bottom";
+            profile = "ToolsGuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "ToolsGuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "PopupMenu";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+      };
+      new GuiScrollCtrl() {
+         willFirstRespond = "1";
+         hScrollBar = "dynamic";
+         vScrollBar = "alwaysOff";
+         lockHorizScroll = "0";
+         lockVertScroll = "1";
+         constantThumbHeight = "0";
+         childMargin = "0 0";
+         mouseWheelScrollSpeed = "-1";
+         docking = "None";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "0";
+         anchorBottom = "1";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "7 64";
+         extent = "712 509";
+         minExtent = "8 2";
+         horizSizing = "width";
+         vertSizing = "height";
+         profile = "GuiScrollProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "ToolsGuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiDynamicCtrlArrayControl() {
+            colCount = "1";
+            colSize = "64";
+            rowCount = "1";
+            rowSize = "258";
+            rowSpacing = "4";
+            colSpacing = "4";
+            frozen = "0";
+            autoCellSize = "1";
+            fillRowFirst = "0";
+            dynamicSize = "1";
+            padding = "0 0 0 0";
+            position = "1 1";
+            extent = "666 507";
+            minExtent = "8 2";
+            horizSizing = "width";
+            vertSizing = "height";
+            profile = "ToolsGuiTransparentProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "ToolsGuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            internalName = "itemArray";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+      };
+      new GuiContainer() {
+         docking = "Bottom";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "0";
+         anchorBottom = "1";
+         anchorLeft = "1";
+         anchorRight = "1";
+         position = "1 583";
+         extent = "725 37";
+         minExtent = "8 2";
+         horizSizing = "width";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiTextCtrl() {
+            text = "File Name";
+            maxLength = "1024";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "10 -1";
+            extent = "51 30";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextEditCtrl() {
+            historySize = "0";
+            tabComplete = "0";
+            sinkAllKeyEvents = "0";
+            password = "0";
+            passwordMask = "*";
+            maxLength = "1024";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "58 5";
+            extent = "561 18";
+            minExtent = "8 2";
+            horizSizing = "width";
+            vertSizing = "bottom";
+            profile = "GuiTextEditProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            internalName = "fileNameEdit";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiContainer() {
+            docking = "Right";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "0";
+            anchorBottom = "0";
+            anchorLeft = "0";
+            anchorRight = "0";
+            position = "630 0";
+            extent = "95 37";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiButtonCtrl() {
+               groupNum = "-1";
+               buttonType = "PushButton";
+               useMouseEvents = "1";
+               position = "6 1";
+               extent = "81 24";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiButtonProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "Button";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 159 - 0
Templates/BaseGame/game/data/ui/guis/IODropdownDlg.ed.gui

@@ -0,0 +1,159 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(IODropdownDlg) {
+	profile = "GuiDefaultProfile";
+	horizSizing = "width";
+	vertSizing = "height";
+	position = "0 0";
+	extent = "640 480";
+	minExtent = "8 8";
+	visible = "1";
+	helpTag = "0";
+   new GuiWindowCtrl(IODropdownFrame) {
+      canSaveDynamicFields = "0";
+      Profile = "GuiWindowProfile";
+      horizSizing = "center";
+      vertSizing = "center";
+      position = "272 77";
+      extent = "256 117";
+      minExtent = "256 8";
+      canSave = "1";
+      Visible = "1";
+      hovertime = "1000";
+      maxLength = "255";
+      resizeWidth = "1";
+      resizeHeight = "1";
+      canMove = "1";
+      canClose = "1";
+      canMinimize = "0";
+      canMaximize = "0";
+      minSize = "50 50";
+      text = "";
+      closeCommand="IOCallback(IODropdownDlg,IODropdownDlg.cancelCallback);";
+
+      new GuiMLTextCtrl(IODropdownText) {
+         text = "";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         isContainer = "0";
+         profile = "GuiMLTextProfile";
+         horizSizing = "center";
+         vertSizing = "bottom";
+         position = "9 26";
+         extent = "237 16";
+         minExtent = "8 8";
+         canSave = "1";
+         visible = "1";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         canSaveDynamicFields = "0";
+      };
+      new GuiBitmapBorderCtrl() {
+         isContainer = "0";
+         profile = "GuiGroupBorderProfile";
+         horizSizing = "width";
+         vertSizing = "bottom";
+         position = "7 51";
+         extent = "243 28";
+         minExtent = "0 0";
+         canSave = "1";
+         visible = "1";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         canSaveDynamicFields = "0";
+
+         new GuiTextCtrl(IOInputText) {
+            text = "Decal Datablock";
+            maxLength = "1024";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            isContainer = "0";
+            profile = "GuiTextRightProfile";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            position = "5 5";
+            extent = "105 18";
+            minExtent = "8 2";
+            canSave = "1";
+            visible = "1";
+            tooltipprofile = "GuiToolTipProfile";
+            hovertime = "1000";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl(IODropdownMenu) {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            maxLength = "1024";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            isContainer = "0";
+            profile = "GuiPopUpMenuProfile";
+            horizSizing = "width";
+            vertSizing = "bottom";
+            position = "115 5";
+            extent = "122 18";
+            minExtent = "8 2";
+            canSave = "1";
+            visible = "1";
+            tooltipprofile = "GuiToolTipProfile";
+            hovertime = "1000";
+            canSaveDynamicFields = "0";
+         };
+      };
+      new GuiButtonCtrl() {
+         text = "OK";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         isContainer = "0";
+         profile = "GuiButtonProfile";
+         horizSizing = "width";
+         vertSizing = "top";
+         position = "7 85";
+         extent = "156 24";
+         minExtent = "8 8";
+         canSave = "1";
+         visible = "1";
+         accelerator = "return";
+         command = "IOCallback(IODropdownDlg,IODropdownDlg.callback);";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         text = "Cancel";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         isContainer = "0";
+         profile = "GuiButtonProfile";
+         horizSizing = "left";
+         vertSizing = "top";
+         position = "170 85";
+         extent = "80 24";
+         minExtent = "8 8";
+         canSave = "1";
+         visible = "1";
+         accelerator = "escape";
+         command = "IOCallback(IODropdownDlg,IODropdownDlg.cancelCallback);";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 230 - 0
Templates/BaseGame/game/data/ui/guis/RecordingsDlg.gui

@@ -0,0 +1,230 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(recordingsDlg) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 8";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      helpTag = "0";
+
+   new GuiWindowCtrl() {
+      text = "Demo Recordings";
+      resizeWidth = "0";
+      resizeHeight = "0";
+      canMove = "1";
+      canClose = "1";
+      canMinimize = "0";
+      canMaximize = "0";
+      canCollapse = "0";
+      closeCommand = "Canvas.popDialog(recordingsDlg);";
+      edgeSnap = "1";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "247 215";
+      extent = "530 338";
+      minExtent = "48 92";
+      horizSizing = "center";
+      vertSizing = "center";
+      profile = "GuiWindowProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiScrollCtrl() {
+         willFirstRespond = "1";
+         hScrollBar = "dynamic";
+         vScrollBar = "alwaysOn";
+         lockHorizScroll = "0";
+         lockVertScroll = "0";
+         constantThumbHeight = "0";
+         childMargin = "0 0";
+         mouseWheelScrollSpeed = "-1";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "23 60";
+         extent = "484 237";
+         minExtent = "32 32";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiScrollProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiTextListCtrl(RecordingsDlgList) {
+            columns = "0";
+            fitParentWidth = "1";
+            clipColumnText = "0";
+            position = "1 1";
+            extent = "469 32";
+            minExtent = "8 20";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextArrayProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+      };
+      new GuiButtonCtrl(DR_CancelBtn) {
+         text = "Cancel";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "396 306";
+         extent = "110 20";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "top";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "Canvas.popDialog(recordingsDlg);";
+         accelerator = "escape";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(DR_StartDemoBtn) {
+         text = "Play";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "25 305";
+         extent = "110 20";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "top";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "StartSelectedDemo();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "During gameplay press the following keys:";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "23 30";
+         extent = "206 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Start = F3";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "253 32";
+         extent = "50 15";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Stop = F4";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "320 32";
+         extent = "49 13";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(DR_DelDemoBtn) {
+         text = "Delete";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "210 305";
+         extent = "110 20";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "deleteDemoRecord();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---
+

+ 374 - 0
Templates/BaseGame/game/data/ui/guis/chooseLevelDlg.cs

@@ -0,0 +1,374 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+//----------------------------------------
+function ChooseLevelDlg::onWake( %this )
+{
+   CL_levelList.clear();
+   ChooseLevelWindow->SmallPreviews.clear();
+   
+   %this->CurrentPreview.visible = false;
+   %this->levelName.visible = false;
+   %this->LevelDescriptionLabel.visible = false;
+   %this->LevelDescription.visible = false;
+   
+   %assetQuery = new AssetQuery();
+   AssetDatabase.findAssetType(%assetQuery, "LevelAsset");
+      
+   %count = %assetQuery.getCount();
+   
+   if(%count == 0 && !IsDirectory("tools"))
+   {
+      //We have no levels found. Prompt the user to open the editor to the default level if the tools are present
+      MessageBoxOK("Error", "No levels were found in any modules. Please ensure you have modules loaded that contain gameplay code and level files.", 
+         "Canvas.popDialog(ChooseLevelDlg); if(isObject(ChooseLevelDlg.returnGui) && ChooseLevelDlg.returnGui.isMethod(\"onReturnTo\")) ChooseLevelDlg.returnGui.onReturnTo();");
+         
+      %assetQuery.delete();
+      return;
+   }
+   
+   for(%i=0; %i < %count; %i++)
+	{
+	   %assetId = %assetQuery.getAsset(%i);
+      
+      %levelAsset = AssetDatabase.acquireAsset(%assetId);
+      
+      %file = %levelAsset.LevelFile;
+      
+      if ( !isFile(%file @ ".mis") && !isFile(%file) )
+         continue;
+         
+      // Skip our new level/mission if we arent choosing a level
+      // to launch in the editor.
+      if ( !%this.launchInEditor )
+      {
+         %fileName = fileName(%file);
+         if (strstr(%fileName, "newMission.mis") > -1 || strstr(%fileName, "newLevel.mis") > -1)
+            continue;      
+      }
+                  
+      %this.addLevelAsset( %levelAsset );
+   }
+   
+   // Also add the new level mission as defined in the world editor settings
+   // if we are choosing a level to launch in the editor.
+   if ( %this.launchInEditor )
+   {
+      %file = EditorSettings.value( "WorldEditor/newLevelFile" );
+      if ( %file !$= "" )
+         %this.addMissionFile( %file );
+   }
+
+   // Sort our list
+   CL_levelList.sort(0);
+
+   // Set the first row as the selected row
+   CL_levelList.setSelectedRow(0);
+
+   for (%i = 0; %i < CL_levelList.rowCount(); %i++)
+   {
+      %preview = new GuiButtonCtrl() {
+         profile = "GuiMenuButtonProfile";
+         internalName = "SmallPreview" @ %i;
+         Extent = "368 35";
+         text = getField(CL_levelList.getRowText(%i), 0);
+         command = "ChooseLevelWindow.previewSelected(ChooseLevelWindow->SmallPreviews->SmallPreview" @ %i @ ");";
+         buttonType = "RadioButton";
+      };
+
+      ChooseLevelWindow->SmallPreviews.add(%preview);
+      
+      %rowText = CL_levelList.getRowText(%i);
+
+      // Set the level index
+      %preview.levelIndex = %i;
+
+      // Get the name
+      %name = getField(CL_levelList.getRowText(%i), 0);
+
+      %preview.levelName = %name;
+
+      %file = getField(CL_levelList.getRowText(%i), 1);
+
+      // Find the preview image
+      %levelPreview = getField(CL_levelList.getRowText(%i), 3);
+
+      // Test against all of the different image formats
+      // This should probably be moved into an engine function
+      if (isFile(%levelPreview @ ".png") ||
+          isFile(%levelPreview @ ".jpg") ||
+          isFile(%levelPreview @ ".bmp") ||
+          isFile(%levelPreview @ ".gif") ||
+          isFile(%levelPreview @ ".jng") ||
+          isFile(%levelPreview @ ".mng") ||
+          isFile(%levelPreview @ ".tga"))
+      {
+         %preview.bitmap = %levelPreview;
+      }
+
+      // Get the description
+      %desc = getField(CL_levelList.getRowText(%i), 2);
+
+      %preview.levelDesc = %desc;
+   }
+
+   ChooseLevelWindow->SmallPreviews.firstVisible = -1;
+   ChooseLevelWindow->SmallPreviews.lastVisible = -1;
+
+   if (ChooseLevelWindow->SmallPreviews.getCount() > 0)
+   {
+      ChooseLevelWindow->SmallPreviews.firstVisible = 0;
+
+      if (ChooseLevelWindow->SmallPreviews.getCount() < 6)
+         ChooseLevelWindow->SmallPreviews.lastVisible = ChooseLevelWindow->SmallPreviews.getCount() - 1;
+      else
+         ChooseLevelWindow->SmallPreviews.lastVisible = 4;
+   }
+
+   if (ChooseLevelWindow->SmallPreviews.getCount() > 0)
+      ChooseLevelWindow.previewSelected(ChooseLevelWindow->SmallPreviews.getObject(0));
+
+   // If we have 5 or less previews then hide our next/previous buttons
+   // and resize to fill their positions
+   if (ChooseLevelWindow->SmallPreviews.getCount() < 6)
+   {
+      ChooseLevelWindow->PreviousSmallPreviews.setVisible(false);
+      ChooseLevelWindow->NextSmallPreviews.setVisible(false);
+
+      %previewPos = ChooseLevelWindow->SmallPreviews.getPosition();
+      %previousPos = ChooseLevelWindow->PreviousSmallPreviews.getPosition();
+
+      %previewPosX = getWord(%previousPos, 0);
+      %previewPosY = getWord(%previewPos,  1);
+
+      ChooseLevelWindow->SmallPreviews.setPosition(%previewPosX, %previewPosY);
+
+      ChooseLevelWindow->SmallPreviews.colSpacing = 10;//((getWord(NextSmallPreviews.getPosition(), 0)+11)-getWord(PreviousSmallPreviews.getPosition(), 0))/4;
+      ChooseLevelWindow->SmallPreviews.refresh();
+   }
+
+   /*if (ChooseLevelWindow->SmallPreviews.getCount() <= 1)
+   {
+      // Hide the small previews
+      ChooseLevelWindow->SmallPreviews.setVisible(false);
+
+      // Shrink the ChooseLevelWindow so that we don't have a large blank space
+      %extentX = getWord(ChooseLevelWindow.getExtent(), 0);
+      %extentY = getWord(ChooseLevelWindow->SmallPreviews.getPosition(), 1);
+
+      ChooseLevelWIndow.setExtent(%extentX, %extentY);
+   }
+   else
+   {
+      // Make sure the small previews are visible
+      ChooseLevelWindow->SmallPreviews.setVisible(true);
+
+      %extentX = getWord(ChooseLevelWindow.getExtent(), 0);
+      
+      %extentY = getWord(ChooseLevelWindow->SmallPreviews.getPosition(), 1);
+      %extentY = %extentY + getWord(ChooseLevelWindow->SmallPreviews.getExtent(), 1);
+      %extentY = %extentY + 9;
+
+      //ChooseLevelWIndow.setExtent(%extentX, %extentY);
+   //}*/
+}
+
+function ChooseLevelDlg::addMissionFile( %this, %file )
+{
+   %levelName = fileBase(%file);
+   %levelDesc = "A Torque level";
+
+   %LevelInfoObject = getLevelInfo(%file);
+
+   if (%LevelInfoObject != 0)
+   {
+      if(%LevelInfoObject.levelName !$= "")
+         %levelName = %LevelInfoObject.levelName;
+      else if(%LevelInfoObject.name !$= "")
+         %levelName = %LevelInfoObject.name;
+
+      if (%LevelInfoObject.desc0 !$= "")
+         %levelDesc = %LevelInfoObject.desc0;
+         
+      if (%LevelInfoObject.preview !$= "")
+         %levelPreview = %LevelInfoObject.preview;
+         
+      %LevelInfoObject.delete();
+   }
+
+   CL_levelList.addRow( CL_levelList.rowCount(), %levelName TAB %file TAB %levelDesc TAB %levelPreview );
+}
+
+function ChooseLevelDlg::addLevelAsset( %this, %levelAsset )
+{
+   %file = %levelAsset.LevelFile;
+   
+   /*%levelName = fileBase(%file);
+   %levelDesc = "A Torque level";
+
+   %LevelInfoObject = getLevelInfo(%file);
+
+   if (%LevelInfoObject != 0)
+   {
+      if(%LevelInfoObject.levelName !$= "")
+         %levelName = %LevelInfoObject.levelName;
+      else if(%LevelInfoObject.name !$= "")
+         %levelName = %LevelInfoObject.name;
+
+      if (%LevelInfoObject.desc0 !$= "")
+         %levelDesc = %LevelInfoObject.desc0;
+         
+      if (%LevelInfoObject.preview !$= "")
+         %levelPreview = %LevelInfoObject.preview;
+         
+      %LevelInfoObject.delete();
+   }*/
+   
+   %levelName = %levelAsset.LevelName;
+   %levelDesc = %levelAsset.description;
+   %levelPreview = %levelAsset.levelPreviewImage;
+   
+   CL_levelList.addRow( CL_levelList.rowCount(), %levelName TAB %file TAB %levelDesc TAB %levelPreview );
+}
+
+function ChooseLevelDlg::onSleep( %this )
+{
+   // This is set from the outside, only stays true for a single wake/sleep
+   // cycle.
+   %this.launchInEditor = false;
+}
+
+function ChooseLevelWindow::previewSelected(%this, %preview)
+{
+   // Set the selected level
+   if (isObject(%preview) && %preview.levelIndex !$= "")
+      CL_levelList.setSelectedRow(%preview.levelIndex);
+   else
+      CL_levelList.setSelectedRow(-1);
+
+   // Set the large preview image
+   if (isObject(%preview) && %preview.bitmap !$= "")
+   {
+      %this->CurrentPreview.visible = true;
+      %this->CurrentPreview.setBitmap(%preview.bitmap);
+   }
+   else
+   {
+      %this->CurrentPreview.visible = false;
+   }
+
+   // Set the current level name
+   if (isObject(%preview) && %preview.levelName !$= "")
+   {
+      %this->LevelName.visible = true;
+      %this->LevelName.setText(%preview.levelName);
+   }
+   else
+   {
+      %this->LevelName.visible = false;
+   }
+
+   // Set the current level description
+   if (isObject(%preview) && %preview.levelDesc !$= "")
+   {
+      %this->LevelDescription.visible = true;
+      %this->LevelDescriptionLabel.visible = true;
+      %this->LevelDescription.setText(%preview.levelDesc);
+   }
+   else
+   {
+      %this->LevelDescription.visible = false;
+      %this->LevelDescriptionLabel.visible = false;
+   }
+}
+
+function ChooseLevelWindow::previousPreviews(%this)
+{
+   %prevHiddenIdx = %this->SmallPreviews.firstVisible - 1;
+
+   if (%prevHiddenIdx < 0)
+      return;
+
+   %lastVisibleIdx = %this->SmallPreviews.lastVisible;
+
+   if (%lastVisibleIdx >= %this->SmallPreviews.getCount())
+      return;
+
+   %prevHiddenObj  = %this->SmallPreviews.getObject(%prevHiddenIdx);
+   %lastVisibleObj = %this->SmallPreviews.getObject(%lastVisibleIdx);
+
+   if (isObject(%prevHiddenObj) && isObject(%lastVisibleObj))
+   {
+      %this->SmallPreviews.firstVisible--;
+      %this->SmallPreviews.lastVisible--;
+
+      %prevHiddenObj.setVisible(true);
+      %lastVisibleObj.setVisible(false);
+   }
+}
+
+function ChooseLevelWindow::nextPreviews(%this)
+{
+   %firstVisibleIdx = %this->SmallPreviews.firstVisible;
+
+   if (%firstVisibleIdx < 0)
+      return;
+
+   %firstHiddenIdx = %this->SmallPreviews.lastVisible + 1;
+
+   if (%firstHiddenIdx >= %this->SmallPreviews.getCount())
+      return;
+
+   %firstVisibleObj = %this->SmallPreviews.getObject(%firstVisibleIdx);
+   %firstHiddenObj  = %this->SmallPreviews.getObject(%firstHiddenIdx);
+
+   if (isObject(%firstVisibleObj) && isObject(%firstHiddenObj))
+   {
+      %this->SmallPreviews.firstVisible++;
+      %this->SmallPreviews.lastVisible++;
+
+      %firstVisibleObj.setVisible(false);
+      %firstHiddenObj.setVisible(true);
+   }
+}
+
+// Do this onMouseUp not via Command which occurs onMouseDown so we do
+// not have a lingering mouseUp event lingering in the ether.
+function ChooseLevelDlgGoBtn::onMouseUp( %this )
+{
+   // So we can't fire the button when loading is in progress.
+   if ( isObject( ServerGroup ) )
+      return;
+
+   // Launch the chosen level with the editor open?
+   if ( ChooseLevelDlg.launchInEditor )
+   {
+      activatePackage( "BootEditor" );
+      ChooseLevelDlg.launchInEditor = false; 
+      StartGame("", "SinglePlayer");
+   }
+   else
+   {
+      StartGame(); 
+   }
+}
+

+ 272 - 0
Templates/BaseGame/game/data/ui/guis/chooseLevelDlg.gui

@@ -0,0 +1,272 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(ChooseLevelDlg) {
+   position = "0 0";
+   extent = "1280 1024";
+   minExtent = "8 8";
+   horizSizing = "width";
+   vertSizing = "height";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      enabled = "1";
+      launchInEditor = "0";
+      returnGui = "MainMenuGui";
+
+   new GuiControl(ChooseLevelWindow) {
+      position = "80 36";
+      extent = "770 616";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiBitmapCtrl() {
+         bitmap = "data/ui/images/no-preview";
+         color = "255 255 255 255";
+         wrap = "0";
+         position = "369 31";
+         extent = "400 300";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "0";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "CurrentPreview";
+         hidden = "1";
+         canSave = "1";
+         canSaveDynamicFields = "1";
+            enabled = "1";
+      };
+      new GuiTextCtrl() {
+         text = "Empty Room";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "370 335";
+         extent = "90 18";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "0";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "levelName";
+         hidden = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Description:";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "370 354";
+         extent = "91 18";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "0";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "LevelDescriptionLabel";
+         hidden = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiMLTextCtrl() {
+         lineSpacing = "2";
+         allowColorChars = "0";
+         maxChars = "-1";
+         useURLMouseCursor = "0";
+         position = "370 380";
+         extent = "165 14";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMLWhiteTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "LevelDescription";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiBitmapButtonCtrl() {
+         bitmap = "data/ui/images/previous-button";
+         bitmapMode = "Stretched";
+         autoFitExtents = "0";
+         useModifiers = "0";
+         useStates = "1";
+         masked = "0";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "2 -1";
+         extent = "368 33";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "0";
+         active = "1";
+         command = "ChooseLevelWindow.previousPreviews();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "PreviousSmallPreviews";
+         hidden = "1";
+         canSave = "1";
+         canSaveDynamicFields = "1";
+            enabled = "1";
+            wrap = "0";
+      };
+      new GuiBitmapButtonCtrl() {
+         bitmap = "data/ui/images/next-button";
+         bitmapMode = "Stretched";
+         autoFitExtents = "0";
+         useModifiers = "0";
+         useStates = "1";
+         masked = "0";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "-3 549";
+         extent = "374 33";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "0";
+         active = "1";
+         command = "ChooseLevelWindow.nextPreviews();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "NextSmallPreviews";
+         hidden = "1";
+         canSave = "1";
+         canSaveDynamicFields = "1";
+            enabled = "1";
+            wrap = "0";
+      };
+      new GuiTextListCtrl(CL_levelList) {
+         columns = "0";
+         fitParentWidth = "1";
+         clipColumnText = "0";
+         position = "-7 1";
+         extent = "80 30";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextArrayProfile";
+         visible = "0";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         hidden = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiDynamicCtrlArrayControl() {
+         colCount = "1";
+         colSize = "368";
+         rowCount = "14";
+         rowSize = "35";
+         rowSpacing = "0";
+         colSpacing = "10";
+         frozen = "0";
+         autoCellSize = "1";
+         fillRowFirst = "0";
+         dynamicSize = "0";
+         padding = "0 0 0 0";
+         position = "2 33";
+         extent = "368 516";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "SmallPreviews";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(ChooseLevelDlgGoBtn) {
+         text = "Start Level";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "1";
+         position = "371 583";
+         extent = "399 33";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(ChooseLevelDlgBackBtn) {
+         text = "Return to Menu";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "1";
+         position = "0 583";
+         extent = "371 33";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "Canvas.popDialog(ChooseLevelDlg);\n\nif(isObject(ChooseLevelDlg.returnGui) && ChooseLevelDlg.returnGui.isMethod(\"onReturnTo\"))    ChooseLevelDlg.returnGui.onReturnTo();";
+         accelerator = "escape";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 102 - 0
Templates/BaseGame/game/data/ui/guis/controlsMenuSetting.taml

@@ -0,0 +1,102 @@
+<GuiContainer
+    margin="0 0 0 0"
+    padding="0 0 0 0"
+    anchorTop="true"
+    anchorBottom="false"
+    anchorLeft="true"
+    anchorRight="false"
+    position="0 0"
+    extent="700 35"
+    minExtent="8 2"
+    horizSizing="right"
+    vertSizing="bottom"
+    profile="GuiDefaultProfile"
+    visible="true"
+    active="true"
+    tooltipProfile="GuiToolTipProfile"
+    hovertime="1000"
+    isContainer="true"
+    class="GraphicsMenuSetting"
+    canSave="true"
+    canSaveDynamicFields="false">
+    <GuiBitmapCtrl
+        bitmap="data/ui/images/hudfill.png"
+        wrap="false"
+        position="0 0"
+        extent="550 35"
+        minExtent="8 2"
+        horizSizing="right"
+        vertSizing="bottom"
+        profile="GuiDefaultProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="false"
+        canSave="true"
+        canSaveDynamicFields="false" />
+    <GuiTextCtrl
+        text="Move Forward"
+        maxLength="1024"
+        margin="0 0 0 0"
+        padding="0 0 0 0"
+        anchorTop="true"
+        anchorBottom="false"
+        anchorLeft="true"
+        anchorRight="false"
+        position="0 0"
+        extent="550 35"
+        minExtent="8 2"
+        horizSizing="right"
+        vertSizing="bottom"
+        profile="GuiMenuButtonProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="true"
+        internalName="nameText"
+        canSave="true"
+        canSaveDynamicFields="false" />
+    <GuiContainer
+        margin="0 0 0 0"
+        padding="0 0 0 0"
+        anchorTop="true"
+        anchorBottom="false"
+        anchorLeft="true"
+        anchorRight="false"
+        position="550 0"
+        extent="150 35"
+        minExtent="8 2"
+        horizSizing="right"
+        vertSizing="bottom"
+        profile="GuiDefaultProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="true"
+        canSave="true"
+        canSaveDynamicFields="false">
+        <GuiButtonCtrl
+            text="W"
+            groupNum="-1"
+            buttonType="PushButton"
+            useMouseEvents="true"
+            position="0 0"
+            extent="150 35"
+            minExtent="8 8"
+            horizSizing="relative"
+            vertSizing="bottom"
+            profile="GuiMenuButtonProfile"
+            visible="true"
+            active="true"
+            tooltipProfile="GuiToolTipProfile"
+            hovertime="1000"
+            isContainer="false"
+            canSave="true"
+            canSaveDynamicFields="false"
+            internalName="rebindButton"
+            className="ControlsMenuRebindButton"/>
+    </GuiContainer>
+</GuiContainer>

+ 123 - 0
Templates/BaseGame/game/data/ui/guis/graphicsMenuSettingsCtrl.taml

@@ -0,0 +1,123 @@
+<GuiContainer
+    margin="0 0 0 0"
+    padding="0 0 0 0"
+    anchorTop="true"
+    anchorBottom="false"
+    anchorLeft="true"
+    anchorRight="false"
+    position="0 105"
+    extent="739 35"
+    minExtent="8 2"
+    horizSizing="width"
+    vertSizing="bottom"
+    profile="GuiDefaultProfile"
+    visible="true"
+    active="true"
+    tooltipProfile="GuiToolTipProfile"
+    hovertime="1000"
+    isContainer="true"
+    class="GraphicsMenuSetting"
+    canSave="true"
+    canSaveDynamicFields="false">
+    <GuiBitmapCtrl
+        bitmap="data/ui/images/hudfill.png"
+        color="255 255 255 255"
+        wrap="false"
+        position="0 0"
+        extent="739 35"
+        minExtent="8 2"
+        horizSizing="relative"
+        vertSizing="bottom"
+        profile="GuiDefaultProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="false"
+        canSave="true"
+        canSaveDynamicFields="false" />
+    <GuiTextCtrl
+        text="Shadow Quality"
+        maxLength="1024"
+        margin="0 0 0 0"
+        padding="0 0 0 0"
+        anchorTop="true"
+        anchorBottom="false"
+        anchorLeft="true"
+        anchorRight="false"
+        position="0 0"
+        extent="350 35"
+        minExtent="8 2"
+        horizSizing="relative"
+        vertSizing="bottom"
+        profile="GuiMenuButtonProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="true"
+        internalName="nameText"
+        canSave="true"
+        canSaveDynamicFields="false" />
+    <GuiTextCtrl
+        text="High"
+        maxLength="1024"
+        margin="0 0 0 0"
+        padding="0 0 0 0"
+        anchorTop="true"
+        anchorBottom="false"
+        anchorLeft="true"
+        anchorRight="false"
+        position="350 0"
+        extent="350 35"
+        minExtent="8 2"
+        horizSizing="relative"
+        vertSizing="bottom"
+        profile="GuiMenuButtonProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="true"
+        internalName="SettingText"
+        canSave="true"
+        canSaveDynamicFields="false" />
+    <GuiButtonCtrl
+        text=">"
+        groupNum="-1"
+        buttonType="PushButton"
+        useMouseEvents="true"
+        position="682 0"
+        extent="36 35"
+        minExtent="8 8"
+        horizSizing="relative"
+        vertSizing="bottom"
+        profile="GuiMenuButtonProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="false"
+        class="OptionsMenuForwardSetting"
+        canSave="true"
+        canSaveDynamicFields="false" />
+    <GuiButtonCtrl
+        text="<"
+        groupNum="-1"
+        buttonType="PushButton"
+        useMouseEvents="true"
+        position="348 0"
+        extent="36 35"
+        minExtent="8 8"
+        horizSizing="relative"
+        vertSizing="bottom"
+        profile="GuiMenuButtonProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="false"
+        class="OptionsMenuBackSetting"
+        canSave="true"
+        canSaveDynamicFields="false" />
+</GuiContainer>

+ 142 - 0
Templates/BaseGame/game/data/ui/guis/graphicsMenuSettingsSlider.taml

@@ -0,0 +1,142 @@
+<GuiContainer
+    margin="0 0 0 0"
+    padding="0 0 0 0"
+    anchorTop="true"
+    anchorBottom="false"
+    anchorLeft="true"
+    anchorRight="false"
+    position="0 35"
+    extent="700 35"
+    minExtent="8 2"
+    horizSizing="right"
+    vertSizing="bottom"
+    profile="GuiDefaultProfile"
+    visible="true"
+    active="true"
+    tooltipProfile="GuiToolTipProfile"
+    hovertime="1000"
+    isContainer="true"
+    canSave="true"
+    canSaveDynamicFields="false">
+    <GuiBitmapCtrl
+        bitmap="data/ui/images/hudfill.png"
+        wrap="false"
+        position="0 0"
+        extent="450 35"
+        minExtent="8 2"
+        horizSizing="right"
+        vertSizing="bottom"
+        profile="GuiDefaultProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="false"
+        canSave="true"
+        canSaveDynamicFields="false" />
+    <GuiContainer
+        margin="0 0 0 0"
+        padding="0 0 0 0"
+        anchorTop="true"
+        anchorBottom="false"
+        anchorLeft="true"
+        anchorRight="false"
+        position="450 0"
+        extent="250 35"
+        minExtent="8 2"
+        horizSizing="right"
+        vertSizing="bottom"
+        profile="GuiDefaultProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="true"
+        canSave="true"
+        canSaveDynamicFields="false">
+        <GuiBitmapCtrl
+            bitmap="data/ui/images/hudfill.png"
+            wrap="false"
+            position="0 0"
+            extent="250 35"
+            minExtent="8 2"
+            horizSizing="right"
+            vertSizing="bottom"
+            profile="GuiDefaultProfile"
+            visible="true"
+            active="true"
+            tooltipProfile="GuiToolTipProfile"
+            hovertime="1000"
+            isContainer="false"
+            canSave="true"
+            canSaveDynamicFields="false" />
+        <GuiSliderCtrl
+            range="0.1 1"
+            ticks="9"
+            snap="false"
+            value="0.453571"
+            position="0 0"
+            extent="200 35"
+            minExtent="8 2"
+            horizSizing="right"
+            vertSizing="bottom"
+            profile="GuiSliderProfile"
+            visible="true"
+            active="true"
+            variable="$pref::Input::VertMouseSensitivity"
+            tooltipProfile="GuiToolTipProfile"
+            hovertime="1000"
+            isContainer="false"
+            internalName="slider"
+            canSave="true"
+            canSaveDynamicFields="false" 
+            renderTicks="false"
+            useFillBar="true" />
+        <GuiTextCtrl
+            text="5"
+            maxLength="1024"
+            margin="0 0 0 0"
+            padding="0 0 0 0"
+            anchorTop="true"
+            anchorBottom="false"
+            anchorLeft="true"
+            anchorRight="false"
+            position="200 0"
+            extent="50 35"
+            minExtent="8 2"
+            horizSizing="right"
+            vertSizing="bottom"
+            profile="GuiMenuButtonProfile"
+            visible="true"
+            active="true"
+            tooltipProfile="GuiToolTipProfile"
+            hovertime="1000"
+            isContainer="true"
+            internalName="valueText"
+            canSave="true"
+            canSaveDynamicFields="false" />
+    </GuiContainer>
+    <GuiTextCtrl
+        text="Vertical Sensitivity"
+        maxLength="1024"
+        margin="0 0 0 0"
+        padding="0 0 0 0"
+        anchorTop="true"
+        anchorBottom="false"
+        anchorLeft="true"
+        anchorRight="false"
+        position="0 0"
+        extent="450 35"
+        minExtent="8 2"
+        horizSizing="right"
+        vertSizing="bottom"
+        profile="GuiMenuButtonProfile"
+        visible="true"
+        active="true"
+        tooltipProfile="GuiToolTipProfile"
+        hovertime="1000"
+        isContainer="true"
+        internalName="nameText"
+        canSave="true"
+        canSaveDynamicFields="false" />
+</GuiContainer>

+ 244 - 0
Templates/BaseGame/game/data/ui/guis/guiMusicPlayer.cs

@@ -0,0 +1,244 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// A very simple music player.
+
+//---------------------------------------------------------------------------------------------
+// Prerequisites.
+
+if( !isObject( GuiMusicPlayer ) )
+   exec( "./guiMusicPlayer.gui" );
+
+//---------------------------------------------------------------------------------------------
+// Preferences.
+
+$pref::GuiMusicPlayer::filePattern = "*.ogg\t*.wav";
+$pref::GuiMusicPlayer::filePatternFMOD = "*.aiff\t*.asf\t*.flac\t*.it\t*.mid\t*.mod\t*.mp2\t*.mp3\t*.ogg\t*.s3m\t*.vag\t*.wav\t*.wma\t*.xm";
+$pref::GuiMusicPlayer::fadeTime = "3.0";
+
+//---------------------------------------------------------------------------------------------
+// Datablocks.
+
+singleton SFXDescription( GuiMusicPlayerStream : AudioMusic2D )
+{
+   volume = 1.0;
+   isLooping = false;
+   isStreaming = true;
+   is3D = false;
+};
+singleton SFXDescription( GuiMusicPlayerLoopingStream : AudioMusic2D )
+{
+   volume = 1.0;
+   isLooping = true;
+   isStreaming = true;
+   is3D = false;
+};
+
+//---------------------------------------------------------------------------------------------
+// Functions.
+
+function toggleMusicPlayer()
+{   
+   if( !GuiMusicPlayer.isAwake() )
+   {
+      GuiMusicPlayer.setExtent( Canvas.getExtent() );
+      GuiMusicPlayer.setPosition( 0, 0 );
+      
+      Canvas.pushDialog( GuiMusicPlayer );
+   }
+   else
+      Canvas.popDialog( GuiMusicPlayer );
+}
+
+//---------------------------------------------------------------------------------------------
+// Methods.
+
+function GuiMusicPlayer_onSFXSourceStatusChange( %id, %status )
+{
+   if( %status $= "Stopped" )
+      GuiMusicPlayer.onStop();
+}
+
+function GuiMusicPlayerClass::play( %this )
+{
+   if( %this.status $= "Stopped"
+       || %this.status $= "Paused"
+       || %this.status $= "" )
+   {
+      %isPlaying = true;
+      if( %this.status $= "Paused" && isObject( %this.sfxSource ) )
+         %this.sfxSource.play();
+      else
+      {
+         %sel = GuiMusicPlayerMusicList.getSelectedItem();
+         if( %sel == -1 )
+            %isPlaying = false;
+         else
+         {
+            %desc = GuiMusicPlayerStream;
+            if( GuiMusicPlayerLoopCheckBox.getValue() )
+               %desc = GuiMusicPlayerLoopingStream;
+               
+            if( GuiMusicPlayerFadeCheckBox.getValue() )
+            {
+               %desc.fadeInTime = $pref::GuiMusicPlayer::fadeTime;
+               %desc.fadeOutTime = $pref::GuiMusicPlayer::fadeTime;
+            }
+            else
+            {
+               %desc.fadeInTime = 0;
+               %desc.fadeOutTime = 0;
+            }
+               
+            %file = GuiMusicPlayerMusicList.getItemText( %sel );
+            %this.sfxSource = sfxPlayOnce( %desc, %file );
+            if( !%this.sfxSource )
+               %isPlaying = false;
+            else
+            {
+               %this.sfxSource.statusCallback = "GuiMusicPlayer_onSFXSourceStatusChange";
+               GuiMusicPlayer.status = "Playing";
+               
+               GuiMusicPlayerScrubber.setActive( true );
+               GuiMusicPlayerScrubber.setup( %this.sfxSource.getDuration() );
+            }
+         }
+      }
+      
+      if( %isPlaying )
+      {
+         GuiMusicPlayerPlayButton.setText( "Pause" );
+         GuiMusicPlayerPlayButton.command = "GuiMusicPlayer.pause();";
+         GuiMusicPlayerLoopCheckBox.setActive( false );
+         GuiMusicPlayerFadeCheckBox.setActive( false );
+         %this.status = "Playing";
+      }
+   }
+}
+
+function GuiMusicPlayerClass::stop( %this )
+{
+   if( %this.status $= "Playing"
+       || %this.status $= "Paused" )
+   {
+      if( isObject( %this.sfxSource ) )
+         %this.sfxSource.stop( 0 ); // Stop immediately.
+   }
+}
+
+function GuiMusicPlayerClass::onStop( %this )
+{
+   %this.sfxSource = 0;
+
+   GuiMusicPlayerLoopCheckBox.setActive( true );
+   GuiMusicPlayerFadeCheckBox.setActive( true );
+   GuiMusicPlayerScrubber.setActive( false );
+   GuiMusicPlayerPlayButton.setText( "Play" );
+   GuiMusicPlayerPlayButton.Command = "GuiMusicPlayer.play();";
+   %this.status = "Stopped";
+   
+   GuiMusicPlayerScrubber.setValue( 0 );   
+}
+
+function GuiMusicPlayerClass::pause( %this )
+{
+   if( %this.status $= "Playing" )
+   {
+      if( isObject( %this.sfxSource ) )
+         %this.sfxSource.pause( 0 );
+         
+      GuiMusicPlayerPlayButton.setText( "Play" );
+      GuiMusicPlayerPlayButton.command = "GuiMusicPlayer.play();";
+      %this.status = "Paused";
+   }
+}
+
+function GuiMusicPlayerClass::seek( %this, %playtime )
+{
+   if( ( %this.status $= "Playing"
+         || %this.status $= "Paused" )
+       && isObject( %this.sfxSource ) )
+      %this.sfxSource.setPosition( %playtime );
+}
+
+function GuiMusicPlayer::onWake( %this )
+{
+   GuiMusicPlayerMusicList.load();
+}
+
+function GuiMusicPlayerMusicListClass::load( %this )
+{
+   // Remove all the files currently in the list.
+   
+   %this.clearItems();
+   
+   // Find the file matching pattern we should use.
+   
+   %filePattern = $pref::GuiMusicPlayer::filePattern;
+   %sfxProvider = getWord( sfxGetDeviceInfo(), 0 );
+   %filePatternVarName = "$pref::GuiMusicPlayer::filePattern" @ %sfxProvider;
+   if( isDefined( %filePatternVarName ) )
+      eval( "%filePattern = " @ %filePatternVarName @ ";" );
+      
+   // Find all files matching the pattern.
+      
+   for( %file = findFirstFileMultiExpr( %filePattern );
+        %file !$= "";
+        %file = findNextFileMultiExpr( %filePattern ) )
+      %this.addItem( makeRelativePath( %file, getMainDotCsDir() ) );
+}
+
+function GuiMusicPlayerMusicList::onDoubleClick( %this )
+{
+   GuiMusicPlayer.stop();
+   GuiMusicPlayer.play();
+}
+
+function GuiMusicPlayerScrubber::onMouseDragged( %this )
+{
+   %this.isBeingDragged = true;
+}
+
+function GuiMusicPlayerScrubberClass::setup( %this, %totalPlaytime )
+{
+   %this.range = "0 " @ %totalPlaytime;
+   %this.ticks = %totalPlaytime / 5; // One tick per five seconds.
+   
+   %this.update();
+}
+
+function GuiMusicPlayerScrubberClass::update( %this )
+{   
+   if( GuiMusicPlayer.status $= "Playing"
+       && !%this.isBeingDragged )
+      %this.setValue( GuiMusicPlayer.sfxSource.getPosition() );
+
+   if( GuiMusicPlayer.status $= "Playing"
+       || GuiMusicPlayer.status $= "Paused" )
+      %this.schedule( 5, "update" );
+}
+
+function GuiMusicPlayerScrubberClass::onDragComplete( %this )
+{
+   GuiMusicPlayer.seek( %this.getValue() );
+   %this.isBeingDragged = false;
+}

+ 192 - 0
Templates/BaseGame/game/data/ui/guis/guiMusicPlayer.gui

@@ -0,0 +1,192 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(GuiMusicPlayer) {
+   isContainer = "1";
+   Profile = "GuiWindowProfile";
+   HorizSizing = "right";
+   VertSizing = "bottom";
+   position = "0 0";
+   Extent = "1024 768";
+   MinExtent = "8 2";
+   canSave = "1";
+   Visible = "1";
+   tooltipprofile = "GuiToolTipProfile";
+   hovertime = "1000";
+   canSaveDynamicFields = "1";
+   superClass = "GuiMusicPlayerClass";
+
+   new GuiWindowCtrl() {
+      resizeWidth = "0";
+      resizeHeight = "0";
+      canMove = "1";
+      canClose = "1";
+      canMinimize = "1";
+      canMaximize = "1";
+      minSize = "50 50";
+      EdgeSnap = "1";
+      text = "Torque Music Player";
+      Margin = "0 0 0 0";
+      Padding = "0 0 0 0";
+      AnchorTop = "1";
+      AnchorBottom = "0";
+      AnchorLeft = "1";
+      AnchorRight = "0";
+      isContainer = "1";
+      Profile = "GuiWindowProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      position = "29 35";
+      Extent = "518 377";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      tooltipprofile = "GuiToolTipProfile";
+      hovertime = "1000";
+      canSaveDynamicFields = "0";
+      closeCommand = "toggleMusicPlayer();";
+
+      new GuiCheckBoxCtrl(GuiMusicPlayerFadeCheckBox) {
+         useInactiveState = "0";
+         text = "Fade";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         isContainer = "0";
+         Profile = "GuiCheckBoxProfile";
+         HorizSizing = "right";
+         VertSizing = "bottom";
+         position = "457 347";
+         Extent = "53 30";
+         MinExtent = "8 2";
+         canSave = "1";
+         Visible = "1";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         canSaveDynamicFields = "0";
+      };
+      new GuiCheckBoxCtrl(GuiMusicPlayerLoopCheckBox) {
+         useInactiveState = "0";
+         text = "Loop";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         isContainer = "0";
+         Profile = "GuiCheckBoxProfile";
+         HorizSizing = "right";
+         VertSizing = "bottom";
+         position = "457 330";
+         Extent = "44 30";
+         MinExtent = "8 2";
+         canSave = "1";
+         Visible = "1";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         canSaveDynamicFields = "0";
+      };
+      new GuiScrollCtrl() {
+         willFirstRespond = "1";
+         hScrollBar = "dynamic";
+         vScrollBar = "alwaysOn";
+         lockHorizScroll = "0";
+         lockVertScroll = "0";
+         constantThumbHeight = "0";
+         childMargin = "0 0";
+         mouseWheelScrollSpeed = "-1";
+         Margin = "0 0 0 0";
+         Padding = "0 0 0 0";
+         AnchorTop = "1";
+         AnchorBottom = "0";
+         AnchorLeft = "1";
+         AnchorRight = "0";
+         isContainer = "1";
+         Profile = "GuiScrollProfile";
+         HorizSizing = "right";
+         VertSizing = "bottom";
+         position = "9 31";
+         Extent = "500 298";
+         MinExtent = "8 2";
+         canSave = "1";
+         Visible = "1";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         canSaveDynamicFields = "0";
+
+         new GuiListBoxCtrl(GuiMusicPlayerMusicList) {
+            AllowMultipleSelections = "1";
+            fitParentWidth = "1";
+            isContainer = "0";
+            Profile = "GuiListBoxProfile";
+            HorizSizing = "right";
+            VertSizing = "bottom";
+            position = "1 1";
+            Extent = "485 2";
+            MinExtent = "8 2";
+            canSave = "1";
+            Visible = "1";
+            tooltipprofile = "GuiToolTipProfile";
+            hovertime = "1000";
+            canSaveDynamicFields = "0";
+            superClass = "GuiMusicPlayerMusicListClass";
+         };
+      };
+      new GuiSliderCtrl(GuiMusicPlayerScrubber) {
+         range = "0 1";
+         ticks = "10";
+         value = "0";
+         snap = "false";
+         isContainer = "0";
+         Profile = "GuiSliderProfile";
+         HorizSizing = "right";
+         VertSizing = "bottom";
+         position = "114 343";
+         Extent = "331 23";
+         MinExtent = "8 2";
+         canSave = "1";
+         Visible = "1";
+         Command = "$thisControl.onDragComplete();";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         canSaveDynamicFields = "0";
+         class = "GuiMusicPlayerScrubberClass";
+         className = "GuiMusicPlayerScrubberClass";
+      };
+      new GuiButtonCtrl(GuiMusicPlayerStopButton) {
+         text = "Stop";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         isContainer = "0";
+         Profile = "GuiButtonProfile";
+         HorizSizing = "right";
+         VertSizing = "bottom";
+         position = "57 338";
+         Extent = "40 30";
+         MinExtent = "8 2";
+         canSave = "1";
+         Visible = "1";
+         Command = "GuiMusicPlayer.stop();";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(GuiMusicPlayerPlayButton) {
+         text = "Play";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         isContainer = "0";
+         Profile = "GuiButtonProfile";
+         HorizSizing = "right";
+         VertSizing = "bottom";
+         position = "13 338";
+         Extent = "40 30";
+         MinExtent = "8 2";
+         canSave = "1";
+         Visible = "1";
+         Command = "GuiMusicPlayer.play();";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 143 - 0
Templates/BaseGame/game/data/ui/guis/joinServerMenu.cs

@@ -0,0 +1,143 @@
+
+function JoinServerMenu::onWake()
+{
+   // Double check the status. Tried setting this the control
+   // inactive to start with, but that didn't seem to work.
+   JoinServerJoinBtn.setActive(JS_serverList.rowCount() > 0);
+}   
+
+//----------------------------------------
+function JoinServerMenu::query(%this)
+{
+   queryMasterServer(
+      0,          // Query flags
+      $Client::GameTypeQuery,       // gameTypes
+      $Client::MissionTypeQuery,    // missionType
+      0,          // minPlayers
+      100,        // maxPlayers
+      0,          // maxBots
+      2,          // regionMask
+      0,          // maxPing
+      100,        // minCPU
+      0           // filterFlags
+   );
+}
+
+//----------------------------------------
+function JoinServerMenu::queryLan(%this)
+{
+   queryLANServers(
+      $pref::Net::Port,      // lanPort for local queries
+      0,          // Query flags
+      $Client::GameTypeQuery,       // gameTypes
+      $Client::MissionTypeQuery,    // missionType
+      0,          // minPlayers
+      100,        // maxPlayers
+      0,          // maxBots
+      2,          // regionMask
+      0,          // maxPing
+      100,        // minCPU
+      0           // filterFlags
+   );
+}
+
+//----------------------------------------
+function JoinServerMenu::cancel(%this)
+{
+   cancelServerQuery();
+   JS_queryStatus.setVisible(false);
+}
+
+
+//----------------------------------------
+function JoinServerMenu::join(%this)
+{
+   cancelServerQuery();
+   %index = JS_serverList.getSelectedId();
+
+   JoinGame(%index);
+}
+
+//----------------------------------------
+function JoinServerMenu::refresh(%this)
+{
+   cancelServerQuery();
+   %index= JS_serverList.getSelectedId();
+
+   // The server info index is stored in the row along with the
+   // rest of displayed info.
+   if( setServerInfo( %index ) )
+      querySingleServer( $ServerInfo::Address, 0 );
+}
+
+//----------------------------------------
+function JoinServerMenu::refreshSelectedServer( %this )
+{
+   querySingleServer( $JoinGameAddress, 0 );
+}
+
+//----------------------------------------
+function JoinServerMenu::exit(%this)
+{
+   cancelServerQuery();
+   
+   Canvas.popDialog(JoinServerMenu);
+}
+
+//----------------------------------------
+function JoinServerMenu::update(%this)
+{
+   // Copy the servers into the server list.
+   JS_queryStatus.setVisible(false);
+   JS_serverList.clear();
+   %sc = getServerCount();
+   for( %i = 0; %i < %sc; %i ++ ) {
+      setServerInfo(%i);
+      JS_serverList.addRow( %i,
+         $ServerInfo::Name TAB
+         $ServerInfo::Ping TAB
+         $ServerInfo::PlayerCount @ "/" @ $ServerInfo::MaxPlayers TAB
+         $ServerInfo::Version TAB
+         $ServerInfo::MissionName
+      );
+   }
+   JS_serverList.sort(0);
+   JS_serverList.setSelectedRow(0);
+   JS_serverList.scrollVisible(0);
+
+   JoinServerJoinBtn.setActive(JS_serverList.rowCount() > 0);
+} 
+
+//----------------------------------------
+function onServerQueryStatus(%status, %msg, %value)
+{
+	echo("ServerQuery: " SPC %status SPC %msg SPC %value);
+   // Update query status
+   // States: start, update, ping, query, done
+   // value = % (0-1) done for ping and query states
+   if (!JS_queryStatus.isVisible())
+      JS_queryStatus.setVisible(true);
+
+   switch$ (%status) {
+      case "start":
+         JoinServerJoinBtn.setActive(false);
+         JoinServerQryInternetBtn.setActive(false);
+         JS_statusText.setText(%msg);
+         JS_statusBar.setValue(0);
+         JS_serverList.clear();
+
+      case "ping":
+         JS_statusText.setText("Ping Servers");
+         JS_statusBar.setValue(%value);
+
+      case "query":
+         JS_statusText.setText("Query Servers");
+         JS_statusBar.setValue(%value);
+
+      case "done":
+         JoinServerQryInternetBtn.setActive(true);
+         JS_queryStatus.setVisible(false);
+         JS_status.setText(%msg);
+         JoinServerMenu.update();
+   }
+}

+ 455 - 0
Templates/BaseGame/game/data/ui/guis/joinServerMenu.gui

@@ -0,0 +1,455 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(JoinServerMenu) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+
+   new GuiControl(JoinServerWindow) {
+      position = "80 36";
+      extent = "800 616";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiTextCtrl(JS_status) {
+         text = "No servers found.";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "277 31";
+         extent = "148 18";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiScrollCtrl() {
+         willFirstRespond = "1";
+         hScrollBar = "dynamic";
+         vScrollBar = "alwaysOn";
+         lockHorizScroll = "0";
+         lockVertScroll = "0";
+         constantThumbHeight = "0";
+         childMargin = "0 0";
+         mouseWheelScrollSpeed = "-1";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "10 80";
+         extent = "780 461";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuScrollProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiTextListCtrl(JS_serverList) {
+            columns = "0 200 270 335 400";
+            fitParentWidth = "1";
+            clipColumnText = "0";
+            position = "1 1";
+            extent = "762 8";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextArrayProfile";
+            visible = "1";
+            active = "1";
+            altCommand = "JoinServerDlg.join();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+      };
+      new GuiTextEditCtrl() {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "116 31";
+         extent = "144 18";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         variable = "$pref::Player::Name";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Player Name:";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "12 31";
+         extent = "98 18";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Players";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "269 59";
+         extent = "36 18";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMLWhiteTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Version";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "335 59";
+         extent = "38 18";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMLWhiteTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Game";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "412 59";
+         extent = "28 18";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMLWhiteTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Ping";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "212 59";
+         extent = "20 18";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMLWhiteTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Server Name";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "12 59";
+         extent = "63 18";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMLWhiteTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiControl(JS_queryStatus) {
+         position = "10 541";
+         extent = "778 35";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "0";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         hidden = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiProgressCtrl(JS_statusBar) {
+            maxLength = "1024";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "84 0";
+            extent = "695 35";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiProgressProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl(JS_cancelQuery) {
+            text = "Cancel!";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "0";
+            position = "0 0";
+            extent = "84 35";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "JoinServerDlg.cancel();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl(JS_statusText) {
+            text = "Querying master server";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "84 0";
+            extent = "695 35";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+      };
+      new GuiButtonCtrl(JoinServerBackBtn) {
+         text = "Return to Menu";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "1";
+         position = "0 583";
+         extent = "160 33";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "Canvas.popDialog(JoinServerMenu);\n\nif(isObject(JoinServerMenu.returnGui) && JoinServerMenu.returnGui.isMethod(\"onReturnTo\"))    JoinServerMenu.returnGui.onReturnTo();";
+         accelerator = "escape";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(JoinServerQryLanBtn) {
+         text = "Query Lan";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "1";
+         position = "160 583";
+         extent = "160 33";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "JoinServerMenu.queryLan();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(JoinServerQryInternetBtn) {
+         text = "Query Internet";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "1";
+         position = "320 583";
+         extent = "160 33";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "JoinServerMenu.query();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(JoinServerRefreshBtn) {
+         text = "Refresh Server";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "1";
+         position = "480 583";
+         extent = "160 33";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "JoinServerMenu.refresh();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(JoinServerJoinBtn) {
+         text = "Join Server";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "1";
+         position = "640 583";
+         extent = "160 33";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "0";
+         command = "JoinServerMenu.join();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 102 - 0
Templates/BaseGame/game/data/ui/guis/loadingGui.gui

@@ -0,0 +1,102 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiChunkedBitmapCtrl(LoadingGui) {
+   bitmap = "data/ui/images/background-dark.png";
+   useVariable = "0";
+   tile = "0";
+   position = "0 0";
+   extent = "1600 838";
+   minExtent = "8 8";
+   horizSizing = "width";
+   vertSizing = "height";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      Enabled = "1";
+
+   new GuiControl() {
+      position = "391 429";
+      extent = "497 166";
+      minExtent = "8 8";
+      horizSizing = "center";
+      vertSizing = "center";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      command = "disconnect();\nCanvas.setContent(ProjectSettings.value(\"UI/mainMenuName\"));";
+      accelerator = "escape";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiBitmapCtrl(LoadingLogo) {
+         bitmap = "data/ui/images/Torque-3D-logo.png";
+         wrap = "0";
+         position = "27 6";
+         extent = "443 139";
+         minExtent = "8 2";
+         horizSizing = "center";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiProgressBitmapCtrl(LoadingProgress) {
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "17 126";
+         extent = "464 24";
+         minExtent = "8 2";
+         horizSizing = "center";
+         vertSizing = "bottom";
+         profile = "GuiProgressBitmapProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl(LoadingProgressTxt) {
+         text = "LOADING DATABLOCKS";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "28 144";
+         extent = "440 20";
+         minExtent = "8 8";
+         horizSizing = "center";
+         vertSizing = "bottom";
+         profile = "GuiMenuTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 41 - 0
Templates/BaseGame/game/data/ui/guis/mainMenu.cs

@@ -0,0 +1,41 @@
+function MainMenuGui::onWake(%this)
+{
+   if (isFunction("getWebDeployment") &&
+       getWebDeployment() &&
+       isObject(%this-->ExitButton))
+      %this-->ExitButton.setVisible(false);
+      
+   MainMenuButtonContainer.hidden = false;
+}
+
+function MainMenuGui::openSinglePlayerMenu(%this)
+{
+   $pref::HostMultiPlayer=false;
+   Canvas.pushDialog(ChooseLevelDlg);
+   ChooseLevelDlg.returnGui = %this; 
+   MainMenuButtonContainer.hidden = true; 
+   MainMenuAppLogo.setBitmap("data/ui/images/Torque-3D-logo");
+}
+
+function MainMenuGui::openMultiPlayerMenu(%this)
+{
+   $pref::HostMultiPlayer=true;
+   Canvas.pushDialog(ChooseLevelDlg);
+   ChooseLevelDlg.returnGui = %this; 
+   MainMenuButtonContainer.hidden = true; 
+   MainMenuAppLogo.setBitmap("data/ui/images/Torque-3D-logo");
+}
+
+function MainMenuGui::openOptionsMenu(%this)
+{
+   Canvas.pushDialog(OptionsMenu);
+   OptionsMenu.returnGui = %this; 
+   MainMenuButtonContainer.hidden = true; 
+   MainMenuAppLogo.setBitmap("data/ui/images/Torque-3D-logo");
+}
+
+function MainMenuGui::onReturnTo(%this)
+{
+   MainMenuButtonContainer.hidden = false;
+   MainMenuAppLogo.setBitmap("data/ui/images/Torque-3D-logo-shortcut");
+}

+ 234 - 0
Templates/BaseGame/game/data/ui/guis/mainMenu.gui

@@ -0,0 +1,234 @@
+exec( "tools/gui/profiles.ed.cs" );
+
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) {
+   bitmap = "data/ui/images/BackgroundImage.png";
+   useVariable = "0";
+   tile = "0";
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 8";
+   horizSizing = "width";
+   vertSizing = "height";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      Enabled = "1";
+      isDecoy = "0";
+
+   new GuiBitmapButtonCtrl(MainMenuAppLogo) {
+      bitmap = "data/ui/images/Torque-3D-logo-shortcut";
+      bitmapMode = "Stretched";
+      autoFitExtents = "0";
+      useModifiers = "0";
+      useStates = "1";
+      masked = "0";
+      groupNum = "-1";
+      buttonType = "PushButton";
+      useMouseEvents = "0";
+      position = "550 30";
+      extent = "443 139";
+      minExtent = "8 2";
+      horizSizing = "left";
+      vertSizing = "bottom";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      command = "gotoWebPage(\"forums.torque3d.org\");";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   new GuiControl(MainMenuButtonContainer) {
+      position = "20 193";
+      extent = "442 381";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "center";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiDynamicCtrlArrayControl() {
+         colCount = "1";
+         colSize = "442";
+         rowCount = "9";
+         rowSize = "40";
+         rowSpacing = "0";
+         colSpacing = "0";
+         frozen = "0";
+         autoCellSize = "1";
+         fillRowFirst = "0";
+         dynamicSize = "0";
+         padding = "0 0 0 0";
+         position = "0 0";
+         extent = "442 381";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiButtonCtrl() {
+            text = "Singleplayer";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "1";
+            position = "0 0";
+            extent = "442 40";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "MainMenuGui.openSinglePlayerMenu();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl() {
+            text = "Create Server";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "0";
+            position = "0 40";
+            extent = "442 40";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "MainMenuGui.openMultiPlayerMenu();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl() {
+            text = "Join Server";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "0";
+            position = "0 80";
+            extent = "442 40";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "Canvas.pushDialog(JoinServerMenu);";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl() {
+            text = "Options";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "0";
+            position = "0 120";
+            extent = "442 40";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "MainMenuGui.openOptionsMenu();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl() {
+            text = "Launch World Editor";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "0";
+            position = "0 160";
+            extent = "442 40";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "fastLoadWorldEdit(1);";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl() {
+            text = "Launch GUI Editor";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "0";
+            position = "0 200";
+            extent = "442 40";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "fastLoadGUIEdit(1);";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl() {
+            text = "Exit";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "0";
+            position = "0 240";
+            extent = "442 40";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "quit();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "ExitButton";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 60 - 0
Templates/BaseGame/game/data/ui/guis/messageBoxOK.gui

@@ -0,0 +1,60 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(MessageBoxOKDlg) {
+   profile = "GuiOverlayProfile";
+   horizSizing = "width";
+   vertSizing = "height";
+   position = "0 0";
+   extent = "640 480";
+   minExtent = "8 8";
+   visible = "1";
+   helpTag = "0";
+
+   new GuiWindowCtrl(MBOKFrame) {
+      profile = "GuiWindowProfile";
+      horizSizing = "center";
+      vertSizing = "center";
+      position = "170 175";
+      extent = "300 107";
+      minExtent = "48 95";
+      visible = "1";
+      helpTag = "0";
+      maxLength = "255";
+      resizeWidth = "1";
+      resizeHeight = "1";
+      canMove = "1";
+      canClose = "0";
+      canMinimize = "0";
+      canMaximize = "0";
+      minSize = "50 50";
+      text = "";
+
+      new GuiMLTextCtrl(MBOKText) {
+         profile = "GuiMLTextProfile";
+         horizSizing = "center";
+         vertSizing = "bottom";
+         position = "9 35";
+         extent = "281 24";
+         minExtent = "8 8";
+         visible = "1";
+         helpTag = "0";
+         lineSpacing = "2";
+         allowColorChars = "0";
+         maxChars = "-1";
+      };
+      new GuiButtonCtrl() {
+         profile = "GuiButtonProfile";
+         horizSizing = "right";
+         vertSizing = "top";
+         position = "111 75";
+         extent = "80 24";
+         minExtent = "8 8";
+         visible = "1";
+         command = "MessageCallback(MessageBoxOKDlg,MessageBoxOKDlg.callback);";
+         accelerator = "return";
+         helpTag = "0";
+         text = "Ok";
+            simpleStyle = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 75 - 0
Templates/BaseGame/game/data/ui/guis/messageBoxYesNo.gui

@@ -0,0 +1,75 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(MessageBoxYesNoDlg) {
+	profile = "GuiOverlayProfile";
+	horizSizing = "width";
+	vertSizing = "height";
+	position = "0 0";
+	extent = "640 480";
+	minExtent = "8 8";
+	visible = "1";
+	helpTag = "0";
+
+	new GuiWindowCtrl(MBYesNoFrame) {
+      profile = "GuiWindowProfile";
+      horizSizing = "center";
+      vertSizing = "center";
+      position = "170 175";
+      extent = "300 100";
+      minExtent = "48 92";
+      visible = "1";
+      helpTag = "0";
+      maxLength = "255";
+      resizeWidth = "1";
+      resizeHeight = "1";
+      canMove = "1";
+      canClose = "1";
+      canMinimize = "0";
+      canMaximize = "0";
+      minSize = "50 50";
+      text = "";
+      closeCommand = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.noCallback);";
+
+		new GuiMLTextCtrl(MBYesNoText) {
+         profile = "GuiMLTextProfile";
+         horizSizing = "center";
+         vertSizing = "bottom";
+         position = "11 38";
+         extent = "280 14";
+         minExtent = "8 8";
+         visible = "1";
+         helpTag = "0";
+         lineSpacing = "2";
+         allowColorChars = "0";
+         maxChars = "-1";
+		};
+		new GuiButtonCtrl() {
+         profile = "GuiButtonProfile";
+         horizSizing = "right";
+         vertSizing = "top";
+         position = "70 68";
+         extent = "80 22";
+         minExtent = "8 8";
+         visible = "1";
+			command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.yesCallback);";
+         accelerator = "return";
+         helpTag = "0";
+         text = "Yes";
+         simpleStyle = "0";
+		};
+		new GuiButtonCtrl() {
+         profile = "GuiButtonProfile";
+         horizSizing = "right";
+         vertSizing = "top";
+         position = "167 68";
+         extent = "80 22";
+         minExtent = "8 8";
+         visible = "1";
+			command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.noCallback);";
+         accelerator = "escape";
+         helpTag = "0";
+         text = "No";
+         simpleStyle = "0";
+		};
+	};
+};
+//--- OBJECT WRITE END ---

+ 557 - 0
Templates/BaseGame/game/data/ui/guis/netGraphGui.gui

@@ -0,0 +1,557 @@
+function execNetGraphGuiGUI()
+{
+   if ( isObject( NetGraphGui ) )
+      NetGraphGui.delete();
+ 
+   if ( isObject( NetGraphProfile ) )
+      NetGraphProfile.delete();
+           
+   if ( isObject( NetGraphGhostsActiveProfile ) )
+      NetGraphGhostsActiveProfile.delete();
+      
+   if ( isObject( NetGraphGhostUpdatesProfile ) )
+      NetGraphGhostUpdatesProfile.delete();
+   
+   if ( isObject( NetGraphBitsSentProfile ) )
+      NetGraphBitsSentProfile.delete();
+      
+   if ( isObject( NetGraphBitsReceivedProfile ) )
+      NetGraphBitsReceivedProfile.delete();
+      
+   if ( isObject( NetGraphLatencyProfile ) )
+      NetGraphLatencyProfile.delete();
+      
+   if ( isObject( NetGraphPacketLossProfile ) )
+      NetGraphPacketLossProfile.delete();
+      
+   exec( "./NetGraphGui.gui" );  
+}
+
+// Profiles
+new GuiControlProfile (NetGraphProfile)
+{
+   modal = false;
+   opaque = false;
+   canKeyFocus = false;
+};
+
+new GuiControlProfile (NetGraphKeyContainerProfile)
+{
+   border = true;
+   opaque = true;
+   fillColor = "100 100 100 200";
+};
+new GuiControlProfile (NetGraphGhostsActiveProfile)
+{
+   border = false;
+   fontColor = "255 255 255";
+};
+new GuiControlProfile (NetGraphGhostUpdatesProfile)
+{
+   border = false;
+   fontColor = "255 0 0";
+};
+new GuiControlProfile (NetGraphBitsSentProfile)
+{
+   border = false;
+   fontColor = "0 255 0";
+};
+new GuiControlProfile (NetGraphBitsReceivedProfile)
+{
+   border = false;
+   fontColor = "0 0 255";
+};
+new GuiControlProfile (NetGraphLatencyProfile)
+{
+   border = false;
+   fontColor = "0 255 255";
+};
+new GuiControlProfile (NetGraphPacketLossProfile)
+{
+   border = false;
+   fontColor = "0 0 0";
+};
+
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(NetGraphGui) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 2";
+   horizSizing = "left";
+   vertSizing = "bottom";
+   profile = "NetGraphProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      noCursor = "1";
+
+   new GuiGraphCtrl(NetGraph) {
+      centerY = "1";
+      plotColor[0] = "1 1 1 1";
+      plotColor[1] = "1 0 0 1";
+      plotColor[2] = "0 1 0 1";
+      plotColor[3] = "0 0 1 1";
+      plotColor[4] = "0 1 1 1";
+      plotColor[5] = "0 0 0 1";
+      plotType[0] = "PolyLine";
+      plotType[1] = "PolyLine";
+      plotType[2] = "PolyLine";
+      plotType[3] = "PolyLine";
+      plotType[4] = "PolyLine";
+      plotType[5] = "PolyLine";
+      plotInterval[0] = "0";
+      plotInterval[1] = "0";
+      plotInterval[2] = "0";
+      plotInterval[3] = "0";
+      plotInterval[4] = "0";
+      plotInterval[5] = "0";
+      position = "816 5";
+      extent = "200 200";
+      minExtent = "8 2";
+      horizSizing = "left";
+      vertSizing = "bottom";
+      profile = "NetGraphKeyContainerProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiControl() {
+      position = "816 205";
+      extent = "200 104";
+      minExtent = "8 2";
+      horizSizing = "left";
+      vertSizing = "bottom";
+      profile = "NetGraphKeyContainerProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiTextCtrl(GhostsActive) {
+         text = "Ghosts Active";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "0 0";
+         extent = "100 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphGhostsActiveProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl(GhostUpdates) {
+         text = "Ghost Updates";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "100 0";
+         extent = "100 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphGhostUpdatesProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl(BitsSent) {
+         text = "Bytes Sent";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "0 18";
+         extent = "100 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphBitsSentProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl(BitsReceived) {
+         text = "Bytes Received";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "100 18";
+         extent = "100 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphBitsReceivedProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl(Latency) {
+         text = "Latency";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "0 36";
+         extent = "100 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphLatencyProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl(PacketLoss) {
+         text = "Packet Loss";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "100 36";
+         extent = "59 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphPacketLossProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Network Simulation:";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "0 52";
+         extent = "97 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphPacketLossProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Simulated Latency:";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "0 68";
+         extent = "91 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphPacketLossProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "ms";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "179 68";
+         extent = "20 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphPacketLossProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextEditCtrl(NetGraphSimLatency) {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         text = "0";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "112 67";
+         extent = "64 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Simulated Packet Loss:";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "0 83";
+         extent = "111 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphPacketLossProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "%";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "179 84";
+         extent = "20 18";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "bottom";
+         profile = "NetGraphPacketLossProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextEditCtrl(NetGraphSimPacket) {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         text = "0";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "112 85";
+         extent = "64 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         command = "if(NetGraphSimLatency.text $= \"\" || NetGraphSimLatency.text  < 0)\n{\n   NetGraphSimLatency.text = 0;\n}\n\nif(NetGraphSimPacket.text $= \"\" || NetGraphSimPacket.text  < 0)\n{\n   NetGraphSimLatency.text = 0;\n}\nelse if(NetGraphSimPacket.text > 100)\n{\n   NetGraphSimPacket.text = 100;\n}\n\nnetSimulateLag( NetGraphSimLatency.text, NetGraphSimPacket.text );";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---
+
+// Functions
+function toggleNetGraph()
+{
+    if(!$NetGraph::isInitialized)
+    {
+        NetGraph::updateStats();
+        $NetGraph::isInitialized = true;
+    }
+
+    if(!Canvas.isMember(NetGraphGui))
+    {
+        Canvas.add(NetGraphGui);
+    }
+    else
+    {
+      Canvas.remove(NetGraphGui);
+      netSimulateLag( 0, 0 ); 
+    }
+}
+
+function NetGraph::updateStats()
+{
+  $NetGraphThread = NetGraph.schedule(32, "updateStats");
+
+  if(!$Stats::netGhostUpdates)
+     return;
+
+  if(isobject(NetGraph))
+  {
+    if(isobject(ServerConnection))
+        NetGraph.addDatum(0,ServerConnection.getGhostsActive());
+    GhostsActive.setText("Ghosts Active: " @ ServerConnection.getGhostsActive());
+    NetGraph.addDatum(1,$Stats::netGhostUpdates);
+    GhostUpdates.setText("Ghost Updates: " @ $Stats::netGhostUpdates);
+    NetGraph.addDatum(2,$Stats::netBitsSent);
+    BitsSent.setText("Bytes Sent: " @ $Stats::netBitsSent);
+    NetGraph.addDatum(3,$Stats::netBitsReceived);
+    BitsReceived.setText("Bytes Received: " @ $Stats::netBitsReceived);
+    NetGraph.matchScale(2,3);
+    NetGraph.addDatum(4,ServerConnection.getPing());
+    Latency.setText("Latency: " @ ServerConnection.getPing());
+    NetGraph.addDatum(5,ServerConnection.getPacketLoss());
+    PacketLoss.setText("Packet Loss: " @ ServerConnection.getPacketLoss());
+  }
+}
+
+function NetGraph::toggleKey()
+{
+  if(!GhostsActive.visible)
+  {
+    GhostsActive.visible = 1;
+    GhostUpdates.visible = 1;
+    BitsSent.visible = 1;
+    BitsReceived.visible = 1;
+    Latency.visible = 1;
+    PacketLoss.visible = 1;
+  }
+  else
+  {
+    GhostsActive.visible = 0;
+    GhostUpdates.visible = 0;
+    BitsSent.visible = 0;
+    BitsReceived.visible = 0;
+    Latency.visible = 0;
+    PacketLoss.visible = 0;
+  }
+}
+
+function NetGraphSimLatency::onReturn(%this)
+{
+   NetGraph.updateNetworkSimulation();
+}
+
+function NetGraphSimPacket::onReturn(%this)
+{
+   NetGraph.updateNetworkSimulation();
+}
+
+function NetGraph::updateNetworkSimulation(%this)
+{
+   %latency = NetGraphSimLatency.getText();
+   
+   if(%latency $= "" || %latency  < 0)
+   {
+      NetGraphSimLatency.text = 0;
+      %latency = 0;
+   }
+   
+   %packetLoss = NetGraphSimPacket.getText();
+   
+   if(%packetLoss $= "" || %packetLoss  < 0)
+   {
+      NetGraphSimLatency.text = 0;
+      %packetLoss = 0;
+   }
+   else if(%packetLoss > 100)
+   {
+      NetGraphSimPacket.text = 100;
+      %packetLoss = 100;
+   }
+   
+   netSimulateLag( %latency, %packetLoss );
+}

+ 1417 - 0
Templates/BaseGame/game/data/ui/guis/optionsDlg.gui

@@ -0,0 +1,1417 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(OptionsDlg) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 8";
+   horizSizing = "width";
+   vertSizing = "height";
+   profile = "GuiOverlayProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      fixedAspectRatio = "0";
+
+   new GuiWindowCtrl() {
+      text = "Options";
+      resizeWidth = "0";
+      resizeHeight = "0";
+      canMove = "1";
+      canClose = "1";
+      canMinimize = "0";
+      canMaximize = "0";
+      canCollapse = "0";
+      closeCommand = "Canvas.popDialog(optionsDlg);";
+      edgeSnap = "0";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "323 232";
+      extent = "377 303";
+      minExtent = "8 8";
+      horizSizing = "center";
+      vertSizing = "center";
+      profile = "GuiWindowProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiButtonCtrl() {
+         text = "Done";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "306 271";
+         extent = "60 23";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "Canvas.popDialog(optionsDlg);";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiBitmapBorderCtrl() {
+         position = "9 55";
+         extent = "358 210";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTabBorderProfile";
+         visible = "0";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "OptControlsPane";
+         hidden = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiScrollCtrl() {
+            willFirstRespond = "1";
+            hScrollBar = "alwaysOff";
+            vScrollBar = "alwaysOn";
+            lockHorizScroll = "1";
+            lockVertScroll = "0";
+            constantThumbHeight = "0";
+            childMargin = "0 0";
+            mouseWheelScrollSpeed = "-1";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "5 24";
+            extent = "347 152";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiScrollProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiTextListCtrl() {
+               columns = "0 160";
+               fitParentWidth = "1";
+               clipColumnText = "0";
+               position = "1 1";
+               extent = "329 780";
+               minExtent = "8 8";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               altCommand = "OptionsDlg.doRemap();";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "1";
+               internalName = "OptRemapList";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+         new GuiTextCtrl() {
+            text = "Control Name";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "6 6";
+            extent = "64 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Control Binding";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "165 6";
+            extent = "72 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+		 
+         new GuiSliderCtrl(OptMouseSensitivity) {  
+            range = "0.02 2";  
+            ticks = "10";  
+            value = "0.75";  
+            isContainer = "0";  
+            Profile = "GuiSliderProfile";  
+            HorizSizing = "right";  
+            VertSizing = "bottom";  
+            position = "105 182";  
+            Extent = "244 18";  
+            MinExtent = "8 2";  
+            canSave = "1";  
+            Visible = "1";  
+            Command = "OptMouseSetSensitivity(OptMouseSensitivity.value);";  
+            tooltipprofile = "GuiToolTipProfile";  
+            hovertime = "1000";  
+            canSaveDynamicFields = "0";  
+         };  
+         new GuiTextCtrl() {  
+            text = "Mouse Sensitivity:"; 
+            maxLength = "255";  
+            Margin = "0 0 0 0";  
+            Padding = "0 0 0 0";  
+            AnchorTop = "1";  
+            AnchorBottom = "0";  
+            AnchorLeft = "1";  
+            AnchorRight = "0";  
+            isContainer = "0";  
+            Profile = "GuiTextProfile";  
+            HorizSizing = "right";  
+            VertSizing = "bottom";  
+            position = "15 182";  
+            Extent = "85 18";  
+            MinExtent = "8 8";  
+            canSave = "1";  
+            Visible = "1";  
+            tooltipprofile = "GuiToolTipProfile";  
+            hovertime = "1000";  
+            canSaveDynamicFields = "0";  
+         };  
+      };
+      new GuiBitmapBorderCtrl() {
+         position = "9 55";
+         extent = "358 210";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTabBorderProfile";
+         visible = "0";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "OptAudioPane";
+         hidden = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiMLTextCtrl() {
+            lineSpacing = "2";
+            allowColorChars = "0";
+            maxChars = "-1";
+            useURLMouseCursor = "0";
+            position = "149 10";
+            extent = "190 14";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiMLTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptAudioInfo";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Audio Provider:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "16 16";
+            extent = "75 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl(OptAudioProviderList) {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            text = "Null";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "101 15";
+            extent = "240 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Audio Device:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "23 48";
+            extent = "75 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl(OptAudioDeviceList) {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            text = "SFX Null Device";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "101 47";
+            extent = "240 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiControl() {
+            position = "18 84";
+            extent = "325 17";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiTextCtrl() {
+               text = "Master Volume";
+               maxLength = "255";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "0 0";
+               extent = "72 18";
+               minExtent = "8 8";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiAutoSizeTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiSliderCtrl() {
+               range = "0 1";
+               ticks = "0";
+               snap = "0";
+               value = "0.8";
+               position = "85 1";
+               extent = "240 14";
+               minExtent = "8 8";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiSliderProfile";
+               visible = "1";
+               active = "1";
+               altCommand = "OptAudioUpdateMasterVolume( $thisControl.value );";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "OptAudioVolumeMaster";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+         new GuiControl() {
+            position = "9 115";
+            extent = "334 17";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiTextCtrl() {
+               text = "Interface Volume";
+               maxLength = "255";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "0 0";
+               extent = "82 18";
+               minExtent = "8 8";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiAutoSizeTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiSliderCtrl() {
+               range = "0 1";
+               ticks = "0";
+               snap = "0";
+               value = "1";
+               position = "94 2";
+               extent = "240 13";
+               minExtent = "8 8";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiSliderProfile";
+               visible = "1";
+               active = "1";
+               altCommand = "OptAudioUpdateChannelVolume(AudioGui, $thisControl.value);";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "OptAudioVolumeShell";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+         new GuiControl() {
+            position = "18 146";
+            extent = "325 17";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiTextCtrl() {
+               text = "Effects Volume";
+               maxLength = "255";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "0 0";
+               extent = "74 18";
+               minExtent = "8 8";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiAutoSizeTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiSliderCtrl() {
+               range = "0 1";
+               ticks = "0";
+               snap = "0";
+               value = "1";
+               position = "85 2";
+               extent = "240 13";
+               minExtent = "8 8";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiSliderProfile";
+               visible = "1";
+               active = "1";
+               altCommand = "OptAudioUpdateChannelVolume(AudioEffect, $thisControl.value);";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "OptAudioVolumeSim";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+         new GuiControl() {
+            position = "23 177";
+            extent = "320 17";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiSliderCtrl() {
+               range = "0 1";
+               ticks = "0";
+               snap = "0";
+               value = "1";
+               position = "80 2";
+               extent = "240 13";
+               minExtent = "8 8";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiSliderProfile";
+               visible = "1";
+               active = "1";
+               altCommand = "OptAudioUpdateChannelVolume(AudioMusic, $thisControl.value);";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               internalName = "OptAudioVolumeMusic";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "Music Volume";
+               maxLength = "255";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "0 0";
+               extent = "67 18";
+               minExtent = "8 8";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiAutoSizeTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+      };
+      new GuiBitmapBorderCtrl() {
+         position = "9 55";
+         extent = "358 210";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTabBorderProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "OptGraphicsPane";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiTextCtrl() {
+            text = "Display Driver:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "11 8";
+            extent = "70 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Resolution:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "11 35";
+            extent = "53 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiCheckBoxCtrl() {
+            text = "Fullscreen";
+            groupNum = "-1";
+            buttonType = "ToggleButton";
+            useMouseEvents = "0";
+            position = "11 62";
+            extent = "85 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiCheckBoxProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptGraphicsFullscreenToggle";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl(OptGraphicsDriverMenu) {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            text = "ATI Radeon HD 5700 Series (D3D9)";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "88 8";
+            extent = "258 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            text = "1024 x 768  (4:3)";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "67 35";
+            extent = "127 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptGraphicsResolutionMenu";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Refresh:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "207 35";
+            extent = "45 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            text = "60";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "252 35";
+            extent = "49 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptRefreshSelectMenu";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Mesh Quality:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "21 91";
+            extent = "62 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            text = "Low";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "90 91";
+            extent = "78 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptMeshQualityPopup";
+            class = "GraphicsQualityPopup";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            text = "Low";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "90 118";
+            extent = "78 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptTextureQualityPopup";
+            class = "GraphicsQualityPopup";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Texture Quality:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "11 118";
+            extent = "77 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            text = "Low";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "90 143";
+            extent = "78 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptLightingQualityPopup";
+            class = "GraphicsQualityPopup";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Lighting Quality:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "11 143";
+            extent = "73 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Effect Quality:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "191 91";
+            extent = "73 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "263 91";
+            extent = "78 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptEffectQualityPopup";
+            class = "GraphicsQualityPopup";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Shader Quality:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "186 118";
+            extent = "77 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            text = "Low";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "263 118";
+            extent = "78 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptShaderQualityPopup";
+            class = "GraphicsQualityPopup";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Particle Quality:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "186 156";
+            extent = "73 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "0";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            hidden = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "263 156";
+            extent = "78 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "0";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptParticleQualityPopup";
+            class = "GraphicsQualityPopup";
+            hidden = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Anisotropic Filtering:";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "22 167";
+            extent = "105 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            text = "Off";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "123 167";
+            extent = "45 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptAnisotropicPopup";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiCheckBoxCtrl() {
+            text = "Vertical Sync";
+            groupNum = "-1";
+            buttonType = "ToggleButton";
+            useMouseEvents = "0";
+            position = "92 62";
+            extent = "85 18";
+            minExtent = "8 8";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiCheckBoxProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptGraphicsVSyncToggle";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl() {
+            text = "Auto Detect Quality";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "0";
+            position = "205 152";
+            extent = "110 27";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._autoDetectQuality();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiPopUpMenuCtrl() {
+            maxPopupHeight = "200";
+            sbUsesNAColor = "0";
+            reverseTextList = "0";
+            bitmapBounds = "16 16";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "263 62";
+            extent = "78 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiPopUpMenuProfile";
+            visible = "1";
+            active = "1";
+            command = "OptionsDlg._updateApplyState();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            internalName = "OptAAQualityPopup";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Anti-aliasing";
+            maxLength = "255";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "191 62";
+            extent = "73 18";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiTextProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiControl() {
+            position = "0 190";
+            extent = "352 15";
+            minExtent = "8 2";
+            horizSizing = "width";
+            vertSizing = "bottom";
+            profile = "GuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            internalName = "GammaSliderContainer";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiSliderCtrl() {
+               range = "0.001 2.2";
+               ticks = "0";
+               snap = "0";
+               value = "1";
+               position = "76 -1";
+               extent = "268 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiSliderProfile";
+               visible = "1";
+               active = "1";
+               variable = "$pref::Video::Gamma";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiTextCtrl() {
+               text = "Gamma:";
+               maxLength = "255";
+               margin = "0 0 0 0";
+               padding = "0 0 0 0";
+               anchorTop = "1";
+               anchorBottom = "0";
+               anchorLeft = "1";
+               anchorRight = "0";
+               position = "22 -4";
+               extent = "105 18";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiTextProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+      };
+      new GuiControl() {
+         position = "9 55";
+         extent = "357 208";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiWindowProfile";
+         visible = "0";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "OptNetworkPane";
+         hidden = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         text = "Graphics";
+         groupNum = "-1";
+         buttonType = "RadioButton";
+         useMouseEvents = "0";
+         position = "9 33";
+         extent = "117 23";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonTabProfile";
+         visible = "1";
+         active = "1";
+         command = "optionsDlg.setPane(Graphics);";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "OptGraphicsButton";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         text = "Audio";
+         groupNum = "-1";
+         buttonType = "RadioButton";
+         useMouseEvents = "0";
+         position = "126 33";
+         extent = "117 23";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonTabProfile";
+         visible = "1";
+         active = "1";
+         command = "optionsDlg.setPane(Audio);";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         text = "Controls";
+         groupNum = "-1";
+         buttonType = "RadioButton";
+         useMouseEvents = "0";
+         position = "243 33";
+         extent = "117 23";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonTabProfile";
+         visible = "1";
+         active = "1";
+         command = "optionsDlg.setPane(Controls);";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         text = "Apply";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "241 271";
+         extent = "60 23";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "0";
+         command = "optionsDlg.applyGraphics();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "apply";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 665 - 0
Templates/BaseGame/game/data/ui/guis/optionsMenu.cs

@@ -0,0 +1,665 @@
+//options settings
+
+//Screen and Display menu
+//Renderer Mode
+//Screen resolution
+//Windowed/fullscreen(borderless?)
+//VSync
+
+//Screen brightness
+//screen brightness
+//screen gamma
+
+//Lighting Menu
+//Shadow Distance(Distance shadows are drawn to. Also affects shadowmap slices)
+//Shadow Quality(Resolution of shadows rendered, setting to none disables dynamic shadows)
+//Soft Shadows(Whether shadow softening is used)
+//Shadow caching(If the lights enable it, shadow caching is activated)
+//Light Draw Distance(How far away lights are still drawn. Doesn't impact vector lights like the sun)
+
+//Mesh and Textures Menu
+//Draw distance(Overall draw distance) -slider
+//Object draw distance(Draw distance from small/unimportant objects) -slider
+//Mesh quality
+//Texture quality
+//Foliage draw distance
+//Terrain Quality
+//Decal Quality
+
+//Effects Menu
+//Parallax
+//HDR
+//Light shafts
+//Motion Blur
+//Depth of Field
+//SSAO
+//AA(ModelXAmount)[defualt is FXAA]
+//Anisotropic filtering
+
+//Keybinds
+
+//Camera
+//horizontal mouse sensitivity
+//vert mouse sensitivity
+//invert vertical
+//zoom mouse sensitivities(both horz/vert)
+//headbob
+//FOV
+
+function OptionsMenu::onWake(%this)
+{
+    OptionsMain.hidden = false;
+    ControlsMenu.hidden = true;
+    GraphicsMenu.hidden = true;
+    AudioMenu.hidden = true;
+    CameraMenu.hidden = true;
+    ScreenBrightnessMenu.hidden = true;
+    
+    OptionsOKButton.hidden = false;
+    OptionsCancelButton.hidden = false;
+    OptionsDefaultsButton.hidden = false;
+    
+    OptionsMenu.tamlReader = new Taml();
+    
+    OptionsSettingStack.clear();
+   
+   %array = OptionsSettingStack;
+   %array.clear();
+   
+   %keyboardMenuBtn = new GuiButtonCtrl(){
+      text = "Keyboard and Mouse";
+      profile = GuiMenuButtonProfile;
+      extent = %array.extent.x SPC "35";
+   };
+   
+   %controllerMenuBtn = new GuiButtonCtrl(){
+      text = "Controller";
+      profile = GuiMenuButtonProfile;
+      extent = %array.extent.x SPC "35";
+      command="DisplayMenu::loadSettings();";
+   };
+   
+   %displayMenuBtn = new GuiButtonCtrl(){
+      text = "Display";
+      profile = GuiMenuButtonProfile;
+      extent = %array.extent.x SPC "35";
+      command="DisplayMenu::loadSettings();";
+   };
+   
+   %graphicsMenuBtn = new GuiButtonCtrl(){
+      text = "Graphics";
+      profile = GuiMenuButtonProfile;
+      extent = %array.extent.x SPC "35";
+      command="GraphicsMenu::loadSettings();";
+   };
+   
+   %audioMenuBtn = new GuiButtonCtrl(){
+      text = "Audio";
+      profile = GuiMenuButtonProfile;
+      extent = %array.extent.x SPC "35";
+      command="AudioMenu::loadSettings();";
+   };
+   
+   %gameplayMenuBtn = new GuiButtonCtrl(){
+      text = "Gameplay";
+      profile = GuiMenuButtonProfile;
+      extent = %array.extent.x SPC "35";
+   };
+   
+   %array.add(%keyboardMenuBtn);
+   %array.add(%controllerMenuBtn);
+   %array.add(%displayMenuBtn);
+   %array.add(%graphicsMenuBtn);
+   %array.add(%audioMenuBtn);
+   %array.add(%gameplayMenuBtn);
+   
+   //We programmatically set up our settings here so we can do some prepwork on the fields/controls
+   //Presets
+   /*OptionsMenu.addSettingOption(%array, "Preset", "High", ShadowQualityList, $pref::Video::Resolution);
+   
+   //AA
+   OptionsMenu.addSettingOption(%array, "AntiAliasing", "FXAA 4x", ShadowQualityList, $pref::Video::Resolution);
+   
+   //Lighting
+   OptionsMenu.addSettingOption(%array, "Shadow Quality", "High", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Shadow Caching", "On", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Soft Shadows", "High", ShadowQualityList, $pref::Video::Resolution);
+   
+   //Models and Textures
+   OptionsMenu.addSettingOption(%array, "Level of Detail", "High", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Texture Quality", "High", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Material Quality", "High", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Terrain Detail", "High", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Decal Lifetime", "High", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Ground Clutter Density", "High", ShadowQualityList, $pref::Video::Resolution);
+   
+   //Effects
+   OptionsMenu.addSettingOption(%array, "HDR", "On", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Parallax", "On", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Ambient Occlusion", "On", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Light Rays", "On", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Depth of Field", "On", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Vignetting", "On", ShadowQualityList, $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(%array, "Water Reflections", "On", ShadowQualityList, $pref::Video::Resolution);
+   
+   OptionsMenu.addSettingOption(%array, "Anisotropic Filtering", "16x", ShadowQualityList, $pref::Video::Resolution);*/
+}
+
+function OptionsMenuOKButton::onClick(%this)
+{
+    //save the settings and then back out
+    eval(OptionsMenu.currentMenu@"::apply();");
+    OptionsMenu.backOut();
+}
+
+function OptionsMenuCancelButton::onClick(%this)
+{
+    //we don't save, so just back out of the menu 
+    OptionsMenu.backOut();
+}
+
+function OptionsMenuDefaultsButton::onClick(%this)
+{
+    //we don't save, so go straight to backing out of the menu    
+    eval(OptionsMenu.currentMenu@"::applyDefaults();");
+    OptionsMenu.backOut();
+}
+
+function ControlsSettingsMenuButton::onClick(%this)
+{
+    OptionsMain.hidden = true;
+    ControlsMenu.hidden = false;
+    
+    KeyboardControlPanel.hidden = false;
+    MouseControlPanel.hidden = true;
+    
+    ControlsMenu.reload();
+}
+
+function GraphicsSettingsMenuButton::onClick(%this)
+{
+    OptionsMain.hidden = true;
+    GraphicsMenu.hidden = false;
+}
+
+function CameraSettingsMenuButton::onClick(%this)
+{
+    OptionsMain.hidden = true;
+    CameraMenu.hidden = false;
+    
+    CameraMenu.loadSettings();
+}
+
+function AudioSettingsMenuButton::onClick(%this)
+{
+    OptionsMain.hidden = true;
+    AudioMenu.hidden = false;
+    AudioMenu.loadSettings();
+}
+
+function ScreenBrSettingsMenuButton::onClick(%this)
+{
+    OptionsMain.hidden = true;
+    ScreenBrightnessMenu.hidden = false;
+}
+
+function OptionsMenu::backOut(%this)
+{
+   //save the settings and then back out
+   if(OptionsMain.hidden == false)
+   {
+      //we're not in a specific menu, so we're actually exiting
+      Canvas.popDialog(OptionsMenu);
+
+      if(isObject(OptionsMenu.returnGui) && OptionsMenu.returnGui.isMethod("onReturnTo"))
+         OptionsMenu.returnGui.onReturnTo();
+   }
+   else
+   {
+      OptionsMain.hidden = false;
+      ControlsMenu.hidden = true;
+      GraphicsMenu.hidden = true;
+      CameraMenu.hidden = true;
+      AudioMenu.hidden = true;
+      ScreenBrightnessMenu.hidden = true;
+   }
+}
+
+function OptionsMenu::addSettingOption(%this, %arrayTarget, %optionName, %defaultValue, %settingsGroup, %targetVar)
+{
+    %option = TAMLRead("data/ui/guis/graphicsMenuSettingsCtrl.taml");
+    
+    if(!isMethod(%settingsGroup, "get") || !isMethod(%settingsGroup, "set"))
+    {
+      error("OptionsMenu::addSettingsOption - unrecognized settings group of: " @ %settingsGroup @ ". Did not have proper getter/setter");
+      return "";
+    }
+    
+    %option-->nameText.text = %optionName;
+    %option-->SettingText.text = eval(%settingsGroup@"::"@"get();");
+    %option.qualitySettingGroup = %settingsGroup;
+    %option.targetVar = %targetVar;
+
+    %arrayTarget.add(%option);
+
+    return %option;
+}
+
+function OptionsMenu::addSliderOption(%this, %arrayTarget, %optionName, %variable, %range, %ticks, %value, %class)
+{
+    %option = TAMLRead("data/ui/guis/graphicsMenuSettingsSlider.taml");
+    
+    %option-->nameText.text = %optionName;
+
+    %arrayTarget.add(%option);
+    
+    if(%range !$= "")
+    {
+       %option-->slider.range = %range;
+    }
+    
+    if(%ticks !$= "")
+    {
+       %option-->slider.ticks = %ticks;
+    }
+    
+    if(%variable !$= "")
+    {
+       %option-->slider.variable = %variable;
+    }
+    
+    if(%value !$= "")
+    {
+       %option-->slider.setValue(%value);
+    }
+    
+    if(%class !$= "")
+    {
+       %option-->slider.className = %class;
+    }
+    else
+        %option-->slider.className = OptionsMenuSlider;
+        
+    %option-->slider.snap = true;
+    
+    %option-->slider.onValueSet();
+
+    return %option;
+}
+
+function OptionsMenuSlider::onMouseDragged(%this)
+{
+   %this.onValueSet();
+}
+
+function OptionsMenuSlider::onValueSet(%this)
+{
+   %this.getParent().getParent()-->valueText.setText(mRound(%this.value * 10));  
+}
+
+function FOVOptionSlider::onMouseDragged(%this)
+{
+   %this.onValueSet();
+}
+
+function FOVOptionSlider::onValueSet(%this)
+{
+   %this.getParent().getParent()-->valueText.setText(mRound(%this.value));
+}
+
+//
+function OptionsMenuForwardSetting::onClick(%this)
+{
+   //we need to advance through the value list, unless it's the end, in which case we do nothing  
+   echo("Move forward in the list!");
+   
+   %settingCtrl = %this.getParent();
+   %settingsList = eval(%settingCtrl.qualitySettingGroup@"::getList();");
+   %settingsListCount = getTokenCount(%settingsList, ",");
+   %currentSetting = %settingCtrl-->SettingText.text;
+   
+   //We consider 'custom' to be the defacto end of the list. The only way back is to go lower
+   if(%currentSetting $= "Custom")
+      return;
+      
+   %currentSettingIdx = OptionsMenu.getCurrentIndexFromSetting(%settingCtrl);
+   
+   if(%currentSettingIdx != %settingsListCount-1)
+   {
+      %currentSettingIdx++;
+      
+      //advance by one
+      %newSetting = getToken(%settingsList, ",", %currentSettingIdx);
+      eval(%settingCtrl.qualitySettingGroup@"::set(\""@%newSetting@"\");");
+      %settingCtrl-->SettingText.setText( %newSetting );
+      
+      if(%currentSettingIdx == %settingsListCount)
+      {
+         //if we hit the end of the list, disable the forward button  
+      }
+   }
+}
+
+function OptionsMenuBackSetting::onClick(%this)
+{
+   //we need to advance through the value list, unless it's the end, in which case we do nothing  
+   echo("Move back in the list!");
+   
+   %settingCtrl = %this.getParent();
+   %settingsList = eval(%settingCtrl.qualitySettingGroup@"::getList();");
+   %settingsListCount = getTokenCount(%settingsList, ",");
+   %currentSetting = %settingCtrl-->SettingText.text;
+   
+   %currentSettingIdx = OptionsMenu.getCurrentIndexFromSetting(%settingCtrl);
+   
+   if(%currentSettingIdx != 0)
+   {
+      %currentSettingIdx--;
+      
+      //advance by one
+      %newSetting = getToken(%settingsList, ",", %currentSettingIdx);
+      eval(%settingCtrl.qualitySettingGroup@"::set("@%newSetting@");");
+      %settingCtrl-->SettingText.setText( %newSetting );
+      
+      if(%currentSettingIdx == %settingsListCount)
+      {
+         //if we hit the end of the list, disable the forward button  
+      }
+   }
+}
+
+function OptionsMenu::getCurrentIndexFromSetting(%this, %settingCtrl)
+{
+   %settingsList = eval(%settingCtrl.qualitySettingGroup@"::getList();");
+   %settingsListCount = getTokenCount(%settingsList, ",");
+   %currentSetting = %settingCtrl-->SettingText.text;
+   
+   for ( %i=0; %i < %settingsListCount; %i++ )
+   {
+      %level = getToken(%settingsList, ",", %i);
+      
+      //find our current level
+      if(%currentSetting $= %level)
+      {
+         return %i;
+      }
+   }
+   
+   return -1;
+}
+
+// =============================================================================
+// CAMERA MENU
+// =============================================================================
+function CameraMenu::onWake(%this)
+{
+    
+}
+
+function CameraMenu::apply(%this)
+{
+   setFOV($pref::Player::defaultFov);  
+}
+
+function CameraMenu::loadSettings(%this)
+{
+   CameraMenuOptionsArray.clear();
+   
+   %option = OptionsMenu.addSettingOption(CameraMenuOptionsArray);
+   %option-->nameText.setText("Invert Vertical");
+   %option.qualitySettingGroup = InvertVerticalMouse;
+   %option.init();
+   
+   %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::VertMouseSensitivity", $pref::Input::VertMouseSensitivity);
+   %option-->nameText.setText("Vertical Sensitivity");
+   
+   %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::HorzMouseSensitivity", $pref::Input::HorzMouseSensitivity);
+   %option-->nameText.setText("Horizontal Sensitivity");
+   
+   %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::ZoomVertMouseSensitivity", $pref::Input::ZoomVertMouseSensitivity);
+   %option-->nameText.setText("Zoom Vertical Sensitivity");
+
+   %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::ZoomHorzMouseSensitivity", $pref::Input::ZoomHorzMouseSensitivity);
+   %option-->nameText.setText("Zoom Horizontal Sensitivity");
+   
+   %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "65 90", 25, "$pref::Player::defaultFov", $pref::Player::defaultFov, FOVOptionSlider);
+   %option-->nameText.setText("Field of View");
+   
+   CameraMenuOptionsArray.refresh();
+}
+
+function CameraMenuOKButton::onClick(%this)
+{
+   //save the settings and then back out
+    CameraMenu.apply();
+    OptionsMenu.backOut();
+}
+
+function CameraMenuDefaultsButton::onClick(%this)
+{
+   
+}
+// =============================================================================
+// AUDIO MENU
+// =============================================================================
+$AudioTestHandle = 0;
+// Description to use for playing the volume test sound.  This isn't
+// played with the description of the channel that has its volume changed
+// because we know nothing about the playback state of the channel.  If it
+// is paused or stopped, the test sound would not play then.
+$AudioTestDescription = new SFXDescription()
+{
+   sourceGroup = AudioChannelMaster;
+};
+
+function AudioMenu::loadSettings(%this)
+{
+   // Audio
+   //OptAudioHardwareToggle.setStateOn($pref::SFX::useHardware);
+   //OptAudioHardwareToggle.setActive( true );
+   
+   %this-->OptAudioVolumeMaster.setValue( $pref::SFX::masterVolume );
+   %this-->OptAudioVolumeShell.setValue( $pref::SFX::channelVolume[ $GuiAudioType] );
+   %this-->OptAudioVolumeSim.setValue( $pref::SFX::channelVolume[ $SimAudioType ] );
+   %this-->OptAudioVolumeMusic.setValue( $pref::SFX::channelVolume[ $MusicAudioType ] );
+   
+   AudioMenuSoundDriver.clear();
+   %buffer = sfxGetAvailableDevices();
+   %count = getRecordCount( %buffer );   
+   for(%i = 0; %i < %count; %i++)
+   {
+      %record = getRecord(%buffer, %i);
+      %provider = getField(%record, 0);
+      
+      if ( AudioMenuSoundDriver.findText( %provider ) == -1 )
+            AudioMenuSoundDriver.add( %provider, %i );
+   }
+   
+   AudioMenuSoundDriver.sort();
+
+   %selId = AudioMenuSoundDriver.findText($pref::SFX::provider);
+	if ( %selId == -1 )
+		AudioMenuSoundDriver.setFirstSelected();
+   else
+	   AudioMenuSoundDriver.setSelected( %selId );
+}
+
+function AudioMenu::loadDevices(%this)
+{
+   if(!isObject(SoundDeviceGroup))
+   {
+      new SimGroup( SoundDeviceGroup );
+   }
+   else
+   {
+      SoundDeviceGroup.clear();
+   }
+   
+   %buffer = sfxGetAvailableDevices();
+   %count = getRecordCount( %buffer );
+   for (%i = 0; %i < %count; %i++)
+   {
+      %record = getRecord(%buffer, %i);
+      %provider = getField(%record, 0);
+      %device = getField(%record, 1);
+         
+      if($pref::SFX::provider !$= %provider)
+         continue;
+      
+      %setting = new ArrayObject()
+      {
+         class = "OptionsMenuSettingLevel";
+         caseSensitive = true;
+         
+         displayName = %device;
+         
+         key["$pref::SFX::Device"] = %device;
+      };
+      
+      SoundDeviceGroup.add(%setting);
+   }
+}
+
+function AudioMenu::apply(%this)
+{
+   sfxSetMasterVolume( $pref::SFX::masterVolume );
+   
+   sfxSetChannelVolume( $GuiAudioType, $pref::SFX::channelVolume[ $GuiAudioType ] );
+   sfxSetChannelVolume( $SimAudioType, $pref::SFX::channelVolume[ $SimAudioType ] );
+   sfxSetChannelVolume( $MusicAudioType, $pref::SFX::channelVolume[ $MusicAudioType ] );
+   
+   if ( !sfxCreateDevice(  $pref::SFX::provider, 
+                           $pref::SFX::device, 
+                           $pref::SFX::useHardware,
+                           -1 ) )                              
+      error( "Unable to create SFX device: " @ $pref::SFX::provider 
+                                             SPC $pref::SFX::device 
+                                             SPC $pref::SFX::useHardware );        
+
+   if( !isObject( $AudioTestHandle ) )
+   {
+      sfxPlay(menuButtonPressed);
+   }
+}
+
+function AudioMenuOKButton::onClick(%this)
+{
+   //save the settings and then back out
+    AudioMenu.apply();
+    OptionsMenu.backOut();
+}
+
+function AudioMenuDefaultsButton::onClick(%this)
+{
+   sfxInit();
+   AudioMenu.loadSettings();
+}
+
+function OptAudioUpdateMasterVolume( %volume )
+{
+   if( %volume == $pref::SFX::masterVolume )
+      return;
+      
+   sfxSetMasterVolume( %volume );
+   $pref::SFX::masterVolume = %volume;
+   
+   if( !isObject( $AudioTestHandle ) )
+      $AudioTestHandle = sfxPlayOnce( AudioChannel, "data/ui/sounds/volumeTest.wav" );
+}
+
+function OptAudioUpdateChannelVolume( %description, %volume )
+{
+   %channel = sfxGroupToOldChannel( %description.sourceGroup );
+   
+   if( %volume == $pref::SFX::channelVolume[ %channel ] )
+      return;
+
+   sfxSetChannelVolume( %channel, %volume );
+   $pref::SFX::channelVolume[ %channel ] = %volume;
+   
+   if( !isObject( $AudioTestHandle ) )
+   {
+      $AudioTestDescription.volume = %volume;
+      $AudioTestHandle = sfxPlayOnce( $AudioTestDescription, "data/ui/sounds/volumeTest.wav" );
+   }
+}
+
+function AudioMenuSoundDriver::onSelect( %this, %id, %text )
+{
+   // Skip empty provider selections.   
+   if ( %text $= "" )
+      return;
+      
+   $pref::SFX::provider = %text;
+   AudioMenuSoundDevice.clear();
+   
+   %buffer = sfxGetAvailableDevices();
+   %count = getRecordCount( %buffer );   
+   for(%i = 0; %i < %count; %i++)
+   {
+      %record = getRecord(%buffer, %i);
+      %provider = getField(%record, 0);
+      %device = getField(%record, 1);
+      
+      if (%provider !$= %text)
+         continue;
+            
+       if ( AudioMenuSoundDevice.findText( %device ) == -1 )
+            AudioMenuSoundDevice.add( %device, %i );
+   }
+
+   // Find the previous selected device.
+   %selId = AudioMenuSoundDevice.findText($pref::SFX::device);
+   if ( %selId == -1 )
+      AudioMenuSoundDevice.setFirstSelected();
+   else
+   AudioMenuSoundDevice.setSelected( %selId );
+}
+
+function AudioMenuSoundDevice::onSelect( %this, %id, %text )
+{
+   // Skip empty selections.
+   if ( %text $= "" )
+      return;
+      
+   $pref::SFX::device = %text;
+   
+   if ( !sfxCreateDevice(  $pref::SFX::provider, 
+                           $pref::SFX::device, 
+                           $pref::SFX::useHardware,
+                           -1 ) )                              
+      error( "Unable to create SFX device: " @ $pref::SFX::provider 
+                                             SPC $pref::SFX::device 
+                                             SPC $pref::SFX::useHardware );                                             
+}
+
+//==============================================================================
+// DISPLAY MENU
+//==============================================================================
+function DisplayMenu::loadSettings()
+{
+   OptionsSettingStack.clear();
+   
+   OptionsMenu.addSettingOption(OptionsSettingStack, "Resolution", "1024 x 768", "", $pref::Video::Resolution);
+   OptionsMenu.addSettingOption(OptionsSettingStack, "Full Screen", "Off", "", $pref::Video::FullScreen);
+   OptionsMenu.addSettingOption(OptionsSettingStack, "Refresh Rate", "60", "", $pref::Video::RefreshRate);
+   OptionsMenu.addSettingOption(OptionsSettingStack, "VSync", "Off", "", $pref::Video::Vsync);
+   
+   OptionsMenu.addSliderOption(OptionsSettingStack, "Field of View", $pref::Video::FOV, "65 120", 55, 75);
+   
+   OptionsMenu.addSliderOption(OptionsSettingStack, "Brightness", $pref::Video::Brightness, "0 1", 10, 5);
+   OptionsMenu.addSliderOption(OptionsSettingStack, "Contrast", $pref::Video::Contrast, "0 1", 10, 5);
+}
+
+//==============================================================================
+// AUDIO MENU
+//==============================================================================
+function AudioMenu::loadSettings()
+{
+   OptionsSettingStack.clear();
+   
+   OptionsMenu.addSliderOption(OptionsSettingStack, "Master Volume", $pref::Video::Brightness, "0 1", 10, 5);
+   OptionsMenu.addSliderOption(OptionsSettingStack, "Menu Volume", $pref::Video::Brightness, "0 1", 10, 5);
+   OptionsMenu.addSliderOption(OptionsSettingStack, "Effects Volume", $pref::Video::Brightness, "0 1", 10, 5);
+   OptionsMenu.addSliderOption(OptionsSettingStack, "Music Volume", $pref::Video::Brightness, "0 1", 10, 5);
+}

+ 247 - 0
Templates/BaseGame/game/data/ui/guis/optionsMenu.gui

@@ -0,0 +1,247 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(OptionsMenu) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      returnGui = "MainMenuGui";
+      tamlReader = "20077";
+      tile = "0";
+      useVariable = "0";
+
+   new GuiControl() {
+      position = "86 70";
+      extent = "846 618";
+      minExtent = "8 2";
+      horizSizing = "center";
+      vertSizing = "center";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiBitmapCtrl() {
+         bitmap = "data/ui/images/hudfill.png";
+         color = "255 255 255 255";
+         wrap = "0";
+         position = "0 0";
+         extent = "846 618";
+         minExtent = "8 2";
+         horizSizing = "width";
+         vertSizing = "height";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiControl() {
+         position = "0 0";
+         extent = "846 20";
+         minExtent = "8 2";
+         horizSizing = "width";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiBitmapCtrl() {
+            bitmap = "data/ui/images/hudfill.png";
+            color = "255 255 255 255";
+            wrap = "0";
+            position = "0 0";
+            extent = "846 20";
+            minExtent = "8 2";
+            horizSizing = "width";
+            vertSizing = "height";
+            profile = "GuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiTextCtrl() {
+            text = "Options";
+            maxLength = "1024";
+            margin = "0 0 0 0";
+            padding = "0 0 0 0";
+            anchorTop = "1";
+            anchorBottom = "0";
+            anchorLeft = "1";
+            anchorRight = "0";
+            position = "0 0";
+            extent = "846 20";
+            minExtent = "8 2";
+            horizSizing = "width";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+      };
+      new GuiScrollCtrl() {
+         willFirstRespond = "1";
+         hScrollBar = "alwaysOff";
+         vScrollBar = "dynamic";
+         lockHorizScroll = "0";
+         lockVertScroll = "0";
+         constantThumbHeight = "0";
+         childMargin = "0 0";
+         mouseWheelScrollSpeed = "-1";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "0 25";
+         extent = "846 522";
+         minExtent = "8 2";
+         horizSizing = "width";
+         vertSizing = "height";
+         profile = "GuiScrollProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiStackControl(OptionsSettingStack) {
+            stackingType = "Vertical";
+            horizStacking = "Left to Right";
+            vertStacking = "Top to Bottom";
+            padding = "0";
+            dynamicSize = "1";
+            dynamicNonStackExtent = "0";
+            dynamicPos = "0";
+            changeChildSizeToFit = "1";
+            changeChildPosition = "1";
+            position = "1 1";
+            extent = "846 210";
+            minExtent = "16 16";
+            horizSizing = "width";
+            vertSizing = "bottom";
+            profile = "GuiDefaultProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+      };
+      new GuiMLTextCtrl() {
+         lineSpacing = "2";
+         allowColorChars = "0";
+         maxChars = "-1";
+         text = "This is a test message to act as a tooltip for any selected options menus for more information on the given option.";
+         useURLMouseCursor = "0";
+         position = "0 547";
+         extent = "847 14";
+         minExtent = "8 2";
+         horizSizing = "width";
+         vertSizing = "top";
+         profile = "GuiMLWhiteTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         class="OptionsMenuOKButton";
+         text = "OK";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "0 581";
+         extent = "282 37";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "top";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         class="OptionsMenuDefaultsButton";
+         text = "Defaults";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "282 581";
+         extent = "282 37";
+         minExtent = "8 2";
+         horizSizing = "relative";
+         vertSizing = "top";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         class="OptionsMenuCancelButton";
+         text = "Cancel";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "564 581";
+         extent = "282 37";
+         minExtent = "8 2";
+         horizSizing = "left";
+         vertSizing = "height";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 30 - 0
Templates/BaseGame/game/data/ui/guis/pauseMenu.cs

@@ -0,0 +1,30 @@
+function PauseMenu::onWake(%this)
+{
+   $timescale = 0;
+}
+
+function PauseMenu::onSleep(%this)
+{
+   $timescale = 1;
+}
+
+function PauseMenu::openOptionsMenu(%this)
+{
+   Canvas.pushDialog(OptionsMenu);
+   OptionsMenu.returnGui = %this; 
+   PauseOptionsMain.hidden = true; 
+}
+
+function PauseMenu::openControlsMenu(%this)
+{
+   Canvas.pushDialog(OptionsMenu);
+   OptionsMenu.returnGui = %this; 
+   PauseOptionsMain.hidden = true; 
+   OptionsMain.hidden = true;
+   ControlsMenu.hidden = false;
+}
+
+function PauseMenu::onReturnTo(%this)
+{
+   PauseOptionsMain.hidden = false;
+}

+ 153 - 0
Templates/BaseGame/game/data/ui/guis/pauseMenu.gui

@@ -0,0 +1,153 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(PauseMenu) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      tamlReader = "19772";
+      tile = "0";
+      useVariable = "0";
+
+   new GuiChunkedBitmapCtrl(PauseMenuBG) {
+      bitmap = "data/ui/images/hudfill";
+      useVariable = "0";
+      tile = "0";
+      position = "0 0";
+      extent = "1024 768";
+      minExtent = "8 2";
+      horizSizing = "width";
+      vertSizing = "height";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   new GuiControl() {
+      position = "155 118";
+      extent = "700 518";
+      minExtent = "8 2";
+      horizSizing = "center";
+      vertSizing = "center";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiControl(PauseOptionsMain) {
+         position = "1 1";
+         extent = "700 320";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "center";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiButtonCtrl(PauseMenuExitButton) {
+            text = "Exit Game";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "1";
+            position = "0 0";
+            extent = "700 35";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "escapeFromGame();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl(PauseMenuOptionsButton) {
+            text = "Options";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "1";
+            position = "0 35";
+            extent = "700 35";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "PauseMenu.openOptionsMenu();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl(PauseMenuControlsButton) {
+            text = "Controls";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "1";
+            position = "0 70";
+            extent = "700 35";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "PauseMenu.openControlsMenu();";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+         new GuiButtonCtrl(PauseMenuCancelButton) {
+            text = "Cancel";
+            groupNum = "-1";
+            buttonType = "PushButton";
+            useMouseEvents = "1";
+            position = "466 285";
+            extent = "233 35";
+            minExtent = "8 8";
+            horizSizing = "relative";
+            vertSizing = "bottom";
+            profile = "GuiMenuButtonProfile";
+            visible = "1";
+            active = "1";
+            command = "Canvas.popDialog();";
+            accelerator = "escape";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "0";
+            class = "OptionsMenuDefaultsButton";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 367 - 0
Templates/BaseGame/game/data/ui/guis/profiler.cs

@@ -0,0 +1,367 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+$MetricsParamArray[0] = "fps ";
+$MetricsParamArray[1] = "shadow "; 
+$MetricsParamArray[2] = "gfx "; 
+$MetricsParamArray[3] = "sfx ";
+$MetricsParamArray[4] = "terrain ";
+$MetricsParamArray[5] = "groundcover ";
+$MetricsParamArray[6] = "forest ";
+$MetricsParamArray[7] = "net ";
+$EnableProfiler = false;
+$string = ""; //string used to collet the parameters for metrics function
+
+function showMetrics(%var)
+{
+	$string = "";
+	if(ppShowFps.getValue())
+	{
+		$string = $string @ $MetricsParamArray[0];
+	}
+	if(ppShowShadow.getValue())
+	{
+		$string = $string @ $MetricsParamArray[1];
+	}
+	if(ppShowGfx.getValue())
+	{
+		$string = $string @ $MetricsParamArray[2];
+	}
+	if(ppShowSfx.getValue())
+	{
+		$string = $string @ $MetricsParamArray[3];
+	}
+	if(ppShowTerrain.getValue())
+	{
+		$string = $string @ $MetricsParamArray[4];
+	}
+	if(ppShowForest.getValue())
+	{
+		$string = $string @ $MetricsParamArray[5];
+	}
+	if(ppShowGroundcover.getValue())
+	{
+		$string = $string @ $MetricsParamArray[6];
+	}
+	if(ppShowNet.getValue())
+	{
+		$string = $string @ $MetricsParamArray[7];
+	}
+
+	if(%var)
+	{
+		$EnableProfiler = !($EnableProfiler);
+
+	   if($EnableProfiler)
+	   {
+			metrics($string);	
+	   }
+	   else if((false == $EnableProfiler))
+	   {
+		   metrics();
+	   }
+	}
+	else if($EnableProfiler)  //will enter only when the enable/disable button was pressed
+	{
+		metrics($string);
+	}
+}
+
+function showMetics(%var)
+{
+   if(%var)
+   {
+      metrics($string);
+   }
+   else if(true == $EnableProfiler)
+   {
+      $EnableProfiler = false;
+      metrics();
+   }
+}
+
+GlobalActionMap.bind(keyboard, "ctrl F2", showMetics);
+
+%guiContent = new GuiControl(FrameOverlayGui) {
+	profile = "GuiModelessDialogProfile";
+	horizSizing = "right";
+	vertSizing = "bottom";
+	position = "0 0";
+	extent = "640 480";
+	minExtent = "8 8";
+	visible = "True";
+	setFirstResponder = "True";
+	modal = "false";
+	helpTag = "0";
+   noCursor = true;
+	new GuiConsoleTextCtrl(TextOverlayControl) {
+		profile = "GuiConsoleTextProfile";
+		horizSizing = "right";
+		vertSizing = "bottom";
+		position = "5 5";
+		extent = "130 18";
+		minExtent = "4 4";
+		visible = "True";
+		setFirstResponder = "True";
+		modal = "True";
+		helpTag = "0";
+		expression = "10";
+		command = "Canvas.popDialog(FrameOverlayGui);";
+		accelerator = "escape";
+	};
+};
+
+// Note:  To implement your own metrics overlay 
+// just add a function with a name in the form 
+// XXXXMetricsCallback which can be enabled via
+// metrics( XXXX )
+
+function fpsMetricsCallback()
+{
+   return "  | FPS |" @ 
+          "  " @ $fps::real @ 
+          "  max: " @ $fps::realMax @
+          "  min: " @ $fps::realMin @
+          "  mspf: " @ 1000 / $fps::real;
+}
+
+function gfxMetricsCallback()
+{
+   return "  | GFX |" @
+          "  PolyCount: " @ $GFXDeviceStatistics::polyCount @
+          "  DrawCalls: " @ $GFXDeviceStatistics::drawCalls @
+          "  RTChanges: " @ $GFXDeviceStatistics::renderTargetChanges;
+          
+}
+
+function terrainMetricsCallback()
+{
+   return "  | Terrain |" @
+          "  Cells: " @ $TerrainBlock::cellsRendered @
+          "  Override Cells: " @ $TerrainBlock::overrideCells @
+          "  DrawCalls: " @ $TerrainBlock::drawCalls;
+}
+
+function netMetricsCallback()
+{
+   return "  | Net |" @
+          "  BitsSent: " @ $Stats::netBitsSent @
+          "  BitsRcvd: " @ $Stats::netBitsReceived @
+          "  GhostUpd: " @ $Stats::netGhostUpdates;
+}
+
+function groundCoverMetricsCallback()
+{
+   return "  | GroundCover |" @
+          "  Cells: " @ $GroundCover::renderedCells @
+          "  Billboards: " @ $GroundCover::renderedBillboards @
+          "  Batches: " @ $GroundCover::renderedBatches @
+          "  Shapes: " @ $GroundCover::renderedShapes;
+}
+
+function forestMetricsCallback()
+{
+   return "  | Forest |" @
+          "  Cells: " @ $Forest::totalCells @
+          "  Cells Meshed: " @ $Forest::cellsRendered @
+          "  Cells Billboarded: " @ $Forest::cellsBatched @
+          "  Meshes: " @ $Forest::cellItemsRendered @                          
+          "  Billboards: " @ $Forest::cellItemsBatched;
+}
+
+function sfxMetricsCallback() 
+{
+   return "  | SFX |" @
+          "  Sounds: " @ $SFX::numSounds @
+          "  Lists: " @ ( $SFX::numSources - $SFX::numSounds - $SFX::Device::fmodNumEventSource ) @
+          "  Events: " @ $SFX::fmodNumEventSources @
+          "  Playing: " @ $SFX::numPlaying @
+          "  Culled: " @ $SFX::numCulled @
+          "  Voices: " @ $SFX::numVoices @
+          "  Buffers: " @ $SFX::Device::numBuffers @
+          "  Memory: " @ ( $SFX::Device::numBufferBytes / 1024.0 / 1024.0 ) @ " MB" @
+          "  Time/S: " @ $SFX::sourceUpdateTime @
+          "  Time/P: " @ $SFX::parameterUpdateTime @
+          "  Time/A: " @ $SFX::ambientUpdateTime;
+}
+
+function sfxSourcesMetricsCallback() 
+{
+   return sfxDumpSourcesToString();
+}
+
+function sfxStatesMetricsCallback()
+{
+   return "  | SFXStates |" @ sfxGetActiveStates();
+}
+
+function timeMetricsCallback()
+{
+   return "  | Time |" @ 
+          "  Sim Time: " @ getSimTime() @ 
+          "  Mod: " @ getSimTime() % 32;
+}
+
+function reflectMetricsCallback()
+{
+   return "  | REFLECT |" @
+          "  Objects: " @ $Reflect::numObjects @ 
+          "  Visible: " @ $Reflect::numVisible @
+          "  Occluded: " @ $Reflect::numOccluded @
+          "  Updated: " @ $Reflect::numUpdated @
+          "  Elapsed: " @ $Reflect::elapsed NL
+             
+          "  Allocated: " @ $Reflect::renderTargetsAllocated @
+          "  Pooled: " @ $Reflect::poolSize NL
+          
+          "  " @ getWord( $Reflect::textureStats, 1 ) TAB
+          "  " @ getWord( $Reflect::textureStats, 2 ) @ "MB" TAB                  
+          "  " @ getWord( $Reflect::textureStats, 0 );
+}
+
+function decalMetricsCallback()
+{
+   return "  | DECAL |" @
+          " Batches: " @ $Decal::Batches @
+          " Buffers: " @ $Decal::Buffers @
+          " DecalsRendered: " @ $Decal::DecalsRendered;
+}
+
+function renderMetricsCallback()
+{
+   return "  | Render |" @
+          "  Mesh: " @ $RenderMetrics::RIT_Mesh @
+          "  MeshDL: " @ $RenderMetrics::RIT_MeshDynamicLighting @
+          "  Shadow: " @ $RenderMetrics::RIT_Shadow @
+          "  Sky: " @ $RenderMetrics::RIT_Sky @
+          "  Obj: " @ $RenderMetrics::RIT_Object @
+          "  ObjT: " @ $RenderMetrics::RIT_ObjectTranslucent @
+          "  Decal: " @ $RenderMetrics::RIT_Decal @
+          "  Water: " @ $RenderMetrics::RIT_Water @
+          "  Foliage: " @ $RenderMetrics::RIT_Foliage @
+          "  Trans: " @ $RenderMetris::RIT_Translucent @
+          "  Custom: " @ $RenderMetrics::RIT_Custom;
+}
+
+function shadowMetricsCallback()
+{   
+   return "  | Shadow |" @
+          "  Active: " @ $ShadowStats::activeMaps @
+          "  Updated: " @ $ShadowStats::updatedMaps @
+          "  PolyCount: " @ $ShadowStats::polyCount @
+          "  DrawCalls: " @ $ShadowStats::drawCalls @          
+          "   RTChanges: " @ $ShadowStats::rtChanges @          
+          "   PoolTexCount: " @ $ShadowStats::poolTexCount @
+          "   PoolTexMB: " @ $ShadowStats::poolTexMemory @ "MB";         
+}
+
+function basicShadowMetricsCallback()
+{   
+   return "  | Shadow |" @
+          "  Active: " @ $BasicLightManagerStats::activePlugins @
+          "  Updated: " @ $BasicLightManagerStats::shadowsUpdated @
+          "  Elapsed Ms: " @ $BasicLightManagerStats::elapsedUpdateMs;         
+}
+
+function lightMetricsCallback()
+{
+   return "  | Deferred Lights |" @
+          "  Active: " @ $lightMetrics::activeLights @
+          "  Culled: " @ $lightMetrics::culledLights;
+}
+
+function particleMetricsCallback()
+{
+   return "  | Particles |" @ 
+          "  # Simulated " @ $particle::numSimulated;
+}
+function partMetricsCallback()
+{
+   return particleMetricsCallback();
+}
+
+function imposterMetricsCallback()
+{
+   return "  | IMPOSTER |" @ 
+          "   Rendered: " @ $ImposterStats::rendered @
+          "   Batches: " @ $ImposterStats::batches @
+          "   DrawCalls: " @ $ImposterStats::drawCalls @
+          "   Polys: " @ $ImposterStats::polyCount @
+          "   RtChanges: " @ $ImposterStats::rtChanges;
+}
+
+// alias
+function audioMetricsCallback()
+{
+   return sfxMetricsCallback(); 
+}
+
+// alias
+function videoMetricsCallback()
+{
+   return gfxMetricsCallback();
+}
+
+// Add a metrics HUD.  %expr can be a vector of names where each element
+// must have a corresponding '<name>MetricsCallback()' function defined
+// that will be called on each update of the GUI control.  The results
+// of each function are stringed together.
+//
+// Example: metrics( "fps gfx" );
+
+function metrics( %expr )
+{
+   %metricsExpr = "";
+   if( %expr !$= "" )
+   {
+      for( %i = 0;; %i ++ )
+      {
+         %name = getWord( %expr, %i );
+         if( %name $= "" )
+            break;
+         else
+         {
+            %cb = %name @ "MetricsCallback";
+            if( !isFunction( %cb ) )
+               error( "metrics - undefined callback: " @ %cb );
+            else
+            {
+               %cb = %cb @ "()";
+               if( %i > 0 )
+                  %metricsExpr = %metricsExpr @ " NL ";
+               %metricsExpr = %metricsExpr @ %cb;
+            }
+         }
+      }
+      
+      if( %metricsExpr !$= "" )
+         %metricsExpr = %metricsExpr @ " @ \" \"";
+   }
+   
+   if( %metricsExpr !$= "" )
+   {
+      $GameCanvas.pushDialog( FrameOverlayGui, 1000 );
+      TextOverlayControl.setValue( %metricsExpr );
+   }
+   else
+      $GameCanvas.popDialog(FrameOverlayGui);
+}

+ 324 - 0
Templates/BaseGame/game/data/ui/guis/profiler.gui

@@ -0,0 +1,324 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(ProfilerGui) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+
+   new GuiWindowCtrl(ppProfilerWindow) {
+      text = "Profiler Manager";
+      resizeWidth = "0";
+      resizeHeight = "0";
+      canMove = "1";
+      canClose = "1";
+      canMinimize = "0";
+      canMaximize = "0";
+      canCollapse = "0";
+      closeCommand = "Canvas.popDialog(ProfilerGui);";
+      edgeSnap = "0";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "306 216";
+      extent = "415 199";
+      minExtent = "8 8";
+      horizSizing = "center";
+      vertSizing = "center";
+      profile = "GuiWindowProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiCheckBoxCtrl(ppShowFps) {
+         text = "Show Fps";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         position = "13 24";
+         extent = "127 30";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiCheckBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Enable or Disable the Fps counter";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiCheckBoxCtrl(ppShowGfx) {
+         text = "Show Gfx";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         position = "13 40";
+         extent = "127 30";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiCheckBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Enable or Disable the Gfx";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiCheckBoxCtrl(ppShowShadow) {
+         text = "Show Shadow";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         position = "13 56";
+         extent = "127 30";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiCheckBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Enable or Disable the Shdow";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiCheckBoxCtrl(ppShowNet) {
+         text = "Show Net";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         position = "13 136";
+         extent = "127 30";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiCheckBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Enable or Disable the Network activity";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiCheckBoxCtrl(ppShowForest) {
+         text = "Show Forest";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         position = "13 120";
+         extent = "127 30";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiCheckBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Enable or Disable the Forest";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiCheckBoxCtrl(ppShowGroundcover) {
+         text = "Show Groundcover";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         position = "13 104";
+         extent = "127 30";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiCheckBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Enable or Disable the Groundcover";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiCheckBoxCtrl(ppShowTerrain) {
+         text = "Show Terrain";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         position = "13 88";
+         extent = "127 30";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiCheckBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Enable or Disable the Terrain";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiCheckBoxCtrl(ppShowSfx) {
+         text = "Show Sfx";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         position = "13 72";
+         extent = "127 30";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiCheckBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Enable or Disable the Sfx";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(ppOptionsEnableDisable) {
+         text = "On/Off OSD";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "309 38";
+         extent = "93 23";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "showMetrics(true);";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Apply the setting from the dialog box";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(ppOptionsUpdate) {
+         text = "Update";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "200 38";
+         extent = "93 23";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "showMetrics(false);";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Update the profiler with the new parameters";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(ppOptionsDoProfiling) {
+         text = "DoProfiling";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "309 141";
+         extent = "93 23";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "doProfileFromGui();";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Does the profile for the ammount of time specified ";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl(DurationLabel) {
+         text = "Duration[ms]";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "200 144";
+         extent = "39 21";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextRightProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextEditCtrl(Duration) {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         text = "1000";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "249 144";
+         extent = "53 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 125 - 0
Templates/BaseGame/game/data/ui/guis/remapConfirmDlg.gui

@@ -0,0 +1,125 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(RemapConfirmDlg) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 8";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      helpTag = "0";
+
+   new GuiContainer(RemapConfirmationPanel) {
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "168 352";
+      extent = "700 64";
+      minExtent = "8 2";
+      horizSizing = "center";
+      vertSizing = "center";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiChunkedBitmapCtrl() {
+         bitmap = "data/ui/images/hudfill.png";
+         useVariable = "0";
+         tile = "0";
+         position = "0 0";
+         extent = "700 64";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl(RemapConfirmationText) {
+         text = "\"m\" is already bound to \"Forward\"!\nDo you wish to replace this mapping?";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "0 8";
+         extent = "700 20";
+         minExtent = "8 8";
+         horizSizing = "width";
+         vertSizing = "height";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         accelerator = "return";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(RemapConfirmationYesButton) {
+         text = "Yes";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "270 36";
+         extent = "80 22";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "top";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "ControlsMenu.redoMapping(keyboard, \"m\", \"jump\", 0, 4); Canvas.popDialog();";
+         accelerator = "return";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl(RemapConfirmationNoButton) {
+         text = "No";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "367 36";
+         extent = "80 22";
+         minExtent = "8 8";
+         horizSizing = "right";
+         vertSizing = "top";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "Canvas.popDialog();";
+         accelerator = "escape";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 122 - 0
Templates/BaseGame/game/data/ui/guis/remapDlg.gui

@@ -0,0 +1,122 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(RemapDlg) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 8";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      helpTag = "0";
+
+   new GuiContainer(RemapPanel) {
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "162 352";
+      extent = "700 64";
+      minExtent = "8 2";
+      horizSizing = "center";
+      vertSizing = "center";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiInputCtrl(OptRemapInputCtrl) {
+         lockMouse = "0";
+         position = "480 0";
+         extent = "64 64";
+         minExtent = "8 8";
+         horizSizing = "width";
+         vertSizing = "height";
+         profile = "GuiInputCtrlProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiChunkedBitmapCtrl() {
+         bitmap = "data/ui/images/hudfill.png";
+         useVariable = "0";
+         tile = "0";
+         position = "0 0";
+         extent = "700 64";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Press escape to cancel";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "247 34";
+         extent = "242 20";
+         minExtent = "8 8";
+         horizSizing = "width";
+         vertSizing = "height";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Re-bind \"\" to...";
+         maxLength = "255";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "177 8";
+         extent = "384 20";
+         minExtent = "8 8";
+         horizSizing = "width";
+         vertSizing = "height";
+         profile = "GuiMenuButtonProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "OptRemapText";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 157 - 0
Templates/BaseGame/game/data/ui/guis/startupGui.cs

@@ -0,0 +1,157 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// StartupGui is the splash screen that initially shows when the game is loaded
+//-----------------------------------------------------------------------------
+
+function loadStartup()
+{
+   // The index of the current splash screen
+   $StartupIdx = 0;
+
+   // A list of the splash screens and logos
+   // to cycle through. Note that they have to
+   // be in consecutive numerical order
+   StartupGui.bitmap[0]     = "data/ui/images/background-dark";
+   StartupGui.logo[0]       = "data/ui/images/Torque-3D-logo";
+   StartupGui.logoPos[0]    = "178 251";
+   StartupGui.logoExtent[0] = "443 139";
+
+   // Call the next() function to set our firt
+   // splash screen
+   StartupGui.next();
+
+   // Play our startup sound
+   //SFXPlayOnce(AudioGui, "data/ui/sounds/startup");//SFXPlay(startsnd);
+}
+
+function StartupGui::onWake(%this)
+{
+   $enableDirectInput = "1";
+   activateDirectInput();
+}
+
+function StartupGui::click(%this)
+{
+   %this.done = true;
+   %this.onDone();
+}
+
+function StartupGui::next(%this)
+{
+   // Set us to a blank screen while we load the next one
+   Canvas.setContent(BlankGui);
+
+   // Set our bitmap and reset the done variable
+   %this.setBitmap(%this.bitmap[$StartupIdx]);
+   %this.done = false;
+
+   // If we have a logo then set it
+   if (isObject(%this->StartupLogo))
+   {
+      if (%this.logo[$StartupIdx] !$= "")
+      {
+         %this->StartupLogo.setBitmap(%this.logo[$StartupIdx]);
+
+         if (%this.logoPos[$StartupIdx] !$= "")
+         {
+            %logoPosX = getWord(%this.logoPos[$StartupIdx], 0);
+            %logoPosY = getWord(%this.logoPos[$StartupIdx], 1);
+
+            %this->StartupLogo.setPosition(%logoPosX, %logoPosY);
+         }
+
+         if (%this.logoExtent[$StartupIdx] !$= "")
+            %this->StartupLogo.setExtent(%this.logoExtent[$StartupIdx]);
+
+         %this->StartupLogo.setVisible(true);
+      }
+      else
+         %this->StartupLogo.setVisible(false);
+   }
+
+   // If we have a secondary logo then set it
+   if (isObject(%this->StartupLogoSecondary))
+   {
+      if (%this.seclogo[$StartupIdx] !$= "")
+      {
+         %this->StartupLogoSecondary.setBitmap(%this.seclogo[$StartupIdx]);
+
+         if (%this.seclogoPos[$StartupIdx] !$= "")
+         {
+            %logoPosX = getWord(%this.seclogoPos[$StartupIdx], 0);
+            %logoPosY = getWord(%this.seclogoPos[$StartupIdx], 1);
+
+            %this->StartupLogoSecondary.setPosition(%logoPosX, %logoPosY);
+         }
+
+         if (%this.seclogoExtent[$StartupIdx] !$= "")
+            %this->StartupLogoSecondary.setExtent(%this.seclogoExtent[$StartupIdx]);
+
+         %this->StartupLogoSecondary.setVisible(true);
+      }
+      else
+         %this->StartupLogoSecondary.setVisible(false);
+   }
+
+   // Increment our screen index for the next screen
+   $StartupIdx++;
+
+   // Set the Canvas to our newly updated GuiFadeinBitmapCtrl
+   Canvas.setContent(%this);
+}
+
+function StartupGui::onDone(%this)
+{
+   // If we have been tagged as done decide if we need
+   // to end or cycle to the next one
+   if (%this.done)
+   {
+      // See if we have a valid bitmap for the next screen
+      if (%this.bitmap[$StartupIdx] $= "")
+      {
+         // Clear our data and load the main menu
+         %this.done = true;
+         
+         // NOTE: Don't ever ever delete yourself during a callback from C++.
+         //
+         // Deleting the whole gui itself seems a bit excessive, what if we want 
+         // to return to the startup gui at a later time?  Any bitmaps set on 
+         // the controls should be unloaded automatically if the control is not 
+         // awake, if this is not the case then that's what needs to be fixed.
+         
+         //%this.delete();
+         //BlankGui.delete();
+         //flushTextureCache();
+         
+         %mainMenuGUI = ProjectSettings.value("UI/mainMenuName");
+         if (isObject( %mainMenuGUI ))
+            Canvas.setContent( %mainMenuGUI );
+      }
+      else
+      {
+         // We do have a bitmap so cycle to it
+         %this.next();
+      }
+   }
+}

+ 79 - 0
Templates/BaseGame/game/data/ui/guis/startupGui.gui

@@ -0,0 +1,79 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiFadeinBitmapCtrl(StartupGui) {
+   canSaveDynamicFields = "0";
+   Enabled = "1";
+   isContainer = "1";
+   Profile = "GuiInputCtrlProfile";
+   HorizSizing = "right";
+   VertSizing = "bottom";
+   position = "0 0";
+   Extent = "800 600";
+   MinExtent = "8 8";
+   canSave = "1";
+   Visible = "1";
+   tooltipprofile = "GuiToolTipProfile";
+   hovertime = "1000";
+   bitmap = "";
+   wrap = "0";
+   fadeinTime = "1000";
+   waitTime = "4000";
+   fadeoutTime = "1000";
+   done = "1";
+
+   new GuiBitmapButtonCtrl() {
+      canSaveDynamicFields = "1";
+      internalName = "StartupLogo";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiDefaultProfile";
+      HorizSizing = "center";
+      VertSizing = "center";
+      position = "399 302";
+      Extent = "253  253";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      tooltipprofile = "GuiToolTipProfile";
+      hovertime = "1000";
+      bitmap = "";
+      wrap = "0";
+      command = "StartupGui.click();";
+   };
+   new GuiBitmapButtonCtrl() {
+      canSaveDynamicFields = "1";
+      internalName = "StartupLogoSecondary";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiDefaultProfile";
+      HorizSizing = "left";
+      VertSizing = "top";
+      position = "275 440";
+      Extent = "530 171";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      tooltipprofile = "GuiToolTipProfile";
+      hovertime = "1000";
+      bitmap = "";
+      wrap = "0";
+      command = "StartupGui.click();";
+   };
+};
+//--- OBJECT WRITE END ---
+//--- OBJECT WRITE BEGIN ---
+new GuiFadeinBitmapCtrl(BlankGui) {
+   profile = "GuiInputCtrlProfile";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   position = "0 0";
+   extent = "800 600";
+   minExtent = "8 8";
+   visible = "1";
+   helpTag = "0";
+   bitmap = "";
+   wrap = "0";
+   fadeinTime = "100";
+   waitTime   = "2000";
+   fadeoutTime = "100";
+};
+//--- OBJECT WRITE END ---

BIN
Templates/BaseGame/game/data/ui/images/BackgroundImage.png


BIN
Templates/BaseGame/game/data/ui/images/ScreenBrightness_Dark.png


BIN
Templates/BaseGame/game/data/ui/images/ScreenBrightness_Light.png


BIN
Templates/BaseGame/game/data/ui/images/Torque-3D-logo-shortcut.png


BIN
Templates/BaseGame/game/data/ui/images/Torque-3D-logo-w.png


BIN
Templates/BaseGame/game/data/ui/images/Torque-3D-logo.png


BIN
Templates/BaseGame/game/data/ui/images/Torque-3D-logo_alt.png


BIN
Templates/BaseGame/game/data/ui/images/background-dark.png


BIN
Templates/BaseGame/game/data/ui/images/background.png


BIN
Templates/BaseGame/game/data/ui/images/buttontab.png


BIN
Templates/BaseGame/game/data/ui/images/chatHudBorderArray.png


BIN
Templates/BaseGame/game/data/ui/images/checkbox.png


BIN
Templates/BaseGame/game/data/ui/images/clear-btn_d.png


BIN
Templates/BaseGame/game/data/ui/images/clear-btn_h.png


BIN
Templates/BaseGame/game/data/ui/images/clear-btn_n.png


BIN
Templates/BaseGame/game/data/ui/images/collapse-toolbar_d.png


BIN
Templates/BaseGame/game/data/ui/images/collapse-toolbar_h.png


BIN
Templates/BaseGame/game/data/ui/images/collapse-toolbar_n.png


BIN
Templates/BaseGame/game/data/ui/images/defaultCursor.png


BIN
Templates/BaseGame/game/data/ui/images/dropDown.png


BIN
Templates/BaseGame/game/data/ui/images/dropdown-button-arrow.png


Some files were not shown because too many files changed in this diff