Sfoglia il codice sorgente

Merge pull request #1968 from Areloch/FillInBaseGame

Fill in base game
Areloch 8 anni fa
parent
commit
6d269f2960

+ 463 - 43
Templates/BaseGame/game/core/helperFunctions.cs

@@ -470,51 +470,9 @@ function AggregateControl::callMethod(%this, %method, %args)
 
 }
 
-// A function used in order to easily parse the MissionGroup for classes . I'm pretty 
-// sure at this point the function can be easily modified to search the any group as well.
-function parseMissionGroup( %className, %childGroup )
-{
-   if( getWordCount( %childGroup ) == 0)
-      %currentGroup = "MissionGroup";
-   else
-      %currentGroup = %childGroup;
-      
-   for(%i = 0; %i < (%currentGroup).getCount(); %i++)
-   {      
-      if( (%currentGroup).getObject(%i).getClassName() $= %className )
-         return true;
-      
-      if( (%currentGroup).getObject(%i).getClassName() $= "SimGroup" )
-      {
-         if( parseMissionGroup( %className, (%currentGroup).getObject(%i).getId() ) )
-            return true;         
-      }
-   } 
-}
-
-// A variation of the above used to grab ids from the mission group based on classnames
-function parseMissionGroupForIds( %className, %childGroup )
-{
-   if( getWordCount( %childGroup ) == 0)
-      %currentGroup = "MissionGroup";
-   else
-      %currentGroup = %childGroup;
-      
-   for(%i = 0; %i < (%currentGroup).getCount(); %i++)
-   {      
-      if( (%currentGroup).getObject(%i).getClassName() $= %className )
-         %classIds = %classIds @ (%currentGroup).getObject(%i).getId() @ " ";
-      
-      if( (%currentGroup).getObject(%i).getClassName() $= "SimGroup" )
-         %classIds = %classIds @ parseMissionGroupForIds( %className, (%currentGroup).getObject(%i).getId());
-   } 
-   return trim( %classIds );
-}
-
 //------------------------------------------------------------------------------
 // Altered Version of TGB's QuickEditDropDownTextEditCtrl
 //------------------------------------------------------------------------------
-
 function QuickEditDropDownTextEditCtrl::onRenameItem( %this )
 {
 }
@@ -531,4 +489,466 @@ function QuickEditDropDownTextEditCtrl::updateFromChild( %this, %ctrl )
       %popup.changeTextById( %popup.getSelected(), %ctrl.getText() );
       %this.onRenameItem();
    }
-}
+}
+
+// Writes out all script functions to a file.
+function writeOutFunctions()
+{
+   new ConsoleLogger(logger, "scriptFunctions.txt", false);
+   dumpConsoleFunctions();
+   logger.delete();
+}
+
+// Writes out all script classes to a file.
+function writeOutClasses()
+{
+   new ConsoleLogger(logger, "scriptClasses.txt", false);
+   dumpConsoleClasses();
+   logger.delete();
+}
+
+//
+function compileFiles(%pattern)
+{  
+   %path = filePath(%pattern);
+
+   %saveDSO    = $Scripts::OverrideDSOPath;
+   %saveIgnore = $Scripts::ignoreDSOs;
+   
+   $Scripts::OverrideDSOPath  = %path;
+   $Scripts::ignoreDSOs       = false;
+   %mainCsFile = makeFullPath("main.cs");
+
+   for (%file = findFirstFileMultiExpr(%pattern); %file !$= ""; %file = findNextFileMultiExpr(%pattern))
+   {
+      // we don't want to try and compile the primary main.cs
+      if(%mainCsFile !$= %file)      
+         compile(%file, true);
+   }
+
+   $Scripts::OverrideDSOPath  = %saveDSO;
+   $Scripts::ignoreDSOs       = %saveIgnore;
+   
+}
+
+function displayHelp() 
+{
+   // Notes on logmode: console logging is written to console.log.
+   // -log 0 disables console logging.
+   // -log 1 appends to existing logfile; it also closes the file
+   // (flushing the write buffer) after every write.
+   // -log 2 overwrites any existing logfile; it also only closes
+   // the logfile when the application shuts down.  (default)
+
+   error(
+      "Torque Demo command line options:\n"@
+      "  -log <logmode>         Logging behavior; see main.cs comments for details\n"@
+      "  -game <game_name>      Reset list of mods to only contain <game_name>\n"@
+      "  <game_name>            Works like the -game argument\n"@
+      "  -dir <dir_name>        Add <dir_name> to list of directories\n"@
+      "  -console               Open a separate console\n"@
+      "  -jSave  <file_name>    Record a journal\n"@
+      "  -jPlay  <file_name>    Play back a journal\n"@
+      "  -help                  Display this help message\n"
+   );
+}
+
+// Execute startup scripts for each mod, starting at base and working up
+function loadDir(%dir)
+{
+   pushback($userDirs, %dir, ";");
+
+   if (isScriptFile(%dir @ "/main.cs"))
+   exec(%dir @ "/main.cs");
+}
+
+function loadDirs(%dirPath)
+{
+   %dirPath = nextToken(%dirPath, token, ";");
+   if (%dirPath !$= "")
+      loadDirs(%dirPath);
+
+   if(exec(%token @ "/main.cs") != true)
+   {
+      error("Error: Unable to find specified directory: " @ %token );
+      $dirCount--;
+   }
+}
+
+//------------------------------------------------------------------------------
+// Utility remap functions:
+//------------------------------------------------------------------------------
+
+function ActionMap::copyBind( %this, %otherMap, %command )
+{
+   if ( !isObject( %otherMap ) )
+   {
+      error( "ActionMap::copyBind - \"" @ %otherMap @ "\" is not an object!" );
+      return;
+   }
+
+   %bind = %otherMap.getBinding( %command );
+   if ( %bind !$= "" )
+   {
+      %device = getField( %bind, 0 );
+      %action = getField( %bind, 1 );
+      %flags = %otherMap.isInverted( %device, %action ) ? "SDI" : "SD";
+      %deadZone = %otherMap.getDeadZone( %device, %action );
+      %scale = %otherMap.getScale( %device, %action );
+      %this.bind( %device, %action, %flags, %deadZone, %scale, %command );
+   }
+}
+
+//------------------------------------------------------------------------------
+function ActionMap::blockBind( %this, %otherMap, %command )
+{
+   if ( !isObject( %otherMap ) )
+   {
+      error( "ActionMap::blockBind - \"" @ %otherMap @ "\" is not an object!" );
+      return;
+   }
+
+   %bind = %otherMap.getBinding( %command );
+   if ( %bind !$= "" )
+      %this.bind( getField( %bind, 0 ), getField( %bind, 1 ), "" );
+}
+
+//Dev helpers
+/// Shortcut for typing dbgSetParameters with the default values torsion uses.
+function dbgTorsion()
+{
+   dbgSetParameters( 6060, "password", false );
+}
+
+/// Reset the input state to a default of all-keys-up.
+/// A helpful remedy for when Torque misses a button up event do to your breakpoints
+/// and can't stop shooting / jumping / strafing.
+function mvReset()
+{
+   for ( %i = 0; %i < 6; %i++ )
+      setVariable( "mvTriggerCount" @ %i, 0 );
+      
+   $mvUpAction = 0;
+   $mvDownAction = 0;
+   $mvLeftAction = 0;
+   $mvRightAction = 0;
+   
+   // There are others.
+}
+
+//Persistance Manager tests
+
+new PersistenceManager(TestPManager);
+
+function runPManTest(%test)
+{
+   if (!isObject(TestPManager))
+      return;
+
+   if (%test $= "")
+      %test = 100;
+
+   switch(%test)
+   {
+      case 0:
+         TestPManager.testFieldUpdates();
+      case 1:
+         TestPManager.testObjectRename();
+      case 2:
+         TestPManager.testNewObject();
+      case 3:
+         TestPManager.testNewGroup();
+      case 4:
+         TestPManager.testMoveObject();
+      case 5:
+         TestPManager.testObjectRemove();
+      case 100:
+         TestPManager.testFieldUpdates();
+         TestPManager.testObjectRename();
+         TestPManager.testNewObject();
+         TestPManager.testNewGroup();
+         TestPManager.testMoveObject();
+         TestPManager.testObjectRemove();
+   }
+}
+
+function TestPManager::testFieldUpdates(%doNotSave)
+{
+   // Set some objects as dirty
+   TestPManager.setDirty(AudioGui);
+   TestPManager.setDirty(AudioSim);
+   TestPManager.setDirty(AudioMessage);
+
+   // Alter some of the existing fields
+   AudioEffect.isLooping         = true;
+   AudioMessage.isLooping     = true;
+   AudioEffect.is3D              = true;
+
+   // Test removing a field
+   TestPManager.removeField(AudioGui, "isLooping");
+
+   // Alter some of the persistent fields
+   AudioGui.referenceDistance     = 0.8;
+   AudioMessage.referenceDistance = 0.8;
+
+   // Add some new dynamic fields
+   AudioGui.foo = "bar";
+   AudioEffect.foo = "bar";
+
+   // Remove an object from the dirty list
+   // It shouldn't get updated in the file
+   TestPManager.removeDirty(AudioEffect);
+
+   // Dirty an object in another file as well
+   TestPManager.setDirty(WarningMaterial);
+
+   // Update a field that doesn't exist
+   WarningMaterial.glow[0] = true;
+
+   // Drity another object to test for crashes
+   // when a dirty object is deleted
+   TestPManager.setDirty(SFXPausedSet);
+
+   // Delete the object
+   SFXPausedSet.delete();
+
+   // Unless %doNotSave is set (by a batch/combo test)
+   // then go ahead and save now
+   if (!%doNotSave)
+      TestPManager.saveDirty();
+}
+
+function TestPManager::testObjectRename(%doNotSave)
+{
+   // Flag an object as dirty
+   if (isObject(AudioGui))
+      TestPManager.setDirty(AudioGui);
+   else if (isObject(AudioGuiFoo))
+      TestPManager.setDirty(AudioGuiFoo);
+
+   // Rename it
+   if (isObject(AudioGui))
+      AudioGui.setName(AudioGuiFoo);
+   else if (isObject(AudioGuiFoo))
+      AudioGuiFoo.setName(AudioGui);
+
+   // Unless %doNotSave is set (by a batch/combo test)
+   // then go ahead and save now
+   if (!%doNotSave)
+      TestPManager.saveDirty();
+}
+
+function TestPManager::testNewObject(%doNotSave)
+{
+   // Test adding a new named object
+   new SFXDescription(AudioNew)
+   {
+      volume = 0.5;
+      isLooping = true;
+      channel  = $GuiAudioType;
+      foo = 2;
+   };
+
+   // Flag it as dirty
+   TestPManager.setDirty(AudioNew, "core/scripts/client/audio.cs");
+
+   // Test adding a new unnamed object
+   %obj = new SFXDescription()
+   {
+      volume = 0.75;
+      isLooping = true;
+      bar = 3;
+   };
+
+   // Flag it as dirty
+   TestPManager.setDirty(%obj, "core/scripts/client/audio.cs");
+
+   // Test adding an "empty" object
+   new SFXDescription(AudioEmpty);
+
+   TestPManager.setDirty(AudioEmpty, "core/scripts/client/audio.cs");
+
+   // Unless %doNotSave is set (by a batch/combo test)
+   // then go ahead and save now
+   if (!%doNotSave)
+      TestPManager.saveDirty();
+}
+
+function TestPManager::testNewGroup(%doNotSave)
+{
+   // Test adding a new named SimGroup
+   new SimGroup(TestGroup)
+   {
+      foo = "bar";
+
+      new SFXDescription(TestObject)
+      {
+         volume = 0.5;
+         isLooping = true;
+         channel  = $GuiAudioType;
+         foo = 1;
+      };
+      new SimGroup(SubGroup)
+      {
+         foo = 2;
+
+         new SFXDescription(SubObject)
+         {
+            volume = 0.5;
+            isLooping = true;
+            channel  = $GuiAudioType;
+            foo = 3;
+         };
+      };
+   };
+
+   // Flag this as dirty
+   TestPManager.setDirty(TestGroup, "core/scripts/client/audio.cs");
+
+   // Test adding a new unnamed SimGroup
+   %group = new SimGroup()
+   {
+      foo = "bar";
+
+      new SFXDescription()
+      {
+         volume = 0.75;
+         channel  = $GuiAudioType;
+         foo = 4;
+      };
+      new SimGroup()
+      {
+         foo = 5;
+
+         new SFXDescription()
+         {
+            volume = 0.75;
+            isLooping = true;
+            channel  = $GuiAudioType;
+            foo = 6;
+         };
+      };
+   };
+
+   // Flag this as dirty
+   TestPManager.setDirty(%group, "core/scripts/client/audio.cs");
+
+   // Test adding a new unnamed SimSet
+   %set = new SimSet()
+   {
+      foo = "bar";
+
+      new SFXDescription()
+      {
+         volume = 0.75;
+         channel  = $GuiAudioType;
+         foo = 7;
+      };
+      new SimGroup()
+      {
+         foo = 8;
+
+         new SFXDescription()
+         {
+            volume = 0.75;
+            isLooping = true;
+            channel  = $GuiAudioType;
+            foo = 9;
+         };
+      };
+   };
+
+   // Flag this as dirty
+   TestPManager.setDirty(%set, "core/scripts/client/audio.cs");
+
+   // Unless %doNotSave is set (by a batch/combo test)
+   // then go ahead and save now
+   if (!%doNotSave)
+      TestPManager.saveDirty();
+}
+
+function TestPManager::testMoveObject(%doNotSave)
+{
+   // First add a couple of groups to the file
+   new SimGroup(MoveGroup1)
+   {
+      foo = "bar";
+
+      new SFXDescription(MoveObject1)
+      {
+         volume = 0.5;
+         isLooping = true;
+         channel  = $GuiAudioType;
+         foo = 1;
+      };
+
+      new SimSet(SubGroup1)
+      {
+         new SFXDescription(SubObject1)
+         {
+            volume = 0.75;
+            isLooping = true;
+            channel  = $GuiAudioType;
+            foo = 2;
+         };
+      };
+   };
+
+   // Flag this as dirty
+   TestPManager.setDirty(MoveGroup1, "core/scripts/client/audio.cs");
+
+   new SimGroup(MoveGroup2)
+   {
+      foo = "bar";
+
+      new SFXDescription(MoveObject2)
+      {
+         volume = 0.5;
+         isLooping = true;
+         channel  = $GuiAudioType;
+         foo = 3;
+      };
+   };
+
+   // Flag this as dirty
+   TestPManager.setDirty(MoveGroup2, "core/scripts/client/audio.cs");
+
+   // Unless %doNotSave is set (by a batch/combo test)
+   // then go ahead and save now
+   if (!%doNotSave)
+      TestPManager.saveDirty();
+
+   // Set them as dirty again
+   TestPManager.setDirty(MoveGroup1);
+   TestPManager.setDirty(MoveGroup2);
+
+   // Give the subobject an new value
+   MoveObject1.foo = 4;
+
+   // Move it into the other group
+   MoveGroup1.add(MoveObject2);
+
+   // Switch the other subobject
+   MoveGroup2.add(MoveObject1);
+
+   // Also add a new unnamed object to one of the groups
+   %obj = new SFXDescription()
+   {
+      volume = 0.75;
+      isLooping = true;
+      bar = 5;
+   };
+
+   MoveGroup1.add(%obj);
+
+   // Unless %doNotSave is set (by a batch/combo test)
+   // then go ahead and save now
+   if (!%doNotSave)
+      TestPManager.saveDirty();
+}
+
+function TestPManager::testObjectRemove(%doNotSave)
+{
+   TestPManager.removeObjectFromFile(AudioSim);
+}
+

+ 3 - 0
Templates/BaseGame/game/core/main.cs

@@ -86,5 +86,8 @@ exec("./gfxData/clouds.cs");
 // Initialize all core post effects.   
 exec("./postFx.cs");
 
+//VR stuff
+exec("./oculusVR.cs");
+
 // Seed the random number generator.
 setRandomSeed();

+ 248 - 0
Templates/BaseGame/game/core/oculusVR.cs

@@ -0,0 +1,248 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Only load these functions if an Oculus VR device is present
+if(!isFunction(isOculusVRDeviceActive))
+   return;
+
+function setupOculusActionMaps()
+{
+   if (isObject(OculusWarningMap))
+      return;
+
+   new ActionMap(OculusWarningMap);
+   new ActionMap(OculusCanvasMap);
+
+   OculusWarningMap.bind(keyboard, space, dismissOculusVRWarnings);
+
+   OculusCanvasMap.bind( mouse, xaxis, oculusYaw );
+   OculusCanvasMap.bind( mouse, yaxis, oculusPitch );
+   OculusCanvasMap.bind( mouse, button0, oculusClick );
+}
+
+function oculusYaw(%val)
+{
+   OculusCanvas.cursorNudge(%val * 0.10, 0);
+}
+
+function oculusPitch(%val)
+{
+   OculusCanvas.cursorNudge(0, %val * 0.10);
+}
+
+function oculusClick(%active)
+{
+   OculusCanvas.cursorClick(0, %active);  
+}
+
+function GuiOffscreenCanvas::checkCursor(%this)
+{
+   %count = %this.getCount();
+   for(%i = 0; %i < %count; %i++)
+   {
+      %control = %this.getObject(%i);
+      if ((%control.noCursor $= "") || !%control.noCursor)
+      {
+         %this.cursorOn();
+         return true;
+      }
+   }
+   // If we get here, every control requested a hidden cursor, so we oblige.
+
+   %this.cursorOff();
+   return false;
+}
+
+function GuiOffscreenCanvas::pushDialog(%this, %ctrl, %layer, %center)
+{
+   Parent::pushDialog(%this, %ctrl, %layer, %center);
+   %cursorVisible = %this.checkCursor();
+
+   if (%cursorVisible)
+   {
+      echo("OffscreenCanvas visible");
+      OculusCanvasMap.pop();
+      OculusCanvasMap.push();
+   }
+   else
+   {
+      echo("OffscreenCanvas not visible");
+      OculusCanvasMap.pop();
+   }
+}
+
+function GuiOffscreenCanvas::popDialog(%this, %ctrl)
+{
+   Parent::popDialog(%this, %ctrl);
+   %cursorVisible = %this.checkCursor();
+
+   if (%cursorVisible)
+   {
+      echo("OffscreenCanvas visible");
+      OculusCanvasMap.pop();
+      OculusCanvasMap.push();
+   }
+   else
+   {
+      echo("OffscreenCanvas not visible");
+      OculusCanvasMap.pop();
+   }
+}
+
+
+//-----------------------------------------------------------------------------
+
+function oculusSensorMetricsCallback()
+{
+   return ovrDumpMetrics(0);
+}
+
+
+//-----------------------------------------------------------------------------
+function onOculusStatusUpdate(%status)
+{
+   $LastOculusTrackingState = %status;
+}
+
+//-----------------------------------------------------------------------------
+
+// Call this function from createCanvas() to have the Canvas attach itself
+// to the Rift's display.  The Canvas' window will still open on the primary
+// display if that is different from the Rift, but it will move to the Rift
+// when it goes full screen.  If the Rift is not connected then nothing
+// will happen.
+function pointCanvasToOculusVRDisplay()
+{
+   $pref::Video::displayOutputDevice = getOVRHMDDisplayDeviceName(0);
+}
+
+//-----------------------------------------------------------------------------
+
+// Call this function from GameConnection::initialControlSet() just before
+// your "Canvas.setContent(PlayGui);" call, or at any time you wish to switch
+// to a side-by-side rendering and the appropriate barrel distortion.  This
+// will turn on side-by-side rendering and tell the GameConnection to use the
+// Rift as its display device.
+// Parameters:
+// %gameConnection - The client GameConnection instance
+// %trueStereoRendering - If true will enable stereo rendering with an eye
+// offset for each viewport.  This will render each frame twice.  If false
+// then a pseudo stereo rendering is done with only a single render per frame.
+function enableOculusVRDisplay(%gameConnection, %trueStereoRendering)
+{
+   setOVRHMDAsGameConnectionDisplayDevice(%gameConnection);
+   PlayGui.renderStyle = "stereo side by side";
+   setOptimalOVRCanvasSize(Canvas);
+
+   if (!isObject(OculusCanvas))
+   {
+      new GuiOffscreenCanvas(OculusCanvas) {
+         targetSize = "512 512";
+         targetName = "oculusCanvas";
+         dynamicTarget = true;
+      };
+   }
+
+   if (!isObject(OculusVROverlay))
+   {
+      exec("./oculusVROverlay.gui");
+   }
+
+   OculusCanvas.setContent(OculusVROverlay);
+   OculusCanvas.setCursor(DefaultCursor);
+   PlayGui.setStereoGui(OculusCanvas);
+   OculusCanvas.setCursorPos("128 128");
+   OculusCanvas.cursorOff();
+   $GameCanvas = OculusCanvas;
+
+   %ext = Canvas.getExtent();
+   $OculusMouseScaleX = 512.0 / 1920.0;
+   $OculusMouseScaleY = 512.0 / 1060.0;
+   
+   //$gfx::wireframe = true;
+   // Reset all sensors
+   ovrResetAllSensors();
+}
+
+// Call this function when ever you wish to turn off the stereo rendering
+// and barrel distortion for the Rift.
+function disableOculusVRDisplay(%gameConnection)
+{
+   OculusCanvas.popDialog();
+   OculusWarningMap.pop();
+   $GameCanvas = Canvas;
+
+   if (isObject(gameConnection))
+   {
+      %gameConnection.clearDisplayDevice();
+   }
+   PlayGui.renderStyle = "standard";
+}
+
+// Helper function to set the standard Rift control scheme.  You could place
+// this function in GameConnection::initialControlSet() at the same time
+// you call enableOculusVRDisplay().
+function setStandardOculusVRControlScheme(%gameConnection)
+{
+   if($OculusVR::SimulateInput)
+   {
+      // We are simulating a HMD so allow the mouse and gamepad to control
+      // both yaw and pitch.
+      %gameConnection.setControlSchemeParameters(true, true, true);
+   }
+   else
+   {
+      // A HMD is connected so have the mouse and gamepad only add to yaw
+      %gameConnection.setControlSchemeParameters(true, true, false);
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+// Helper function to set the resolution for the Rift.
+// Parameters:
+// %fullscreen - If true then the display will be forced to full screen.  If
+// pointCanvasToOculusVRDisplay() was called before the Canvas was created, then
+// the full screen display will appear on the Rift.
+function setVideoModeForOculusVRDisplay(%fullscreen)
+{
+   %res = getOVRHMDResolution(0);
+   Canvas.setVideoMode(%res.x, %res.y, %fullscreen, 32, 4);
+}
+
+//-----------------------------------------------------------------------------
+
+// Reset all Oculus Rift sensors.  This will make the Rift's current heading
+// be considered the origin.
+function resetOculusVRSensors()
+{
+   ovrResetAllSensors();
+}
+
+function dismissOculusVRWarnings(%value)
+{
+   //if (%value)
+   //{
+      ovrDismissWarnings();
+      OculusWarningMap.pop();
+   //}
+}

+ 19 - 0
Templates/BaseGame/game/core/oculusVROverlay.gui

@@ -0,0 +1,19 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = singleton GuiControl(OculusVROverlay) {
+   canSaveDynamicFields = "0";
+   Enabled = "1";
+   isContainer = "1";
+   Profile = "GuiContentProfile";
+   HorizSizing = "width";
+   VertSizing = "height";
+   Position = "0 0";
+   Extent = "512 512";
+   MinExtent = "8 8";
+   canSave = "1";
+   Visible = "1";
+   tooltipprofile = "GuiToolTipProfile";
+   hovertime = "1000";
+   useVariable = "0";
+   tile = "0";
+};
+//--- OBJECT WRITE END ---

+ 41 - 0
Templates/BaseGame/game/data/clientServer/scripts/server/kickban.cs

@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------------
+// 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 kick(%client)
+{
+   messageAll( 'MsgAdminForce', '\c2The Admin has kicked %1.', %client.playerName);
+
+   if (!%client.isAIControlled())
+      BanList::add(%client.guid, %client.getAddress(), $Pref::Server::KickBanTime);
+   %client.delete("You have been kicked from this server");
+}
+
+function ban(%client)
+{
+   messageAll('MsgAdminForce', '\c2The Admin has banned %1.', %client.playerName);
+
+   if (!%client.isAIControlled())
+      BanList::add(%client.guid, %client.getAddress(), $Pref::Server::BanTime);
+   %client.delete("You have been banned from this server");
+}

+ 5 - 1
Templates/BaseGame/game/data/clientServer/scripts/server/server.cs

@@ -33,6 +33,7 @@ function initServer()
    
    exec( "data/clientServer/scripts/server/audio.cs" );
    exec( "data/clientServer/scripts/server/commands.cs" );
+   exec( "data/clientServer/scripts/server/kickban.cs" );
    exec( "data/clientServer/scripts/server/message.cs" );
    exec( "data/clientServer/scripts/server/levelDownload.cs" );
    exec( "data/clientServer/scripts/server/levelLoad.cs" );
@@ -219,8 +220,11 @@ function destroyServer()
    deleteDataBlocks();
    
    // Save any server settings
+   %prefPath = getPrefpath();
    echo( "Exporting server prefs..." );
-   export( "$Pref::Server::*", "data/clientServer/scripts/server/prefs.cs", false );
+   export( "$Pref::Server::*", %prefPath@"/serverPrefs.cs", false );
+   
+   BanList::Export(%prefPath@"/banlist.cs");
 
    // Increase the server session number.  This is used to make sure we're
    // working with the server session we think we are.

+ 12 - 1
Templates/BaseGame/game/data/ui/UI.cs

@@ -39,6 +39,9 @@ function UI::create( %this )
    
    exec("./scripts/guis/profiler.gui");
    exec("./scripts/guis/netGraphGui.gui");
+   exec("./scripts/guis/FileDialog.gui");
+   exec("./scripts/guis/guiMusicPlayer.gui");
+   exec("./scripts/guis/startupGui.gui");
    
    //Load gui companion scripts
    exec("./scripts/chooseLevelDlg.cs");
@@ -51,10 +54,18 @@ function UI::create( %this )
    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);
    
-   Canvas.pushDialog(MainMenuGui);
+   loadStartup();
+   //Canvas.pushDialog(MainMenuGui);
 }
 
 function Game::destroy( %this )

+ 306 - 0
Templates/BaseGame/game/data/ui/scripts/FileDialog.cs

@@ -0,0 +1,306 @@
+function PlatformFileDialog::buildFilters(%this)
+{
+   %str = strreplace( %this.data.filters, "|", "\t");
+   %this.filterCount = getFieldCount( %str ) / 2;
+   //echo( "Filter count: " @  %str );
+   for( %i = 0; %i < %this.filterCount; %i++ )
+   {
+      %this.filterName[%i] = GetField( %str, (%i*2) + 0 );
+      %this.filter[%i] = strreplace( GetField( %str, (%i*2) + 1 ), ";", "\t");
+      //echo( "Filter: " @  %this.filterName[%i] @ " - " @ %this.filter[%i]);
+   }   
+}
+
+function PlatformFileDialog::handleFlags(%this, %flags)
+{
+   %this.FDS_OPEN = false;
+   %this.FDS_SAVE = false;
+   %this.FDS_OVERWRITEPROMPT = false;
+   %this.FDS_MUSTEXIST = false;
+   %this.FDS_BROWSEFOLDER = false;
+   
+   %flagCount = getFieldCount( %flags );
+   
+   //echo( "flag count: " @ %flagCount );   
+   
+   for( %i = 0; %i < %flagCount; %i++ )
+   {
+      %flag = GetField( %flags, %i );
+      //echo(%flag);
+      if( %flag $= "FDS_OPEN" )
+      {
+         %this.FDS_OPEN = true;
+         %this-->Button.setText( "OPEN" );
+         %this-->Button.command = "PlatformFileDialog.tryFile();";
+         %this-->window.text = "Select file to OPEN";
+      }
+      else if( %flag $= "FDS_SAVE" )
+      {
+         %this.FDS_SAVE = true;
+         %this-->Button.setText( "SAVE" );
+         %this-->Button.command = "PlatformFileDialog.tryFile();";
+         %this-->window.text = "Select file to Save";
+      }
+      else if( %flag $= "FDS_OVERWRITEPROMPT" )
+      {
+         %this.FDS_OVERWRITEPROMPT = true;
+      }
+      else if( %flag $= "FDS_MUSTEXIST" )
+      {
+         %this.FDS_MUSTEXIST = true;
+      }
+      else if( %flag $= "FDS_BROWSEFOLDER" )
+      {
+         %this.FDS_BROWSEFOLDER = true;
+         %this-->window.text = "Select folder to OPEN";
+      }
+   }   
+}
+
+function OpenPlatformFileDialog(%data, %flags)
+{
+   PlatformFileDialog.searchDir = "";
+   PlatformFileDialog-->fileNameEdit.setText( "" );
+   PlatformFileDialog.data = %data;
+   PlatformFileDialog.data.finished = 0;
+   
+   PlatformFileDialog.handleFlags( %flags );
+   
+   if( !isObject(PlatformFileDialog.freeItemSet) )
+   {
+      PlatformFileDialog.freeItemSet = new SimGroup();
+   }
+   
+   PlatformFileDialog.buildFilters();
+   
+   Canvas.pushDialog(PlatformFileDialog);
+}
+
+function PlatformFileDialog::changeDir( %this, %newDir )
+{     
+   %this.searchDir = %newDir;
+   %this.update();
+}
+
+function PlatformFileDialog::navigateUp( %this )
+{
+   //echo( "PlatformFileDialog::navigateUp " @ %this.searchDir );
+   if( %this.searchDir !$= "" )
+   {      
+      %str = strreplace( %this.searchDir, "/", "\t");
+      %count = getFieldCount( %str );
+      
+      if ( %count == 0 )
+         return;
+         
+      if ( %count == 1 )
+         %address = "";
+      else      
+         %address = getFields( %str, 0, %count - 2 );
+         
+      %newDir = strreplace( %address, "\t", "/" );
+      
+      if( %newDir !$= "" )
+         %newDir = %newDir @ "/";
+      
+      %this.changeDir( %newDir );
+      
+   }
+}
+
+function PlatformFileDialog::cancel( %this )
+{
+   %this.data.files[0] = "";
+   %this.data.fileCount = 0;
+   %this.data.finished = 1;
+   
+   Canvas.popDialog(%this);
+}
+
+function FileDialogItem::onClick( %this )
+{
+   PlatformFileDialog-->fileNameEdit.setText( "" );
+   
+   if( %this.isDir && %this.FDS_BROWSEFOLDER)
+   {
+      PlatformFileDialog-->fileNameEdit.setText( %this.text );
+   }
+   else if( !%this.isDir && !%this.FDS_BROWSEFOLDER )
+   {
+      PlatformFileDialog-->fileNameEdit.setText( %this.text );
+   }
+}
+
+function FileDialogItem::onDoubleClick( %this )
+{
+   PlatformFileDialog-->fileNameEdit.setText( "" );
+   
+   if( %this.isDir )
+   {
+      PlatformFileDialog.changeDir( PlatformFileDialog.searchDir @ %this.text @ "/" );
+   }
+}
+
+function PlatformFileDialog::tryFile( %this )
+{
+   %file = %this-->fileNameEdit.getText();
+   if( %file $= "" )
+      return;
+      
+   if( %this.FDS_OVERWRITEPROMPT )
+   {
+      %callback = "PlatformFileDialog.onFile( \"" @ %file @ "\" );";
+      MessageBoxOKCancel("Confirm overwrite", "Confirm overwrite", %callback, "");
+      return;
+   }
+   
+   %this.onFile( %file );
+}
+
+function PlatformFileDialog::onFile( %this, %file )
+{
+   %this.data.files[0] = "";
+   %this.data.fileCount = 0;   
+   
+   if( %file !$= "" )
+   {
+      %file = %this.searchDir @ %file;
+      %this.data.fileCount = 1;
+   }
+   
+   if( %this.FDS_BROWSEFOLDER && !isDirectory( %file ) )
+   {
+      echo("Select a directory");
+      return;
+   }
+   else if( !%this.FDS_BROWSEFOLDER && !isFile( %file ) )
+   {
+      echo("Select a file");
+      return;
+   }
+   
+   if( %this.FDS_MUSTEXIST )
+   {
+      if( !isFile( %file ) && !isDirectory( %file ) )
+      {
+         echo("Target must exist: " @ %file );
+         return;
+      }
+   }  
+   
+   %this.data.finished = 1;
+   %this.data.files[0] = %file;
+   
+   Canvas.popDialog(%this);
+   
+   %this-->fileNameEdit.setText( "" );
+}
+
+function PlatformFileDialog::clear( %this )
+{
+   %itemArray = %this-->itemArray;
+   
+   while( %itemArray.getCount() )
+   {
+      %item = %itemArray.getObject( 0 );
+      %this.freeItem( %item );      
+   }
+}
+
+function PlatformFileDialog::getNewItem( %this )
+{
+   if( %this.freeItemSet.getCount() )
+      %item = %this.freeItemSet.getObject( 0 );
+   
+   if( isObject(%item) )
+   {
+      %this.freeItemSet.remove( %item );
+   }
+   else
+   {
+      //create new
+      %item = new GuiIconButtonCtrl();
+      %item.className = "FileDialogItem";
+      %item.profile = "ToolsGuiIconButtonProfile";
+      %item.textLocation = "left";
+      %item.iconLocation = "left";
+      %item.iconBitmap = "";
+      %item.text = "";
+   }  
+   
+   return %item;
+}
+
+function PlatformFileDialog::freeItem( %this, %item )
+{
+   %this-->itemArray.remove( %item );
+   
+   //clear
+   %item.setText( "" );
+   %item.iconBitmap = "";
+   %item.textMargin = 0;
+   %item.textLocation = "left";
+   %item.iconLocation = "left";
+   %item.resetState();
+   
+   PlatformFileDialog.freeItemSet.add( %item );
+}
+
+function PlatformFileDialog::addDir( %this, %dir )
+{
+   //echo( "Dir: " @ %dir );
+   %item = %this.getNewItem();
+   %item.setText( %dir );
+   %item.isDir = true;
+   %item.iconBitmap = "core/art/gui/images/folder";
+   %item.textLocation = "left";
+   %item.iconLocation = "left";
+   %item.textMargin = 24;
+   %this-->itemArray.add( %item );
+}
+
+function PlatformFileDialog::addFile( %this, %file )
+{
+   //echo( "File: " @ %file );
+   %item = %this.getNewItem();
+   %item.text = strreplace( %file, %this.searchDir, "" );
+   %item.isDir = false;
+   %this-->itemArray.add( %item );
+}
+
+function PlatformFileDialog::onWake( %this )
+{
+   %this.update();
+}
+
+function PlatformFileDialog::onSleep( %this )
+{
+   %this.data.finished = 1;
+}
+
+function PlatformFileDialog::update( %this )
+{
+   %this.clear();
+   
+   %this-->popUpMenu.text = %this.searchDir;
+
+   // dirs
+   %dirList = getDirectoryList( %this.searchDir, 0 );
+   %wordCount = getFieldCount( %dirList );
+   for( %i = 0; %i < %wordCount; %i++ )
+   {
+      %dirItem = GetField( %dirList, %i );
+      %this.addDir( %dirItem );
+   }
+   
+   //files
+   %pattern = %this.filter[0];
+   //echo( %pattern );
+   %file = findFirstFileMultiExpr( %this.searchDir @ %pattern, false);
+   
+   while( %file !$= "" )
+   {      
+      %this.addFile( %file );
+      %file = findNextFileMultiExpr( %pattern );
+   }
+}

+ 40 - 0
Templates/BaseGame/game/data/ui/scripts/cursors.cs

@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------------
+// 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($platform $= "macos")
+{
+   new GuiCursor(DefaultCursor)
+   {
+      hotSpot = "4 4";
+      renderOffset = "0 0";
+      bitmapName = "~/art/gui/images/macCursor";
+   };
+} 
+else 
+{
+   new GuiCursor(DefaultCursor)
+   {
+      hotSpot = "1 1";
+      renderOffset = "0 0";
+      bitmapName = "~/art/gui/images/defaultCursor";
+   };
+}

+ 244 - 0
Templates/BaseGame/game/data/ui/scripts/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;
+}

+ 50 - 0
Templates/BaseGame/game/data/ui/scripts/guiTreeViewCtrl.cs

@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// 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 GuiTreeViewCtrl::onDefineIcons( %this )
+{
+   %icons = "core/art/gui/images/treeview/default:" @
+            "core/art/gui/images/treeview/simgroup:" @
+            "core/art/gui/images/treeview/simgroup_closed:" @
+            "core/art/gui/images/treeview/simgroup_selected:" @
+            "core/art/gui/images/treeview/simgroup_selected_closed:" @      
+            "core/art/gui/images/treeview/hidden:" @      
+            "core/art/gui/images/treeview/shll_icon_passworded_hi:" @
+            "core/art/gui/images/treeview/shll_icon_passworded:" @      
+            "core/art/gui/images/treeview/default";
+              
+   %this.buildIconTable(%icons);   
+}
+
+function GuiTreeViewCtrl::handleRenameObject( %this, %name, %obj )
+{
+   %inspector = GuiInspector::findByObject( %obj );
+   
+   if( isObject( %inspector ) )   
+   {
+      %field = ( %this.renameInternal ) ? "internalName" : "name";      
+      %inspector.setObjectField( %field, %name );
+      return true;
+   }
+   
+   return false;   
+}

+ 293 - 0
Templates/BaseGame/game/data/ui/scripts/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/scripts/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 ---

+ 192 - 0
Templates/BaseGame/game/data/ui/scripts/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 ---

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

@@ -322,340 +322,3 @@
    };
 };
 //--- OBJECT WRITE END ---
-
-$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();
-}
-
-
-// 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);
-}

+ 79 - 0
Templates/BaseGame/game/data/ui/scripts/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 ---

+ 90 - 0
Templates/BaseGame/game/data/ui/scripts/help.cs

@@ -0,0 +1,90 @@
+//-----------------------------------------------------------------------------
+// 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 HelpDlg::onWake(%this)
+{
+   HelpFileList.entryCount = 0;
+   HelpFileList.clear();
+   for(%file = findFirstFile("*.hfl"); %file !$= ""; %file = findNextFile("*.hfl"))
+   {
+      HelpFileList.fileName[HelpFileList.entryCount] = %file;
+      HelpFileList.addRow(HelpFileList.entryCount, fileBase(%file));
+      HelpFileList.entryCount++;
+   }
+   HelpFileList.sortNumerical(0);
+   for(%i = 0; %i < HelpFileList.entryCount; %i++)
+   {
+      %rowId = HelpFileList.getRowId(%i);
+      %text = HelpFileList.getRowTextById(%rowId);
+      %text = %i + 1 @ ". " @ restWords(%text);
+      HelpFileList.setRowById(%rowId, %text);
+   }
+   HelpFileList.setSelectedRow(0);
+}
+
+function HelpFileList::onSelect(%this, %row)
+{
+   %fo = new FileObject();
+   %fo.openForRead(%this.fileName[%row]);
+   %text = "";
+   while(!%fo.isEOF())
+      %text = %text @ %fo.readLine() @ "\n";
+
+   %fo.delete();
+   HelpText.setText(%text);
+}
+
+function getHelp(%helpName)
+{
+   Canvas.pushDialog(HelpDlg);
+   if(%helpName !$= "")
+   {
+      %index = HelpFileList.findTextIndex(%helpName);
+      HelpFileList.setSelectedRow(%index);
+   }
+}
+
+function contextHelp()
+{
+   for(%i = 0; %i < Canvas.getCount(); %i++)
+   {
+      if(Canvas.getObject(%i).getName() $= HelpDlg)
+      {
+         Canvas.popDialog(HelpDlg);
+         return;
+      }
+   }
+   %content = Canvas.getContent();
+   %helpPage = %content.getHelpPage();
+   getHelp(%helpPage);
+}
+
+function GuiControl::getHelpPage(%this)
+{
+   return %this.helpPage;
+}
+
+function GuiMLTextCtrl::onURL(%this, %url)
+{
+   gotoWebPage( %url );
+}   
+

+ 367 - 0
Templates/BaseGame/game/data/ui/scripts/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);
+}

+ 155 - 0
Templates/BaseGame/game/data/ui/scripts/startupGui.cs

@@ -0,0 +1,155 @@
+//-----------------------------------------------------------------------------
+// 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/art/background-dark";
+   StartupGui.logo[0]       = "data/ui/art/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, "art/sound/gui/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();
+         
+         Canvas.setContent(MainMenuGui);
+      }
+      else
+      {
+         // We do have a bitmap so cycle to it
+         %this.next();
+      }
+   }
+}

+ 159 - 0
Templates/BaseGame/game/tools/gui/messageBoxes/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 ---

+ 90 - 0
Templates/BaseGame/game/tools/settings.xml

@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<EditorSettings>
+    <Group name="AxisGizmo">
+        <Setting name="axisGizmoMaxScreenLen">100</Setting>
+        <Setting name="snapRotations">0</Setting>
+        <Setting name="mouseScaleScalar">0.8</Setting>
+        <Setting name="renderInfoText">1</Setting>
+        <Setting name="rotationSnap">15</Setting>
+        <Setting name="mouseRotateScalar">0.8</Setting>
+        <Setting name="renderWhenUsed">0</Setting>
+        <Group name="Grid">
+            <Setting name="planeDim">500</Setting>
+            <Setting name="gridColor">255 255 255 20</Setting>
+            <Setting name="snapToGrid">0</Setting>
+            <Setting name="renderPlaneHashes">0</Setting>
+            <Setting name="gridSize">10 10 10</Setting>
+            <Setting name="renderPlane">0</Setting>
+        </Group>
+    </Group>
+    <Group name="WorldEditor">
+        <Setting name="dropType">screenCenter</Setting>
+        <Setting name="forceLoadDAE">0</Setting>
+        <Setting name="orthoFOV">50</Setting>
+        <Setting name="currentEditor">WorldEditorInspectorPlugin</Setting>
+        <Setting name="undoLimit">40</Setting>
+        <Setting name="displayType">6</Setting>
+        <Setting name="orthoShowGrid">1</Setting>
+        <Group name="Tools">
+            <Setting name="snapSoft">0</Setting>
+            <Setting name="boundingBoxCollision">0</Setting>
+            <Setting name="snapGround">0</Setting>
+            <Setting name="dropAtScreenCenterMax">100</Setting>
+            <Setting name="snapSoftSize">2</Setting>
+            <Setting name="dropAtScreenCenterScalar">1</Setting>
+            <Setting name="objectsUseBoxCenter">1</Setting>
+        </Group>
+        <Group name="Docs">
+            <Setting name="documentationURL">http://www.garagegames.com/products/torque-3d/documentation/user</Setting>
+            <Setting name="documentationLocal">../../../Documentation/Official Documentation.html</Setting>
+            <Setting name="forumURL">http://www.garagegames.com/products/torque-3d/forums</Setting>
+            <Setting name="documentationReference">../../../Documentation/Torque 3D - Script Manual.chm</Setting>
+        </Group>
+        <Group name="Grid">
+            <Setting name="gridOriginColor">255 255 255 100</Setting>
+            <Setting name="gridSize">1</Setting>
+            <Setting name="gridColor">102 102 102 100</Setting>
+            <Setting name="gridMinorColor">51 51 51 100</Setting>
+            <Setting name="gridSnap">0</Setting>
+        </Group>
+        <Group name="Images">
+            <Setting name="lockedHandle">tools/worldEditor/images/LockedHandle</Setting>
+            <Setting name="defaultHandle">tools/worldEditor/images/DefaultHandle</Setting>
+            <Setting name="selectHandle">tools/worldEditor/images/SelectHandle</Setting>
+        </Group>
+        <Group name="Render">
+            <Setting name="showMousePopupInfo">1</Setting>
+            <Setting name="renderObjHandle">1</Setting>
+            <Setting name="renderSelectionBox">1</Setting>
+            <Setting name="renderPopupBackground">1</Setting>
+            <Setting name="renderObjText">1</Setting>
+        </Group>
+        <Group name="Color">
+            <Setting name="objMouseOverColor">0 255 0 255</Setting>
+            <Setting name="popupBackgroundColor">100 100 100 255</Setting>
+            <Setting name="objectTextColor">255 255 255 255</Setting>
+            <Setting name="objSelectColor">255 0 0 255</Setting>
+            <Setting name="selectionBoxColor">255 255 0 255</Setting>
+            <Setting name="objMouseOverSelectColor">0 0 255 255</Setting>
+            <Setting name="dragRectColor">255 255 0 255</Setting>
+        </Group>
+        <Group name="ObjectIcons">
+            <Setting name="fadeIconsStartDist">8</Setting>
+            <Setting name="fadeIcons">1</Setting>
+            <Setting name="fadeIconsEndAlpha">0</Setting>
+            <Setting name="fadeIconsStartAlpha">255</Setting>
+            <Setting name="fadeIconsEndDist">20</Setting>
+        </Group>
+    </Group>
+    <Group name="LevelInformation">
+        <Setting name="levelsDirectory">data/FPSGameplay/levels</Setting>
+        <Group name="levels">
+            <Group name="BlankRoom.mis">
+                <Setting name="cameraSpeed">25</Setting>
+            </Group>
+        </Group>
+    </Group>
+    <Group name="NavEditor">
+        <Setting name="SpawnClass">AIPlayer</Setting>
+    </Group>
+</EditorSettings>