Sfoglia il codice sorgente

merged numerous changes from upstream

Thomas "elfprince13" Dickerson 8 anni fa
parent
commit
849a1c1eb1
50 ha cambiato i file con 917 aggiunte e 366 eliminazioni
  1. 116 44
      Engine/source/T3D/fx/lightning.cpp
  2. 3 1
      Engine/source/T3D/fx/lightning.h
  3. 6 1
      Engine/source/console/consoleFunctions.cpp
  4. 3 0
      Engine/source/forest/editor/forestSelectionTool.cpp
  5. 27 24
      Engine/source/gfx/bitmap/gBitmap.cpp
  6. 1 15
      Engine/source/gfx/gfxTextureManager.cpp
  7. 4 0
      Engine/source/gfx/video/videoCapture.cpp
  8. 9 0
      Engine/source/math/mMathFn.h
  9. 1 1
      Engine/source/platform/input/event.h
  10. 1 1
      Engine/source/renderInstance/renderMeshMgr.cpp
  11. 37 29
      Engine/source/renderInstance/renderParticleMgr.cpp
  12. 1 0
      Engine/source/renderInstance/renderPassManager.cpp
  13. 1 1
      Engine/source/renderInstance/renderPrePassMgr.cpp
  14. 48 3
      Engine/source/windowManager/sdl/sdlSplashScreen.cpp
  15. 104 86
      Engine/source/windowManager/sdl/sdlWindow.cpp
  16. 54 0
      Engine/source/windowManager/sdl/sdlWindowMgr.cpp
  17. 26 6
      Engine/source/windowManager/windowInputGenerator.cpp
  18. 1 1
      Templates/Empty/game/art/gui/mainMenuGui.gui
  19. BIN
      Templates/Empty/game/art/gui/splash.bmp
  20. BIN
      Templates/Empty/game/art/gui/splash.png
  21. 15 0
      Templates/Empty/game/core/scripts/client/screenshot.cs
  22. BIN
      Templates/Empty/game/core/torque.png
  23. 2 0
      Templates/Empty/game/main.cs
  24. 43 0
      Templates/Empty/game/scripts/client/default.bind.cs
  25. 1 1
      Templates/Empty/game/tools/base/utils/inspector.ed.cs
  26. 1 1
      Templates/Empty/game/tools/forestEditor/forestEditorGui.gui
  27. 1 1
      Templates/Empty/game/tools/guiEditor/gui/guiEditor.ed.gui
  28. 39 4
      Templates/Empty/game/tools/guiEditor/scripts/guiEditor.ed.cs
  29. 1 1
      Templates/Empty/game/tools/worldEditor/gui/EditorGui.ed.gui
  30. 17 2
      Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs
  31. 9 23
      Templates/Empty/game/tools/worldEditor/scripts/editor.ed.cs
  32. 50 38
      Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs
  33. 2 0
      Templates/Full/game/art/datablocks/environment.cs
  34. BIN
      Templates/Full/game/art/environment/lightning.png
  35. 1 1
      Templates/Full/game/art/gui/mainMenuGui.gui
  36. BIN
      Templates/Full/game/art/gui/splash.bmp
  37. BIN
      Templates/Full/game/art/gui/splash.png
  38. 15 0
      Templates/Full/game/core/scripts/client/screenshot.cs
  39. BIN
      Templates/Full/game/core/torque.png
  40. 2 0
      Templates/Full/game/main.cs
  41. 43 0
      Templates/Full/game/scripts/client/default.bind.cs
  42. 1 1
      Templates/Full/game/tools/base/utils/inspector.ed.cs
  43. 1 1
      Templates/Full/game/tools/forestEditor/forestEditorGui.gui
  44. 1 1
      Templates/Full/game/tools/guiEditor/gui/guiEditor.ed.gui
  45. 39 4
      Templates/Full/game/tools/guiEditor/scripts/guiEditor.ed.cs
  46. 1 1
      Templates/Full/game/tools/worldEditor/gui/EditorGui.ed.gui
  47. 17 2
      Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs
  48. 9 23
      Templates/Full/game/tools/worldEditor/scripts/editor.ed.cs
  49. 50 38
      Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs
  50. 113 10
      Tools/CMake/torque3d.cmake

+ 116 - 44
Engine/source/T3D/fx/lightning.cpp

@@ -200,7 +200,7 @@ void LightningStrikeEvent::unpack(NetConnection* con, BitStream* stream)
 {
 {
    if(!stream->readFlag())
    if(!stream->readFlag())
       return;
       return;
-   S32 mClientId = stream->readRangedU32(0, NetConnection::MaxGhostCount);
+   mClientId = stream->readRangedU32(0, NetConnection::MaxGhostCount);
    mLightning = NULL;
    mLightning = NULL;
    NetObject* pObject = con->resolveGhost(mClientId);
    NetObject* pObject = con->resolveGhost(mClientId);
    if (pObject)
    if (pObject)
@@ -214,10 +214,10 @@ void LightningStrikeEvent::unpack(NetConnection* con, BitStream* stream)
       // target id
       // target id
       S32 mTargetID    = stream->readRangedU32(0, NetConnection::MaxGhostCount);
       S32 mTargetID    = stream->readRangedU32(0, NetConnection::MaxGhostCount);
 
 
-      NetObject* pObject = con->resolveGhost(mTargetID);
-      if( pObject != NULL )
+      NetObject* tObject = con->resolveGhost(mTargetID);
+      if(tObject != NULL )
       {
       {
-         mTarget = dynamic_cast<SceneObject*>(pObject);
+         mTarget = dynamic_cast<SceneObject*>(tObject);
       }
       }
       if( bool(mTarget) == false )
       if( bool(mTarget) == false )
       {
       {
@@ -243,6 +243,7 @@ LightningData::LightningData()
    dMemset( strikeTextureNames, 0, sizeof( strikeTextureNames ) );
    dMemset( strikeTextureNames, 0, sizeof( strikeTextureNames ) );
    dMemset( strikeTextures, 0, sizeof( strikeTextures ) );
    dMemset( strikeTextures, 0, sizeof( strikeTextures ) );
    dMemset( thunderSounds, 0, sizeof( thunderSounds ) );
    dMemset( thunderSounds, 0, sizeof( thunderSounds ) );
+   mNumStrikeTextures = 0;
 }
 }
 
 
 LightningData::~LightningData()
 LightningData::~LightningData()
@@ -297,10 +298,14 @@ bool LightningData::preload(bool server, String &errorStr)
       if( !sfxResolve( &strikeSound, sfxErrorStr ) )
       if( !sfxResolve( &strikeSound, sfxErrorStr ) )
          Con::errorf(ConsoleLogEntry::General, "LightningData::preload: Invalid packet: %s", sfxErrorStr.c_str());
          Con::errorf(ConsoleLogEntry::General, "LightningData::preload: Invalid packet: %s", sfxErrorStr.c_str());
 
 
+      mNumStrikeTextures = 0;
       for (U32 i = 0; i < MaxTextures; i++) 
       for (U32 i = 0; i < MaxTextures; i++) 
       {
       {
          if (strikeTextureNames[i][0])
          if (strikeTextureNames[i][0])
+         {
             strikeTextures[i] = GFXTexHandle(strikeTextureNames[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - strikeTextures[%d] (line %d)", __FUNCTION__, i, __LINE__));
             strikeTextures[i] = GFXTexHandle(strikeTextureNames[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - strikeTextures[%d] (line %d)", __FUNCTION__, i, __LINE__));
+            mNumStrikeTextures++;
+         }
       }
       }
    }
    }
 
 
@@ -317,7 +322,11 @@ void LightningData::packData(BitStream* stream)
    U32 i;
    U32 i;
    for (i = 0; i < MaxThunders; i++)
    for (i = 0; i < MaxThunders; i++)
       sfxWrite( stream, thunderSounds[ i ] );
       sfxWrite( stream, thunderSounds[ i ] );
-   for (i = 0; i < MaxTextures; i++) {
+
+   stream->writeInt(mNumStrikeTextures, 4);
+
+   for (i = 0; i < MaxTextures; i++) 
+   {
       stream->writeString(strikeTextureNames[i]);
       stream->writeString(strikeTextureNames[i]);
    }
    }
 
 
@@ -331,7 +340,11 @@ void LightningData::unpackData(BitStream* stream)
    U32 i;
    U32 i;
    for (i = 0; i < MaxThunders; i++)
    for (i = 0; i < MaxThunders; i++)
       sfxRead( stream, &thunderSounds[ i ] );
       sfxRead( stream, &thunderSounds[ i ] );
-   for (i = 0; i < MaxTextures; i++) {
+
+   mNumStrikeTextures = stream->readInt(4);
+
+   for (i = 0; i < MaxTextures; i++) 
+   {
       strikeTextureNames[i] = stream->readSTString();
       strikeTextureNames[i] = stream->readSTString();
    }
    }
 
 
@@ -368,16 +381,16 @@ Lightning::~Lightning()
 {
 {
    while( mThunderListHead )
    while( mThunderListHead )
    {
    {
-      Thunder* next = mThunderListHead->next;
+      Thunder* nextThunder = mThunderListHead->next;
       delete mThunderListHead;
       delete mThunderListHead;
-      mThunderListHead = next;
+      mThunderListHead = nextThunder;
    }
    }
 
 
    while( mStrikeListHead )
    while( mStrikeListHead )
    {
    {
-      Strike* next = mStrikeListHead->next;
+      Strike* nextStrike = mStrikeListHead->next;
       delete mStrikeListHead;
       delete mStrikeListHead;
-      mStrikeListHead = next;
+      mStrikeListHead = nextStrike;
    }
    }
 }
 }
 
 
@@ -478,11 +491,16 @@ void Lightning::renderObject(ObjectRenderInst *ri, SceneRenderState *state, Base
       desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendOne);
       desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendOne);
       desc.setCullMode(GFXCullNone);
       desc.setCullMode(GFXCullNone);
       desc.zWriteEnable = false;
       desc.zWriteEnable = false;
-      desc.samplersDefined = true;
-      desc.samplers[0].magFilter = GFXTextureFilterLinear;
-      desc.samplers[0].minFilter = GFXTextureFilterLinear;
-      desc.samplers[0].addressModeU = GFXAddressWrap;
-      desc.samplers[0].addressModeV = GFXAddressWrap;
+      desc.vertexColorEnable = true;
+
+      if (mDataBlock->mNumStrikeTextures != 0)
+      {
+         desc.samplersDefined = true;
+         desc.samplers[0].magFilter = GFXTextureFilterLinear;
+         desc.samplers[0].minFilter = GFXTextureFilterLinear;
+         desc.samplers[0].addressModeU = GFXAddressWrap;
+         desc.samplers[0].addressModeV = GFXAddressWrap;
+      }
 
 
       mLightningSB = GFX->createStateBlock(desc);
       mLightningSB = GFX->createStateBlock(desc);
 
 
@@ -494,9 +512,16 @@ void Lightning::renderObject(ObjectRenderInst *ri, SceneRenderState *state, Base
    Strike* walk = mStrikeListHead;
    Strike* walk = mStrikeListHead;
    while (walk != NULL)
    while (walk != NULL)
    {
    {
-      GFX->setTexture(0, mDataBlock->strikeTextures[0]);
+      if (mDataBlock->mNumStrikeTextures > 1)
+      {
+         GFX->setTexture(0, mDataBlock->strikeTextures[sgLightningRand.randI(0, mDataBlock->mNumStrikeTextures - 1)]);
+      }
+      else if (mDataBlock->mNumStrikeTextures > 0)
+      {
+         GFX->setTexture(0, mDataBlock->strikeTextures[0]);
+      }
 
 
-      for( U32 i=0; i<3; i++ )
+      for( U32 i=0; i<MAX_LIGHTNING; i++ )
       {
       {
          if( walk->bolt[i].isFading )
          if( walk->bolt[i].isFading )
          {
          {
@@ -515,8 +540,8 @@ void Lightning::renderObject(ObjectRenderInst *ri, SceneRenderState *state, Base
    }
    }
 
 
    //GFX->setZWriteEnable(true);
    //GFX->setZWriteEnable(true);
-	//GFX->setAlphaTestEnable(false);
-	//GFX->setAlphaBlendEnable(false);
+   //GFX->setAlphaTestEnable(false);
+   //GFX->setAlphaBlendEnable(false);
 }
 }
 
 
 void Lightning::scheduleThunder(Strike* newStrike)
 void Lightning::scheduleThunder(Strike* newStrike)
@@ -589,7 +614,7 @@ void Lightning::advanceTime(F32 dt)
    while (*pWalker != NULL) {
    while (*pWalker != NULL) {
       Strike* pStrike = *pWalker;
       Strike* pStrike = *pWalker;
 
 
-      for( U32 i=0; i<3; i++ )
+      for( U32 i=0; i<MAX_LIGHTNING; i++ )
       {
       {
          pStrike->bolt[i].update( dt );
          pStrike->bolt[i].update( dt );
       }
       }
@@ -673,7 +698,7 @@ void Lightning::processEvent(LightningStrikeEvent* pEvent)
       pStrike->currentAge = 0.0f;
       pStrike->currentAge = 0.0f;
       pStrike->next       = mStrikeListHead;
       pStrike->next       = mStrikeListHead;
 
 
-      for( U32 i=0; i<3; i++ )
+      for( U32 i=0; i<MAX_LIGHTNING; i++ )
       {
       {
          F32 randStart = boltStartRadius;
          F32 randStart = boltStartRadius;
          F32 height = mObjScale.z * 0.5f + getPosition().z;
          F32 height = mObjScale.z * 0.5f + getPosition().z;
@@ -709,6 +734,7 @@ void Lightning::warningFlashes()
 {
 {
    AssertFatal(isServerObject(), "Error, client objects may not initiate lightning!");
    AssertFatal(isServerObject(), "Error, client objects may not initiate lightning!");
 
 
+   Point3F strikePoint( gRandGen.randF( 0.0f, 1.0f ), gRandGen.randF( 0.0f, 1.0f ), 0.0f );
 
 
    SimGroup* pClientGroup = Sim::getClientGroup();
    SimGroup* pClientGroup = Sim::getClientGroup();
    for (SimGroup::iterator itr = pClientGroup->begin(); itr != pClientGroup->end(); itr++) {
    for (SimGroup::iterator itr = pClientGroup->begin(); itr != pClientGroup->end(); itr++) {
@@ -717,6 +743,9 @@ void Lightning::warningFlashes()
       {
       {
          LightningStrikeEvent* pEvent = new LightningStrikeEvent;
          LightningStrikeEvent* pEvent = new LightningStrikeEvent;
          pEvent->mLightning = this;
          pEvent->mLightning = this;
+       
+       pEvent->mStart.x = strikePoint.x;
+       pEvent->mStart.y = strikePoint.y;
 
 
          nc->postNetEvent(pEvent);
          nc->postNetEvent(pEvent);
       }
       }
@@ -731,18 +760,19 @@ void Lightning::strikeRandomPoint()
    Point3F strikePoint( gRandGen.randF( 0.0f, 1.0f ), gRandGen.randF( 0.0f, 1.0f ), 0.0f );
    Point3F strikePoint( gRandGen.randF( 0.0f, 1.0f ), gRandGen.randF( 0.0f, 1.0f ), 0.0f );
 
 
    // check if an object is within target range
    // check if an object is within target range
+   Point3F worldPosStrikePoint = strikePoint;
 
 
-   strikePoint *= mObjScale;
-   strikePoint += getPosition();
-   strikePoint += Point3F( -mObjScale.x * 0.5f, -mObjScale.y * 0.5f, 0.0f );
+   worldPosStrikePoint *= mObjScale;
+   worldPosStrikePoint += getPosition();
+   worldPosStrikePoint += Point3F( -mObjScale.x * 0.5f, -mObjScale.y * 0.5f, 0.0f );
 
 
    Box3F queryBox;
    Box3F queryBox;
    F32 boxWidth = strikeRadius * 2.0f;
    F32 boxWidth = strikeRadius * 2.0f;
 
 
    queryBox.minExtents.set( -boxWidth * 0.5f, -boxWidth * 0.5f, -mObjScale.z * 0.5f );
    queryBox.minExtents.set( -boxWidth * 0.5f, -boxWidth * 0.5f, -mObjScale.z * 0.5f );
    queryBox.maxExtents.set(  boxWidth * 0.5f,  boxWidth * 0.5f,  mObjScale.z * 0.5f );
    queryBox.maxExtents.set(  boxWidth * 0.5f,  boxWidth * 0.5f,  mObjScale.z * 0.5f );
-   queryBox.minExtents += strikePoint;
-   queryBox.maxExtents += strikePoint;
+   queryBox.minExtents += worldPosStrikePoint;
+   queryBox.maxExtents += worldPosStrikePoint;
 
 
    SimpleQueryList sql;
    SimpleQueryList sql;
    getContainer()->findObjects(queryBox, DAMAGEABLE_TYPEMASK,
    getContainer()->findObjects(queryBox, DAMAGEABLE_TYPEMASK,
@@ -837,13 +867,53 @@ void Lightning::strikeRandomPoint()
 }
 }
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
-void Lightning::strikeObject(ShapeBase*)
+void Lightning::strikeObject(ShapeBase* targetObj)
 {
 {
    AssertFatal(isServerObject(), "Error, client objects may not initiate lightning!");
    AssertFatal(isServerObject(), "Error, client objects may not initiate lightning!");
 
 
-   AssertFatal(false, "Lightning::strikeObject is not implemented.");
-}
+   Point3F strikePoint = targetObj->getPosition();
+   Point3F objectCenter;
+
+   Box3F wb = getWorldBox();
+   if (!wb.isContained(strikePoint))
+        return;
+
+   Point3F targetRel = strikePoint - getPosition();
+   Point3F length(wb.len_x() / 2.0f, wb.len_y() / 2.0f, wb.len_z() / 2.0f);
 
 
+   Point3F strikePos = targetRel / length;
+
+   bool playerInWarmup = false;
+   Player *playerObj = dynamic_cast< Player * >(targetObj);
+   if (playerObj)
+   {
+       if (!playerObj->getControllingClient())
+       {
+           playerInWarmup = true;
+       }
+   }
+
+   if (!playerInWarmup)
+   {
+       applyDamage_callback(targetObj->getWorldSphere().center, VectorF(0.0, 0.0, 1.0), targetObj);
+   }
+ 
+   SimGroup* pClientGroup = Sim::getClientGroup();
+   for (SimGroup::iterator itr = pClientGroup->begin(); itr != pClientGroup->end(); itr++) {
+      NetConnection* nc = static_cast<NetConnection*>(*itr);
+      if (nc != NULL)
+      {
+         LightningStrikeEvent* pEvent = new LightningStrikeEvent;
+         pEvent->mLightning = this;
+       
+         pEvent->mStart.x = strikePoint.x;
+         pEvent->mStart.y = strikePoint.y;
+         pEvent->mTarget = targetObj;
+
+         nc->postNetEvent(pEvent);
+      }
+   }
+}
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
 U32 Lightning::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
 U32 Lightning::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
@@ -864,6 +934,7 @@ U32 Lightning::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
       stream->write(color.red);
       stream->write(color.red);
       stream->write(color.green);
       stream->write(color.green);
       stream->write(color.blue);
       stream->write(color.blue);
+      stream->write(color.alpha);
       stream->write(fadeColor.red);
       stream->write(fadeColor.red);
       stream->write(fadeColor.green);
       stream->write(fadeColor.green);
       stream->write(fadeColor.blue);
       stream->write(fadeColor.blue);
@@ -895,6 +966,7 @@ void Lightning::unpackUpdate(NetConnection* con, BitStream* stream)
       stream->read(&color.red);
       stream->read(&color.red);
       stream->read(&color.green);
       stream->read(&color.green);
       stream->read(&color.blue);
       stream->read(&color.blue);
+      stream->read(&color.alpha);
       stream->read(&fadeColor.red);
       stream->read(&fadeColor.red);
       stream->read(&fadeColor.green);
       stream->read(&fadeColor.green);
       stream->read(&fadeColor.blue);
       stream->read(&fadeColor.blue);
@@ -930,7 +1002,7 @@ DefineEngineMethod(Lightning, strikeRandomPoint, void, (),,
       object->strikeRandomPoint();
       object->strikeRandomPoint();
 }
 }
 
 
-DefineEngineMethod(Lightning, strikeObject, void, (ShapeBase* pSB),,
+DefineEngineMethod(Lightning, strikeObject, void, (ShapeBase* pSB), (nullAsType<ShapeBase*>()),
    "Creates a LightningStrikeEvent which strikes a specific object.\n"
    "Creates a LightningStrikeEvent which strikes a specific object.\n"
    "@note This method is currently unimplemented.\n" )
    "@note This method is currently unimplemented.\n" )
 {
 {
@@ -1028,7 +1100,7 @@ void LightningBolt::render( const Point3F &camPos )
          renderSegment(mMinorNodes[i], camPos, false);
          renderSegment(mMinorNodes[i], camPos, false);
    }
    }
 
 
-	PrimBuild::end();
+   PrimBuild::end();
 
 
    for(LightingBoltList::Iterator i = splitList.begin(); i != splitList.end(); ++i)
    for(LightingBoltList::Iterator i = splitList.begin(); i != splitList.end(); ++i)
    {
    {
@@ -1154,26 +1226,26 @@ void LightningBolt::generateMinorNodes()
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 // Recursive algo to create bolts that split off from main bolt
 // Recursive algo to create bolts that split off from main bolt
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-void LightningBolt::createSplit( const Point3F &startPoint, const Point3F &endPoint, U32 depth, F32 width )
+void LightningBolt::createSplit( const Point3F &startingPoint, const Point3F &endingPoint, U32 depth, F32 splitWidth )
 {
 {
    if( depth == 0 )
    if( depth == 0 )
       return;
       return;
-	  
+     
    F32 chanceToEnd = gRandGen.randF();
    F32 chanceToEnd = gRandGen.randF();
    if( chanceToEnd > 0.70f )
    if( chanceToEnd > 0.70f )
       return;
       return;
 
 
-   if( width < 0.75f )
-      width = 0.75f;
+   if(splitWidth < 0.75f )
+      splitWidth = 0.75f;
 
 
-   VectorF diff = endPoint - startPoint;
+   VectorF diff = endingPoint - startingPoint;
    F32 length = diff.len();
    F32 length = diff.len();
    diff.normalizeSafe();
    diff.normalizeSafe();
 
 
    LightningBolt newBolt;
    LightningBolt newBolt;
-   newBolt.startPoint = startPoint;
-   newBolt.endPoint = endPoint;
-   newBolt.width = width;
+   newBolt.startPoint = startingPoint;
+   newBolt.endPoint = endingPoint;
+   newBolt.width = splitWidth;
    newBolt.numMajorNodes = 3;
    newBolt.numMajorNodes = 3;
    newBolt.maxMajorAngle = 30.0f;
    newBolt.maxMajorAngle = 30.0f;
    newBolt.numMinorNodes = 3;
    newBolt.numMinorNodes = 3;
@@ -1184,13 +1256,13 @@ void LightningBolt::createSplit( const Point3F &startPoint, const Point3F &endPo
    splitList.pushBack( newBolt );
    splitList.pushBack( newBolt );
 
 
    VectorF newDir1 = MathUtils::randomDir( diff, 10.0f, 45.0f );
    VectorF newDir1 = MathUtils::randomDir( diff, 10.0f, 45.0f );
-   Point3F newEndPoint1 = endPoint + newDir1 * gRandGen.randF( 0.5f, 1.5f ) * length;
+   Point3F newEndPoint1 = endingPoint + newDir1 * gRandGen.randF( 0.5f, 1.5f ) * length;
 
 
    VectorF newDir2 = MathUtils::randomDir( diff, 10.0f, 45.0f );
    VectorF newDir2 = MathUtils::randomDir( diff, 10.0f, 45.0f );
-   Point3F newEndPoint2 = endPoint + newDir2 * gRandGen.randF( 0.5f, 1.5f ) * length;
+   Point3F newEndPoint2 = endingPoint + newDir2 * gRandGen.randF( 0.5f, 1.5f ) * length;
 
 
-   createSplit( endPoint, newEndPoint1, depth - 1, width * 0.30f );
-   createSplit( endPoint, newEndPoint2, depth - 1, width * 0.30f );
+   createSplit(endingPoint, newEndPoint1, depth - 1, splitWidth * 0.30f );
+   createSplit(endingPoint, newEndPoint2, depth - 1, splitWidth * 0.30f );
 
 
 }
 }
 
 
@@ -1203,7 +1275,7 @@ void LightningBolt::startSplits()
    for( U32 i=0; i<mMajorNodes.numNodes-1; i++ )
    for( U32 i=0; i<mMajorNodes.numNodes-1; i++ )
    {
    {
       if( gRandGen.randF() > 0.3f )
       if( gRandGen.randF() > 0.3f )
-	     continue;
+        continue;
 
 
       Node node = mMajorNodes.nodeList[i];
       Node node = mMajorNodes.nodeList[i];
       Node node2 = mMajorNodes.nodeList[i+1];
       Node node2 = mMajorNodes.nodeList[i+1];

+ 3 - 1
Engine/source/T3D/fx/lightning.h

@@ -47,6 +47,7 @@ class ShapeBase;
 class LightningStrikeEvent;
 class LightningStrikeEvent;
 class SFXTrack;
 class SFXTrack;
 
 
+#define MAX_LIGHTNING 3
 
 
 // -------------------------------------------------------------------------
 // -------------------------------------------------------------------------
 class LightningData : public GameBaseData
 class LightningData : public GameBaseData
@@ -70,6 +71,7 @@ class LightningData : public GameBaseData
 
 
    GFXTexHandle  strikeTextures[MaxTextures];
    GFXTexHandle  strikeTextures[MaxTextures];
    U32           numThunders;
    U32           numThunders;
+   U32           mNumStrikeTextures;
 
 
   protected:
   protected:
    bool onAdd();
    bool onAdd();
@@ -227,7 +229,7 @@ class Lightning : public GameBase
 
 
    void warningFlashes();
    void warningFlashes();
    void strikeRandomPoint();
    void strikeRandomPoint();
-   void strikeObject(ShapeBase*);
+   void strikeObject(ShapeBase* targetObj);
    void processEvent(LightningStrikeEvent*);
    void processEvent(LightningStrikeEvent*);
 
 
    DECLARE_CONOBJECT(Lightning);
    DECLARE_CONOBJECT(Lightning);

+ 6 - 1
Engine/source/console/consoleFunctions.cpp

@@ -2141,13 +2141,18 @@ DefineEngineFunction( gotoWebPage, void, ( const char* address ),,
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-DefineEngineFunction( displaySplashWindow, bool, (const char* path), ("art/gui/splash.bmp"),
+DefineEngineFunction( displaySplashWindow, bool, (const char* path), (""),
    "Display a startup splash window suitable for showing while the engine still starts up.\n\n"
    "Display a startup splash window suitable for showing while the engine still starts up.\n\n"
    "@note This is currently only implemented on Windows.\n\n"
    "@note This is currently only implemented on Windows.\n\n"
    "@param path   relative path to splash screen image to display.\n"
    "@param path   relative path to splash screen image to display.\n"
    "@return True if the splash window could be successfully initialized.\n\n"
    "@return True if the splash window could be successfully initialized.\n\n"
    "@ingroup Platform" )
    "@ingroup Platform" )
 {
 {
+   if (path == "")
+   {
+      path = Con::getVariable("$Core::splashWindowImage");
+   }
+
    return Platform::displaySplashWindow(path);
    return Platform::displaySplashWindow(path);
 }
 }
 
 

+ 3 - 0
Engine/source/forest/editor/forestSelectionTool.cpp

@@ -197,6 +197,9 @@ void ForestSelectionTool::_selectItem( const ForestItem &item )
 
 
 void ForestSelectionTool::deleteSelection()
 void ForestSelectionTool::deleteSelection()
 {
 {
+   if (!mEditor)
+      return;
+
    ForestDeleteUndoAction *action = new ForestDeleteUndoAction( mForest->getData(), mEditor );
    ForestDeleteUndoAction *action = new ForestDeleteUndoAction( mForest->getData(), mEditor );
 
 
    for ( U32 i=0; i < mSelection.size(); i++ )
    for ( U32 i=0; i < mSelection.size(); i++ )

+ 27 - 24
Engine/source/gfx/bitmap/gBitmap.cpp

@@ -327,7 +327,10 @@ void GBitmap::allocateBitmap(const U32 in_width, const U32 in_height, const bool
 
 
          mNumMipLevels++;
          mNumMipLevels++;
          allocPixels += currWidth * currHeight * mBytesPerPixel;
          allocPixels += currWidth * currHeight * mBytesPerPixel;
-      } while (currWidth != 1 && currHeight != 1);
+      } while (currWidth != 1 || currHeight != 1);
+
+      U32 expectedMips = mFloor(mLog2(mMax(in_width, in_height))) + 1;
+      AssertFatal(mNumMipLevels == expectedMips, "GBitmap::allocateBitmap: mipmap count wrong");
    }
    }
    AssertFatal(mNumMipLevels <= c_maxMipLevels, "GBitmap::allocateBitmap: too many miplevels");
    AssertFatal(mNumMipLevels <= c_maxMipLevels, "GBitmap::allocateBitmap: too many miplevels");
 
 
@@ -608,31 +611,31 @@ bool GBitmap::checkForTransparency()
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 ColorF GBitmap::sampleTexel(F32 u, F32 v) const
 ColorF GBitmap::sampleTexel(F32 u, F32 v) const
 {
 {
-	ColorF col(0.5f, 0.5f, 0.5f);
-	// normally sampling wraps all the way around at 1.0,
-	// but locking doesn't support this, and we seem to calc
-	// the uv based on a clamped 0 - 1...
-	Point2F max((F32)(getWidth()-1), (F32)(getHeight()-1));
-	Point2F posf;
-	posf.x = mClampF(((u) * max.x), 0.0f, max.x);
-	posf.y = mClampF(((v) * max.y), 0.0f, max.y);
-	Point2I posi((S32)posf.x, (S32)posf.y);
-
-	const U8 *buffer = getBits();
-	U32 lexelindex = ((posi.y * getWidth()) + posi.x) * mBytesPerPixel;
-
-	if(mBytesPerPixel == 2)
-	{
-		//U16 *buffer = (U16 *)lockrect->pBits;
-	}
-	else if(mBytesPerPixel > 2)
-	{		
-		col.red = F32(buffer[lexelindex + 0]) / 255.0f;
+   ColorF col(0.5f, 0.5f, 0.5f);
+   // normally sampling wraps all the way around at 1.0,
+   // but locking doesn't support this, and we seem to calc
+   // the uv based on a clamped 0 - 1...
+   Point2F max((F32)(getWidth()-1), (F32)(getHeight()-1));
+   Point2F posf;
+   posf.x = mClampF(((u) * max.x), 0.0f, max.x);
+   posf.y = mClampF(((v) * max.y), 0.0f, max.y);
+   Point2I posi((S32)posf.x, (S32)posf.y);
+
+   const U8 *buffer = getBits();
+   U32 lexelindex = ((posi.y * getWidth()) + posi.x) * mBytesPerPixel;
+
+   if(mBytesPerPixel == 2)
+   {
+      //U16 *buffer = (U16 *)lockrect->pBits;
+   }
+   else if(mBytesPerPixel > 2)
+   {     
+      col.red = F32(buffer[lexelindex + 0]) / 255.0f;
       col.green = F32(buffer[lexelindex + 1]) / 255.0f;
       col.green = F32(buffer[lexelindex + 1]) / 255.0f;
-		col.blue = F32(buffer[lexelindex + 2]) / 255.0f;
-	}
+      col.blue = F32(buffer[lexelindex + 2]) / 255.0f;
+   }
 
 
-	return col;
+   return col;
 }
 }
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------

+ 1 - 15
Engine/source/gfx/gfxTextureManager.cpp

@@ -1085,21 +1085,7 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height,
       // NOTE: Does this belong here?
       // NOTE: Does this belong here?
       if( inOutNumMips == 0 && !autoGenSupp )
       if( inOutNumMips == 0 && !autoGenSupp )
       {
       {
-         U32 currWidth  = width;
-         U32 currHeight = height;
-
-         inOutNumMips = 1;
-         do 
-         {
-            currWidth  >>= 1;
-            currHeight >>= 1;
-            if( currWidth == 0 )
-               currWidth  = 1;
-            if( currHeight == 0 ) 
-               currHeight = 1;
-
-            inOutNumMips++;
-         } while ( currWidth != 1 && currHeight != 1 );
+         inOutNumMips = mFloor(mLog2(mMax(width, height))) + 1;
       }
       }
    }
    }
 }
 }

+ 4 - 0
Engine/source/gfx/video/videoCapture.cpp

@@ -314,6 +314,9 @@ DefineEngineFunction( startVideoCapture, void,
    "@see stopVideoCapture\n"
    "@see stopVideoCapture\n"
    "@ingroup Rendering\n" )
    "@ingroup Rendering\n" )
 {
 {
+#ifdef TORQUE_DEBUG
+   Con::errorf("Recording video is disabled in debug!");
+#else
    if ( !canvas )
    if ( !canvas )
    {
    {
       Con::errorf("startVideoCapture -Please specify a GuiCanvas object to record from!");
       Con::errorf("startVideoCapture -Please specify a GuiCanvas object to record from!");
@@ -328,6 +331,7 @@ DefineEngineFunction( startVideoCapture, void,
       VIDCAP->setResolution(resolution);
       VIDCAP->setResolution(resolution);
 
 
    VIDCAP->begin(canvas);
    VIDCAP->begin(canvas);
+#endif
 }
 }
 
 
 DefineEngineFunction( stopVideoCapture, void, (),,
 DefineEngineFunction( stopVideoCapture, void, (),,

+ 9 - 0
Engine/source/math/mMathFn.h

@@ -320,6 +320,11 @@ inline F32 mLog(const F32 val)
    return (F32) log(val);
    return (F32) log(val);
 }
 }
 
 
+inline F32 mLog2(const F32 val)
+{
+   return (F32) log2(val);
+}
+
 inline F32 mExp(const F32 val)
 inline F32 mExp(const F32 val)
 {
 {
    return (F32) exp(val);
    return (F32) exp(val);
@@ -380,6 +385,10 @@ inline F64 mLog(const F64 val)
    return (F64) log(val);
    return (F64) log(val);
 }
 }
 
 
+inline F64 mLog2(const F64 val)
+{
+   return (F64) log2(val);
+}
 
 
 inline F32 mCatmullrom(F32 t, F32 p0, F32 p1, F32 p2, F32 p3)
 inline F32 mCatmullrom(F32 t, F32 p0, F32 p1, F32 p2, F32 p3)
 {
 {

+ 1 - 1
Engine/source/platform/input/event.h

@@ -429,7 +429,7 @@ struct InputEventInfo
    U16 ascii;
    U16 ascii;
    
    
    /// Modifiers to action: SI_LSHIFT, SI_LCTRL, etc.
    /// Modifiers to action: SI_LSHIFT, SI_LCTRL, etc.
-   InputModifiers modifier;
+   U32 modifier;
 
 
    inline void postToSignal(InputEvent &ie)
    inline void postToSignal(InputEvent &ie)
    {
    {

+ 1 - 1
Engine/source/renderInstance/renderMeshMgr.cpp

@@ -245,7 +245,7 @@ void RenderMeshMgr::render(SceneRenderState * state)
             if ( passRI->accuTex != lastAccuTex )
             if ( passRI->accuTex != lastAccuTex )
             {
             {
                sgData.accuTex = passRI->accuTex;
                sgData.accuTex = passRI->accuTex;
-               lastAccuTex = lastAccuTex;
+               lastAccuTex = passRI->accuTex;
                dirty = true;
                dirty = true;
             }
             }
 
 

+ 37 - 29
Engine/source/renderInstance/renderParticleMgr.cpp

@@ -589,43 +589,51 @@ bool RenderParticleMgr::_initShader()
 
 
 void RenderParticleMgr::_onLMActivate( const char*, bool activate )
 void RenderParticleMgr::_onLMActivate( const char*, bool activate )
 {
 {
-   RenderPassManager *rpm = getRenderPass();
-   if ( !rpm )
-      return;
-
-   // Hunt for the pre-pass manager/target
-   RenderPrePassMgr *prePassBin = NULL;
-   for( U32 i = 0; i < rpm->getManagerCount(); i++ )
+   if ( activate )
    {
    {
-      RenderBinManager *bin = rpm->getManager(i);
-      if( bin->getRenderInstType() == RenderPrePassMgr::RIT_PrePass )
+      RenderPassManager *rpm = getRenderPass();
+      if ( !rpm )
+         return;
+
+      // Hunt for the pre-pass manager/target
+      RenderPrePassMgr *prePassBin = NULL;
+      for( U32 i = 0; i < rpm->getManagerCount(); i++ )
       {
       {
-         prePassBin = (RenderPrePassMgr*)bin;
-         break;
+         RenderBinManager *bin = rpm->getManager(i);
+         if( bin->getRenderInstType() == RenderPrePassMgr::RIT_PrePass )
+         {
+            prePassBin = (RenderPrePassMgr*)bin;
+            break;
+         }
       }
       }
-   }
 
 
-   // If we found the prepass bin, set this bin to render very shortly afterwards
-   // and re-add this render-manager. If there is no pre-pass bin, or it doesn't
-   // have a depth-texture, we can't render offscreen.
-   mOffscreenRenderEnabled = prePassBin && (prePassBin->getTargetChainLength() > 0);
-   if(mOffscreenRenderEnabled)
-   {
-      rpm->removeManager(this);
-      setRenderOrder( prePassBin->getRenderOrder() + 0.011f );
-      rpm->addManager(this);
-   }
+      // If we found the prepass bin, set this bin to render very shortly afterwards
+      // and re-add this render-manager. If there is no pre-pass bin, or it doesn't
+      // have a depth-texture, we can't render offscreen.
+      mOffscreenRenderEnabled = prePassBin && (prePassBin->getTargetChainLength() > 0);
+      if(mOffscreenRenderEnabled)
+      {
+         rpm->removeManager(this);
+         setRenderOrder( prePassBin->getRenderOrder() + 0.011f );
+         rpm->addManager(this);
+      }
 
 
-   // Find the targets we use
-   mPrepassTarget = NamedTexTarget::find( "prepass" );
-   mEdgeTarget = NamedTexTarget::find( "edge" );
+      // Find the targets we use
+      mPrepassTarget = NamedTexTarget::find( "prepass" );
+      mEdgeTarget = NamedTexTarget::find( "edge" );
 
 
-   // Setup the shader
-   if ( activate ) 
+      // Setup the shader
       _initShader();
       _initShader();
 
 
-   if ( mScreenQuadVertBuff.isNull() )
-      _initGFXResources();
+      if ( mScreenQuadVertBuff.isNull() )
+         _initGFXResources();
+   } 
+   else
+   {
+      mStencilClearSB = NULL;
+      mScreenQuadPrimBuff = NULL;
+      mScreenQuadVertBuff = NULL;
+   }
 }
 }
 
 
 GFXStateBlockRef RenderParticleMgr::_getOffscreenStateBlock(ParticleRenderInst *ri)
 GFXStateBlockRef RenderParticleMgr::_getOffscreenStateBlock(ParticleRenderInst *ri)

+ 1 - 0
Engine/source/renderInstance/renderPassManager.cpp

@@ -124,6 +124,7 @@ RenderPassManager::RenderBinEventSignal& RenderPassManager::getRenderBinSignal()
 
 
 void RenderPassManager::initPersistFields()
 void RenderPassManager::initPersistFields()
 {
 {
+   Parent::initPersistFields();
 }
 }
 
 
 RenderPassManager::RenderPassManager()
 RenderPassManager::RenderPassManager()

+ 1 - 1
Engine/source/renderInstance/renderPrePassMgr.cpp

@@ -480,7 +480,7 @@ void RenderPrePassMgr::render( SceneRenderState *state )
             if (passRI->accuTex != lastAccuTex)
             if (passRI->accuTex != lastAccuTex)
             {
             {
                sgData.accuTex = passRI->accuTex;
                sgData.accuTex = passRI->accuTex;
-               lastAccuTex = lastAccuTex;
+               lastAccuTex = passRI->accuTex;
                dirty = true;
                dirty = true;
             }
             }
 
 

+ 48 - 3
Engine/source/windowManager/sdl/sdlSplashScreen.cpp

@@ -22,7 +22,7 @@
 
 
 #include "platform/platform.h"
 #include "platform/platform.h"
 #include "console/console.h"
 #include "console/console.h"
-
+#include "gfx/bitmap/gBitmap.h"
 #include "SDL.h"
 #include "SDL.h"
 #include "windowManager/sdl/sdlWindow.h"
 #include "windowManager/sdl/sdlWindow.h"
 
 
@@ -36,7 +36,52 @@ bool Platform::displaySplashWindow( String path )
    if(path.isEmpty())
    if(path.isEmpty())
       return false;
       return false;
 
 
-   gSplashImage = SDL_LoadBMP(path);
+   Torque::Path iconPath = Torque::Path(path);
+
+   if (iconPath.getExtension() == String("bmp"))
+   {
+      Con::errorf("Unable to use bmp format images for the splash screen. Please use a different format.");
+      return false;
+   }
+
+   Resource<GBitmap> img = GBitmap::load(iconPath);
+   if (img != NULL)
+   {
+      U32 pitch;
+      U32 width = img->getWidth();
+      bool hasAlpha = img->getHasTransparency();
+      U32 depth;
+
+      if (hasAlpha)
+      {
+         pitch = 4 * width;
+         depth = 32;
+      }
+      else
+      {
+         pitch = 3 * width;
+         depth = 24;
+      }
+
+      Uint32 rmask, gmask, bmask, amask;
+      if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+      {
+         S32 shift = hasAlpha ? 8 : 0;
+         rmask = 0xff000000 >> shift;
+         gmask = 0x00ff0000 >> shift;
+         bmask = 0x0000ff00 >> shift;
+         amask = 0x000000ff >> shift;
+      }
+      else
+      {
+         rmask = 0x000000ff;
+         gmask = 0x0000ff00;
+         bmask = 0x00ff0000;
+         amask = hasAlpha ? 0xff000000 : 0;
+      }
+
+      gSplashImage = SDL_CreateRGBSurfaceFrom(img->getAddress(0, 0), img->getWidth(), img->getHeight(), depth, pitch, rmask, gmask, bmask, amask);
+   }
 
 
    //now the pop-up window
    //now the pop-up window
    if (gSplashImage)
    if (gSplashImage)
@@ -53,7 +98,7 @@ bool Platform::displaySplashWindow( String path )
       SDL_RenderPresent(gSplashRenderer);
       SDL_RenderPresent(gSplashRenderer);
    }
    }
 
 
-	return true;
+   return true;
 }
 }
 
 
 bool Platform::closeSplashWindow()
 bool Platform::closeSplashWindow()

+ 104 - 86
Engine/source/windowManager/sdl/sdlWindow.cpp

@@ -51,23 +51,41 @@ namespace
    {
    {
       U32 ret = 0;
       U32 ret = 0;
 
 
-      if(mod & KMOD_LSHIFT)
-         ret |= IM_LSHIFT;
+      if (mod & KMOD_LSHIFT)
+      {
+         ret |= SI_LSHIFT;
+         ret |= SI_SHIFT;
+      }
 
 
-      if(mod & KMOD_RSHIFT)
-         ret |= IM_RSHIFT;
+      if (mod & KMOD_RSHIFT)
+      {
+         ret |= SI_RSHIFT;
+         ret |= SI_SHIFT;
+      }
 
 
-      if(mod & KMOD_LCTRL)
-         ret |= IM_LCTRL;
+      if (mod & KMOD_LCTRL)
+      {
+         ret |= SI_LCTRL;
+         ret |= SI_CTRL;
+      }
 
 
-      if(mod & KMOD_RCTRL)
-         ret |= IM_RCTRL;
+      if (mod & KMOD_RCTRL)
+      {
+         ret |= SI_RCTRL;
+         ret |= SI_CTRL;
+      }
 
 
-      if(mod & KMOD_LALT)
-         ret |= IM_LALT;
+      if (mod & KMOD_LALT)
+      {
+         ret |= SI_LALT;
+         ret |= SI_ALT;
+      }
 
 
-      if(mod & KMOD_RALT)
-         ret |= IM_RALT;
+      if (mod & KMOD_RALT)
+      {
+         ret |= SI_RALT;
+         ret |= SI_ALT;
+      }
 
 
       return ret;
       return ret;
    }
    }
@@ -86,37 +104,37 @@ mShouldLockMouse(false),
 mSuppressReset(false),
 mSuppressReset(false),
 mMenuHandle(NULL)
 mMenuHandle(NULL)
 {
 {
-	mCursorController = new PlatformCursorControllerSDL( this );
+   mCursorController = new PlatformCursorControllerSDL( this );
 
 
-	mVideoMode.bitDepth = 32;
-	mVideoMode.fullScreen = false;
-	mVideoMode.refreshRate = 60;
-	mVideoMode.resolution.set(800,600);
+   mVideoMode.bitDepth = 32;
+   mVideoMode.fullScreen = false;
+   mVideoMode.refreshRate = 60;
+   mVideoMode.resolution.set(800,600);
 }
 }
 
 
 PlatformWindowSDL::~PlatformWindowSDL()
 PlatformWindowSDL::~PlatformWindowSDL()
 {
 {
-	// delete our sdl handle..
-	SDL_DestroyWindow(mWindowHandle);
+   // delete our sdl handle..
+   SDL_DestroyWindow(mWindowHandle);
 
 
-	// unlink ourselves from the window list...
-	AssertFatal(mOwningManager, "PlatformWindowSDL::~PlatformWindowSDL - orphan window, cannot unlink!");
-	mOwningManager->unlinkWindow(this);
+   // unlink ourselves from the window list...
+   AssertFatal(mOwningManager, "PlatformWindowSDL::~PlatformWindowSDL - orphan window, cannot unlink!");
+   mOwningManager->unlinkWindow(this);
 }
 }
 
 
 GFXDevice * PlatformWindowSDL::getGFXDevice()
 GFXDevice * PlatformWindowSDL::getGFXDevice()
 {
 {
-	return mDevice;
+   return mDevice;
 }
 }
 
 
 GFXWindowTarget * PlatformWindowSDL::getGFXTarget()
 GFXWindowTarget * PlatformWindowSDL::getGFXTarget()
 {
 {
-	return mTarget;
+   return mTarget;
 }
 }
 
 
 const GFXVideoMode & PlatformWindowSDL::getVideoMode()
 const GFXVideoMode & PlatformWindowSDL::getVideoMode()
 {
 {
-	return mVideoMode;
+   return mVideoMode;
 }
 }
 
 
 void* PlatformWindowSDL::getSystemWindow(const WindowSystem system)
 void* PlatformWindowSDL::getSystemWindow(const WindowSystem system)
@@ -144,41 +162,41 @@ void PlatformWindowSDL::setVideoMode( const GFXVideoMode &mode )
    mVideoMode = mode;
    mVideoMode = mode;
    mSuppressReset = true;
    mSuppressReset = true;
 
 
-	// Set our window to have the right style based on the mode
+   // Set our window to have the right style based on the mode
    if(mode.fullScreen && !Platform::getWebDeployment() && !mOffscreenRender)
    if(mode.fullScreen && !Platform::getWebDeployment() && !mOffscreenRender)
-	{		
+   {     
       setSize(mode.resolution);
       setSize(mode.resolution);
 
 
       SDL_SetWindowFullscreen( mWindowHandle, SDL_WINDOW_FULLSCREEN);
       SDL_SetWindowFullscreen( mWindowHandle, SDL_WINDOW_FULLSCREEN);
 
 
       // When switching to Fullscreen, reset device after setting style
       // When switching to Fullscreen, reset device after setting style
-	   if(mTarget.isValid())
-		   mTarget->resetMode();
-	}
-	else
-	{
+      if(mTarget.isValid())
+         mTarget->resetMode();
+   }
+   else
+   {
       // Reset device *first*, so that when we call setSize() and let it
       // Reset device *first*, so that when we call setSize() and let it
-	   // access the monitor settings, it won't end up with our fullscreen
-	   // geometry that is just about to change.
+      // access the monitor settings, it won't end up with our fullscreen
+      // geometry that is just about to change.
 
 
-	   if(mTarget.isValid())
-		   mTarget->resetMode();
+      if(mTarget.isValid())
+         mTarget->resetMode();
 
 
       if (!mOffscreenRender)
       if (!mOffscreenRender)
       {
       {
-		   SDL_SetWindowFullscreen( mWindowHandle, 0);
+         SDL_SetWindowFullscreen( mWindowHandle, 0);
       }
       }
 
 
       setSize(mode.resolution);
       setSize(mode.resolution);
       centerWindow();
       centerWindow();
-	}
+   }
 
 
-	mSuppressReset = false;
+   mSuppressReset = false;
 }
 }
 
 
 bool PlatformWindowSDL::clearFullscreen()
 bool PlatformWindowSDL::clearFullscreen()
 {
 {
-	return true;
+   return true;
 }
 }
 
 
 bool PlatformWindowSDL::isFullscreen()
 bool PlatformWindowSDL::isFullscreen()
@@ -192,32 +210,32 @@ bool PlatformWindowSDL::isFullscreen()
 
 
 void PlatformWindowSDL::_setFullscreen(const bool fullscreen)
 void PlatformWindowSDL::_setFullscreen(const bool fullscreen)
 {
 {
-	if( isFullscreen() )
-		return;
-
-	if(fullscreen && !mOffscreenRender)
-	{
-		Con::printf("PlatformWindowSDL::setFullscreen (full) enter");
-		SDL_SetWindowFullscreen( mWindowHandle, SDL_WINDOW_FULLSCREEN);
-	}
-	else
-	{
-		Con::printf("PlatformWindowSDL::setFullscreen (windowed) enter");
+   if( isFullscreen() )
+      return;
+
+   if(fullscreen && !mOffscreenRender)
+   {
+      Con::printf("PlatformWindowSDL::setFullscreen (full) enter");
+      SDL_SetWindowFullscreen( mWindowHandle, SDL_WINDOW_FULLSCREEN);
+   }
+   else
+   {
+      Con::printf("PlatformWindowSDL::setFullscreen (windowed) enter");
       if (!mOffscreenRender)
       if (!mOffscreenRender)
       {
       {
-	      SDL_SetWindowFullscreen( mWindowHandle, SDL_WINDOW_FULLSCREEN_DESKTOP);
+         SDL_SetWindowFullscreen( mWindowHandle, SDL_WINDOW_FULLSCREEN_DESKTOP);
       }
       }
 
 
       setSize(mVideoMode.resolution);
       setSize(mVideoMode.resolution);
 
 
-	}
-	Con::printf("PlatformWindowSDL::setFullscreen exit");   
+   }
+   Con::printf("PlatformWindowSDL::setFullscreen exit");   
 }
 }
 
 
 bool PlatformWindowSDL::setCaption( const char *cap )
 bool PlatformWindowSDL::setCaption( const char *cap )
 {
 {
    SDL_SetWindowTitle(mWindowHandle, cap);
    SDL_SetWindowTitle(mWindowHandle, cap);
-	return true;
+   return true;
 }
 }
 
 
 const char * PlatformWindowSDL::getCaption()
 const char * PlatformWindowSDL::getCaption()
@@ -232,45 +250,45 @@ void PlatformWindowSDL::setFocus()
 
 
 void PlatformWindowSDL::setClientExtent( const Point2I newExtent )
 void PlatformWindowSDL::setClientExtent( const Point2I newExtent )
 {
 {
-	Point2I oldExtent = getClientExtent();
-	if (oldExtent == newExtent)
-		return;   
+   Point2I oldExtent = getClientExtent();
+   if (oldExtent == newExtent)
+      return;   
 
 
    SDL_SetWindowSize(mWindowHandle, newExtent.x, newExtent.y);
    SDL_SetWindowSize(mWindowHandle, newExtent.x, newExtent.y);
 }
 }
 
 
 const Point2I PlatformWindowSDL::getClientExtent()
 const Point2I PlatformWindowSDL::getClientExtent()
 {
 {
-	// Fetch Client Rect from Windows
+   // Fetch Client Rect from Windows
    Point2I size;
    Point2I size;
-	SDL_GetWindowSize(mWindowHandle, &size.x, &size.y);
+   SDL_GetWindowSize(mWindowHandle, &size.x, &size.y);
 
 
-	return size;
+   return size;
 }
 }
 
 
 void PlatformWindowSDL::setBounds( const RectI &newBounds )
 void PlatformWindowSDL::setBounds( const RectI &newBounds )
 {
 {
-	// TODO SDL
+   // TODO SDL
 }
 }
 
 
 const RectI PlatformWindowSDL::getBounds() const
 const RectI PlatformWindowSDL::getBounds() const
 {
 {
-	// TODO SDL
-	return RectI(0, 0, 0, 0);   
+   // TODO SDL
+   return RectI(0, 0, 0, 0);   
 }
 }
 
 
 void PlatformWindowSDL::setPosition( const Point2I newPosition )
 void PlatformWindowSDL::setPosition( const Point2I newPosition )
 {
 {
-	SDL_SetWindowPosition( mWindowHandle, newPosition.x, newPosition.y );
+   SDL_SetWindowPosition( mWindowHandle, newPosition.x, newPosition.y );
 }
 }
 
 
 const Point2I PlatformWindowSDL::getPosition()
 const Point2I PlatformWindowSDL::getPosition()
 {
 {
-	Point2I position;
-	SDL_GetWindowPosition( mWindowHandle, &position.x, &position.y );
+   Point2I position;
+   SDL_GetWindowPosition( mWindowHandle, &position.x, &position.y );
 
 
-	// Return position
-	return position;
+   // Return position
+   return position;
 }
 }
 
 
 Point2I PlatformWindowSDL::clientToScreen( const Point2I& pos )
 Point2I PlatformWindowSDL::clientToScreen( const Point2I& pos )
@@ -293,7 +311,7 @@ void PlatformWindowSDL::centerWindow()
    SDL_GetWindowSize(mWindowHandle, &sizeX, &sizeY);
    SDL_GetWindowSize(mWindowHandle, &sizeX, &sizeY);
 
 
    SDL_DisplayMode mode;
    SDL_DisplayMode mode;
-	SDL_GetDesktopDisplayMode(0, &mode);
+   SDL_GetDesktopDisplayMode(0, &mode);
    
    
    U32 posX = (mode.w/2) - (sizeX/2);
    U32 posX = (mode.w/2) - (sizeX/2);
    U32 posY = (mode.h/2) - (sizeY/2);
    U32 posY = (mode.h/2) - (sizeY/2);
@@ -307,21 +325,21 @@ bool PlatformWindowSDL::setSize( const Point2I &newSize )
 
 
    // Let GFX get an update about the new resolution
    // Let GFX get an update about the new resolution
    if (mTarget.isValid())
    if (mTarget.isValid())
-		mTarget->resetMode();
+      mTarget->resetMode();
 
 
-	return true;
+   return true;
 }
 }
 
 
 bool PlatformWindowSDL::isOpen()
 bool PlatformWindowSDL::isOpen()
 {
 {
-	return mWindowHandle;
+   return mWindowHandle;
 }
 }
 
 
 bool PlatformWindowSDL::isVisible()
 bool PlatformWindowSDL::isVisible()
 {
 {
-	// Is the window open and visible, ie. not minimized?
-	if(!mWindowHandle)
-		return false;
+   // Is the window open and visible, ie. not minimized?
+   if(!mWindowHandle)
+      return false;
 
 
    if (mOffscreenRender)
    if (mOffscreenRender)
       return true;
       return true;
@@ -330,7 +348,7 @@ bool PlatformWindowSDL::isVisible()
    if( flags & SDL_WINDOW_SHOWN)
    if( flags & SDL_WINDOW_SHOWN)
       return true;
       return true;
 
 
-	return false;
+   return false;
 }
 }
 
 
 bool PlatformWindowSDL::isFocused()
 bool PlatformWindowSDL::isFocused()
@@ -371,7 +389,7 @@ bool PlatformWindowSDL::isMaximized()
 
 
 WindowId PlatformWindowSDL::getWindowId()
 WindowId PlatformWindowSDL::getWindowId()
 {
 {
-	return mWindowId;
+   return mWindowId;
 }
 }
 
 
 void PlatformWindowSDL::minimize()
 void PlatformWindowSDL::minimize()
@@ -379,7 +397,7 @@ void PlatformWindowSDL::minimize()
    if (mOffscreenRender)
    if (mOffscreenRender)
       return;
       return;
 
 
-	SDL_MinimizeWindow( mWindowHandle );
+   SDL_MinimizeWindow( mWindowHandle );
 }
 }
 
 
 void PlatformWindowSDL::maximize()
 void PlatformWindowSDL::maximize()
@@ -387,7 +405,7 @@ void PlatformWindowSDL::maximize()
    if (mOffscreenRender)
    if (mOffscreenRender)
       return;
       return;
 
 
-	SDL_MaximizeWindow( mWindowHandle );
+   SDL_MaximizeWindow( mWindowHandle );
 }
 }
 
 
 void PlatformWindowSDL::restore()
 void PlatformWindowSDL::restore()
@@ -395,7 +413,7 @@ void PlatformWindowSDL::restore()
    if (mOffscreenRender)
    if (mOffscreenRender)
       return;
       return;
 
 
-	SDL_RestoreWindow( mWindowHandle );
+   SDL_RestoreWindow( mWindowHandle );
 }
 }
 
 
 void PlatformWindowSDL::hide()
 void PlatformWindowSDL::hide()
@@ -403,7 +421,7 @@ void PlatformWindowSDL::hide()
    if (mOffscreenRender)
    if (mOffscreenRender)
       return;
       return;
 
 
-	SDL_HideWindow( mWindowHandle );
+   SDL_HideWindow( mWindowHandle );
 }
 }
 
 
 void PlatformWindowSDL::show()
 void PlatformWindowSDL::show()
@@ -411,17 +429,17 @@ void PlatformWindowSDL::show()
    if (mOffscreenRender)
    if (mOffscreenRender)
       return;
       return;
 
 
-	SDL_ShowWindow( mWindowHandle );
+   SDL_ShowWindow( mWindowHandle );
 }
 }
 
 
 void PlatformWindowSDL::close()
 void PlatformWindowSDL::close()
 {
 {
-	delete this;
+   delete this;
 }
 }
 
 
 void PlatformWindowSDL::defaultRender()
 void PlatformWindowSDL::defaultRender()
 {
 {
-	// TODO SDL
+   // TODO SDL
 }
 }
 
 
 void PlatformWindowSDL::_triggerMouseLocationNotify(const SDL_Event& evt)
 void PlatformWindowSDL::_triggerMouseLocationNotify(const SDL_Event& evt)
@@ -597,7 +615,7 @@ void PlatformWindowSDL::setMouseLocked( bool enable )
    if (mOffscreenRender)
    if (mOffscreenRender)
       return;
       return;
 
 
-	mMouseLocked = enable;
+   mMouseLocked = enable;
    
    
    SDL_SetWindowGrab( mWindowHandle, SDL_bool(enable) );
    SDL_SetWindowGrab( mWindowHandle, SDL_bool(enable) );
    SDL_SetRelativeMouseMode( SDL_bool(enable) );
    SDL_SetRelativeMouseMode( SDL_bool(enable) );

+ 54 - 0
Engine/source/windowManager/sdl/sdlWindowMgr.cpp

@@ -24,6 +24,7 @@
 #include "gfx/gfxDevice.h"
 #include "gfx/gfxDevice.h"
 #include "core/util/journal/process.h"
 #include "core/util/journal/process.h"
 #include "core/strings/unicode.h"
 #include "core/strings/unicode.h"
+#include "gfx/bitmap/gBitmap.h"
 
 
 #include "SDL.h"
 #include "SDL.h"
 
 
@@ -165,6 +166,59 @@ PlatformWindow *PlatformWindowManagerSDL::createWindow(GFXDevice *device, const
    window->mOwningManager = this;
    window->mOwningManager = this;
    mWindowMap[ window->mWindowId ] = window;
    mWindowMap[ window->mWindowId ] = window;
 
 
+   //Now, fetch our window icon, if any
+   Torque::Path iconPath = Torque::Path(Con::getVariable( "$Core::windowIcon" ));
+
+   if (iconPath.getExtension() == String("bmp"))
+   {
+      Con::errorf("Unable to use bmp format images for the window icon. Please use a different format.");
+   }
+   else
+   {
+      Resource<GBitmap> img = GBitmap::load(iconPath);
+      if (img != NULL)
+      {
+         U32 pitch;
+         U32 width = img->getWidth();
+         bool hasAlpha = img->getHasTransparency();
+         U32 depth;
+
+         if (hasAlpha)
+         {
+            pitch = 4 * width;
+            depth = 32;
+         }
+         else
+         {
+            pitch = 3 * width;
+            depth = 24;
+         }
+
+         Uint32 rmask, gmask, bmask, amask;
+         if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+         {
+            S32 shift = hasAlpha ? 8 : 0;
+            rmask = 0xff000000 >> shift;
+            gmask = 0x00ff0000 >> shift;
+            bmask = 0x0000ff00 >> shift;
+            amask = 0x000000ff >> shift;
+         }
+         else
+         {
+            rmask = 0x000000ff;
+            gmask = 0x0000ff00;
+            bmask = 0x00ff0000;
+            amask = hasAlpha ? 0xff000000 : 0;
+         }
+
+         SDL_Surface* iconSurface = SDL_CreateRGBSurfaceFrom(img->getAddress(0, 0), img->getWidth(), img->getHeight(), depth, pitch, rmask, gmask, bmask, amask);
+
+         SDL_SetWindowIcon(window->mWindowHandle, iconSurface);
+
+         SDL_FreeSurface(iconSurface);
+      }
+   }
+
    if(device)
    if(device)
    {
    {
       window->mDevice = device;
       window->mDevice = device;

+ 26 - 6
Engine/source/windowManager/windowInputGenerator.cpp

@@ -95,7 +95,7 @@ void WindowInputGenerator::generateInputEvent( InputEventInfo &inputEvent )
       {
       {
          const AccKeyMap &acc = mAcceleratorMap[i];
          const AccKeyMap &acc = mAcceleratorMap[i];
          if (!mWindow->getKeyboardTranslation() &&
          if (!mWindow->getKeyboardTranslation() &&
-            (acc.modifier & inputEvent.modifier || (acc.modifier == 0 && inputEvent.modifier == 0))
+            ((acc.modifier == inputEvent.modifier && acc.modifier != 0) || (acc.modifier == 0 && inputEvent.modifier == 0))
             && acc.keyCode == inputEvent.objInst)
             && acc.keyCode == inputEvent.objInst)
          {
          {
             Con::evaluatef(acc.cmd);
             Con::evaluatef(acc.cmd);
@@ -145,7 +145,11 @@ void WindowInputGenerator::handleMouseMove( WindowId did, U32 modifier, S32 x, S
    event.deviceType = MouseDeviceType;
    event.deviceType = MouseDeviceType;
    event.deviceInst = 0;
    event.deviceInst = 0;
    event.objType    = SI_AXIS;
    event.objType    = SI_AXIS;
-   event.modifier   = convertModifierBits(modifier);
+#ifdef TORQUE_SDL
+   event.modifier = modifier;
+#else
+   event.modifier = convertModifierBits(modifier);
+#endif
    event.ascii      = 0;
    event.ascii      = 0;
 
 
    // Generate delta movement along each axis
    // Generate delta movement along each axis
@@ -231,7 +235,11 @@ void WindowInputGenerator::handleMouseButton( WindowId did, U32 modifiers, U32 a
    event.deviceInst = 0;
    event.deviceInst = 0;
    event.objType    = SI_BUTTON;
    event.objType    = SI_BUTTON;
    event.objInst    = (InputObjectInstances)(KEY_BUTTON0 + button);
    event.objInst    = (InputObjectInstances)(KEY_BUTTON0 + button);
-   event.modifier   = convertModifierBits(modifiers);
+#ifdef TORQUE_SDL
+   event.modifier = modifiers;
+#else
+   event.modifier = convertModifierBits(modifiers);
+#endif
    event.ascii      = 0;
    event.ascii      = 0;
    event.action     = (action==IA_MAKE) ? SI_MAKE : SI_BREAK;
    event.action     = (action==IA_MAKE) ? SI_MAKE : SI_BREAK;
    event.fValue     = (action==IA_MAKE) ? 1.0 : 0.0;
    event.fValue     = (action==IA_MAKE) ? 1.0 : 0.0;
@@ -248,7 +256,11 @@ void WindowInputGenerator::handleMouseWheel( WindowId did, U32 modifiers, S32 wh
    event.deviceType = MouseDeviceType;
    event.deviceType = MouseDeviceType;
    event.deviceInst = 0;
    event.deviceInst = 0;
    event.objType    = SI_AXIS;
    event.objType    = SI_AXIS;
-   event.modifier   = convertModifierBits(modifiers);
+#ifdef TORQUE_SDL
+   event.modifier = modifiers;
+#else
+   event.modifier = convertModifierBits(modifiers);
+#endif
    event.ascii      = 0;
    event.ascii      = 0;
    event.action     = SI_MOVE;
    event.action     = SI_MOVE;
 
 
@@ -281,7 +293,11 @@ void WindowInputGenerator::handleCharInput( WindowId did, U32 modifier, U16 key
    event.deviceInst  = 0;
    event.deviceInst  = 0;
    event.objType     = SI_KEY;
    event.objType     = SI_KEY;
    event.objInst     = KEY_NULL;
    event.objInst     = KEY_NULL;
-   event.modifier    = convertModifierBits(modifier);
+#ifdef TORQUE_SDL
+   event.modifier = modifier;
+#else
+   event.modifier = convertModifierBits(modifier);
+#endif
    event.ascii       = key;
    event.ascii       = key;
    event.action      = SI_MAKE;
    event.action      = SI_MAKE;
    event.fValue      = 1.0;
    event.fValue      = 1.0;
@@ -303,7 +319,11 @@ void WindowInputGenerator::handleKeyboard( WindowId did, U32 modifier, U32 actio
    event.deviceInst  = 0;
    event.deviceInst  = 0;
    event.objType     = SI_KEY;
    event.objType     = SI_KEY;
    event.objInst     = (InputObjectInstances)key;
    event.objInst     = (InputObjectInstances)key;
-   event.modifier    = convertModifierBits(modifier);
+#ifdef TORQUE_SDL
+   event.modifier    = modifier;
+#else
+   event.modifier = convertModifierBits(modifier);
+#endif
    event.ascii       = 0;
    event.ascii       = 0;
 
 
    switch(action)
    switch(action)

+ 1 - 1
Templates/Empty/game/art/gui/mainMenuGui.gui

@@ -106,7 +106,7 @@
          profile = "GuiMenuButtonProfile";
          profile = "GuiMenuButtonProfile";
          visible = "1";
          visible = "1";
          active = "1";
          active = "1";
-         command = "GuiEdit();";
+         command = "toggleGuiEditor(1);";
          tooltipProfile = "GuiToolTipProfile";
          tooltipProfile = "GuiToolTipProfile";
          tooltip = "The GUI Editor is accessible in-game by pressing F10";
          tooltip = "The GUI Editor is accessible in-game by pressing F10";
          hovertime = "1000";
          hovertime = "1000";

BIN
Templates/Empty/game/art/gui/splash.bmp


BIN
Templates/Empty/game/art/gui/splash.png


+ 15 - 0
Templates/Empty/game/core/scripts/client/screenshot.cs

@@ -55,6 +55,9 @@ function formatSessionNumber(%number)
 // Records a movie file from the Canvas content using the specified fps.
 // Records a movie file from the Canvas content using the specified fps.
 // Possible encoder values are "PNG" and "THEORA" (default).
 // Possible encoder values are "PNG" and "THEORA" (default).
 //---------------------------------------------------------------------------------------------
 //---------------------------------------------------------------------------------------------
+
+$RecordingMovie = false;
+
 function recordMovie(%movieName, %fps, %encoder)
 function recordMovie(%movieName, %fps, %encoder)
 {
 {
    // If the canvas doesn't exist yet, setup a flag so it'll 
    // If the canvas doesn't exist yet, setup a flag so it'll 
@@ -65,12 +68,24 @@ function recordMovie(%movieName, %fps, %encoder)
    if (%encoder $= "") 
    if (%encoder $= "") 
       %encoder = "THEORA";   
       %encoder = "THEORA";   
    %resolution = Canvas.getVideoMode();
    %resolution = Canvas.getVideoMode();
+   
+   // Start the movie recording
+   ChatHud.AddLine( "\c4Recording movie file to [\c2" @ %movieName @ "\cr].ogv.");
+   echo("Recording movie to: " @ %movieName);   
    startVideoCapture(Canvas, %movieName, %encoder, %fps); 
    startVideoCapture(Canvas, %movieName, %encoder, %fps); 
+   
+    $RecordingMovie = true;
 }
 }
 
 
 function stopMovie()
 function stopMovie()
 {
 {
+   // Stop the current recording
+   ChatHud.AddLine( "\c4Recording movie file finished.");
+   echo("Stopped movie recording");
+   
    stopVideoCapture();
    stopVideoCapture();
+
+   $RecordingMovie = false;
 }
 }
 
 
 /// This is bound in initializeCommon() to take
 /// This is bound in initializeCommon() to take

BIN
Templates/Empty/game/core/torque.png


+ 2 - 0
Templates/Empty/game/main.cs

@@ -28,6 +28,8 @@ $defaultGame = "scripts";
 
 
 // Set profile directory
 // Set profile directory
 $Pref::Video::ProfilePath = "core/profile";
 $Pref::Video::ProfilePath = "core/profile";
+$Core::windowIcon = "core/torque.png";
+$Core::splashWindowImage = "art/gui/splash.png";
 
 
 function createCanvas(%windowTitle)
 function createCanvas(%windowTitle)
 {
 {

+ 43 - 0
Templates/Empty/game/scripts/client/default.bind.cs

@@ -409,6 +409,49 @@ function stopRecordingDemo( %val )
 moveMap.bind( keyboard, F3, startRecordingDemo );
 moveMap.bind( keyboard, F3, startRecordingDemo );
 moveMap.bind( keyboard, F4, stopRecordingDemo );
 moveMap.bind( keyboard, F4, stopRecordingDemo );
 
 
+//------------------------------------------------------------------------------
+// Theora Video Capture (Records a movie file)  
+//------------------------------------------------------------------------------
+
+function toggleMovieRecording(%val)
+{
+   if (!%val)
+      return;
+
+   %movieEncodingType = "THEORA";  // Valid encoder values are "PNG" and "THEORA" (default). 
+   %movieFPS = 30;  // video capture frame rate.
+   
+   if (!$RecordingMovie)
+   {
+       // locate a non-existent filename to use
+       for(%i = 0; %i < 1000; %i++)
+       {
+          %num = %i;
+          if(%num < 10)
+             %num = "0" @ %num;
+          if(%num < 100)
+             %num = "0" @ %num;
+       
+          %filePath = "movies/movie" @ %num;
+          if(!isfile(%filePath))
+             break;
+       }
+       if(%i == 1000)
+          return;
+
+      // Start the movie recording
+      recordMovie(%filePath, %movieFPS, %movieEncodingType);
+      
+   }
+   else
+   {
+      // Stop the current recording
+      stopMovie();
+   }
+}
+
+// Key binding works at any time and not just while in a game.
+GlobalActionMap.bind(keyboard, "alt m", toggleMovieRecording);
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 // Helper Functions
 // Helper Functions

+ 1 - 1
Templates/Empty/game/tools/base/utils/inspector.ed.cs

@@ -105,7 +105,7 @@ function EditorInspectorBase::onAdd( %this )
          superClass = "MenuBuilder";
          superClass = "MenuBuilder";
          isPopup = true;
          isPopup = true;
 
 
-         item[ 0 ] = "Edit Profile" TAB "" TAB "if( !$InGuiEditor ) toggleGuiEditor( true ); GuiEditor.editProfile( %this.inspectorField.getData() );";
+         item[ 0 ] = "Edit Profile" TAB "" TAB "if( !GuiEditorIsActive() ) toggleGuiEditor( true ); GuiEditor.editProfile( %this.inspectorField.getData() );";
          item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );";
          item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );";
          item[ 2 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );";
          item[ 2 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );";
          item[ 3 ] = "-";
          item[ 3 ] = "-";

+ 1 - 1
Templates/Empty/game/tools/forestEditor/forestEditorGui.gui

@@ -252,7 +252,7 @@
                   objectNamesOnly = "1";
                   objectNamesOnly = "1";
                   useInspectorTooltips = "0";
                   useInspectorTooltips = "0";
                   tooltipOnWidthOnly = "0";
                   tooltipOnWidthOnly = "0";
-                  compareToObjectID = "1";
+                  compareToObjectID = "0";
                   canRenameObjects = "1";
                   canRenameObjects = "1";
                   renameInternal = "0";
                   renameInternal = "0";
                   isContainer = "1";
                   isContainer = "1";

+ 1 - 1
Templates/Empty/game/tools/guiEditor/gui/guiEditor.ed.gui

@@ -86,7 +86,7 @@
                minExtent = "8 8";
                minExtent = "8 8";
                canSave = "1";
                canSave = "1";
                visible = "1";
                visible = "1";
-               command = "GuiEditor.switchToWorldEditor();";
+               command = "toggleEditor(1);";
                tooltipProfile = "ToolsGuiToolTipProfile";
                tooltipProfile = "ToolsGuiToolTipProfile";
                ToolTip = "World Editor";
                ToolTip = "World Editor";
                hovertime = "1000";
                hovertime = "1000";

+ 39 - 4
Templates/Empty/game/tools/guiEditor/scripts/guiEditor.ed.cs

@@ -75,11 +75,26 @@ function toggleGuiEditor( %make )
       if( EditorIsActive() && !GuiEditor.toggleIntoEditorGui )
       if( EditorIsActive() && !GuiEditor.toggleIntoEditorGui )
          toggleEditor( true );
          toggleEditor( true );
          
          
-      GuiEdit();
+      if( !isObject( GuiEditCanvas ) )
+         new GuiControl( GuiEditCanvas, EditorGuiGroup );
       
       
-	  // Cancel the scheduled event to prevent
-	  // the level from cycling after it's duration
-	  // has elapsed.
+      if( GuiEditorIsActive() )
+      {
+         GuiEditor.close();
+      }
+      else
+      {
+         GuiEditor.open();
+      
+         // Cancel the scheduled event to prevent
+         // the level from cycling after it's duration
+         // has elapsed.
+         cancel($Game::Schedule);
+      }
+      
+      // Cancel the scheduled event to prevent
+      // the level from cycling after it's duration
+      // has elapsed.
       cancel($Game::Schedule);
       cancel($Game::Schedule);
    }
    }
 }
 }
@@ -98,6 +113,26 @@ package GuiEditor_BlockDialogs
 
 
 //---------------------------------------------------------------------------------------------
 //---------------------------------------------------------------------------------------------
 
 
+function GuiEditor::open(%this)
+{
+   GuiEditCanvas.onCreateMenu();
+
+   GuiEditContent(Canvas.getContent());
+}
+
+function GuiEditor::close(%this)
+{
+   // prevent the mission editor from opening while the GuiEditor is open.
+   if(Canvas.getContent() != GuiEditorGui.getId())
+      return;
+
+   GuiGroup.add(GuiEditorGui);
+   
+   Canvas.setContent(GuiEditor.lastContent);
+   
+   GuiEditCanvas.onDestroyMenu();
+}
+
 function GuiEditor::openForEditing( %this, %content )
 function GuiEditor::openForEditing( %this, %content )
 {   
 {   
    Canvas.setContent( GuiEditorGui );
    Canvas.setContent( GuiEditorGui );

+ 1 - 1
Templates/Empty/game/tools/worldEditor/gui/EditorGui.ed.gui

@@ -67,7 +67,7 @@
          MinExtent = "8 8";
          MinExtent = "8 8";
          canSave = "1";
          canSave = "1";
          Visible = "1";
          Visible = "1";
-         Command = "toggleEditor( true ); GuiEdit(); $GuiEditorBtnPressed = true;";
+         Command = "toggleGuiEditor(true); $GuiEditorBtnPressed = true;";
          tooltipprofile = "ToolsGuiToolTipProfile";
          tooltipprofile = "ToolsGuiToolTipProfile";
          ToolTip = "Open the GuiEditor";
          ToolTip = "Open the GuiEditor";
          hovertime = "1000";
          hovertime = "1000";

+ 17 - 2
Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs

@@ -35,8 +35,6 @@ function EditorGui::init(%this)
    $NextOperationId   = 1;
    $NextOperationId   = 1;
    $HeightfieldDirtyRow = -1;
    $HeightfieldDirtyRow = -1;
 
 
-   %this.buildMenus();
-
    if( !isObject( %this-->ToolsPaletteWindow ) )
    if( !isObject( %this-->ToolsPaletteWindow ) )
    {
    {
       // Load Creator/Inspector GUI
       // Load Creator/Inspector GUI
@@ -1914,6 +1912,8 @@ function Editor::open(%this)
    if(Canvas.getContent() == GuiEditorGui.getId())
    if(Canvas.getContent() == GuiEditorGui.getId())
       return;
       return;
       
       
+   EditorGui.buildMenus();
+      
    if( !EditorGui.isInitialized )
    if( !EditorGui.isInitialized )
       EditorGui.init();
       EditorGui.init();
 
 
@@ -1929,6 +1929,21 @@ function Editor::close(%this, %gui)
    if(isObject(MessageHud))
    if(isObject(MessageHud))
       MessageHud.close();   
       MessageHud.close();   
    EditorGui.writeCameraSettings();
    EditorGui.writeCameraSettings();
+   
+   EditorGui.onDestroyMenu();
+}
+
+function EditorGui::onDestroyMenu(%this)
+{
+   if( !isObject( %this.menuBar ) )
+      return;
+
+   // Destroy menus      
+   while( %this.menuBar.getCount() != 0 )
+      %this.menuBar.getObject( 0 ).delete();
+   
+   %this.menuBar.removeFromCanvas();
+   %this.menuBar.delete();
 }
 }
 
 
 $RelightCallback = "";
 $RelightCallback = "";

+ 9 - 23
Templates/Empty/game/tools/worldEditor/scripts/editor.ed.cs

@@ -99,18 +99,12 @@ function Editor::checkActiveLoadDone()
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 function toggleEditor(%make)
 function toggleEditor(%make)
 {
 {
-   if (Canvas.isFullscreen())
-   {
-      MessageBoxOK("Windowed Mode Required", "Please switch to windowed mode to access the Mission Editor.");
-      return;
-   }
-   
    if (%make)
    if (%make)
-   {      
+   {  
       %timerId = startPrecisionTimer();
       %timerId = startPrecisionTimer();
       
       
-      if( $InGuiEditor )
-         GuiEdit();
+      if( GuiEditorIsActive() )
+         toggleGuiEditor(1);
          
          
       if( !$missionRunning )
       if( !$missionRunning )
       {
       {
@@ -141,29 +135,21 @@ function toggleEditor(%make)
                Editor.close("PlayGui");
                Editor.close("PlayGui");
             }
             }
          }
          }
-         else 
+         else
          {
          {
-            if ( !$GuiEditorBtnPressed )
-            {
-               canvas.pushDialog( EditorLoadingGui );
-               canvas.repaint();
-            }
-            else
-            {
-               $GuiEditorBtnPressed = false;
-            }
+            canvas.pushDialog( EditorLoadingGui );
+            canvas.repaint();
             
             
             Editor.open();
             Editor.open();
 			
 			
-			// Cancel the scheduled event to prevent
-			// the level from cycling after it's duration
-			// has elapsed.
+            // Cancel the scheduled event to prevent
+            // the level from cycling after it's duration
+            // has elapsed.
             cancel($Game::Schedule);
             cancel($Game::Schedule);
             
             
             if (theLevelInfo.type $= "DemoScene")
             if (theLevelInfo.type $= "DemoScene")
                commandToServer('dropCameraAtPlayer', true);
                commandToServer('dropCameraAtPlayer', true);
                
                
-            
             canvas.popDialog(EditorLoadingGui);
             canvas.popDialog(EditorLoadingGui);
          }
          }
          
          

+ 50 - 38
Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs

@@ -42,47 +42,59 @@ function EditorGui::buildMenus(%this)
    }
    }
 
 
    // Sub menus (temporary, until MenuBuilder gets updated)
    // Sub menus (temporary, until MenuBuilder gets updated)
-      // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState.
-      // The new min/max for the editor camera speed range can be set in each level's levelInfo object.
-   %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions)
+   // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState.
+   // The new min/max for the editor camera speed range can be set in each level's levelInfo object.
+   if(!isObject(EditorCameraSpeedOptions))
    {
    {
-      superClass = "MenuBuilder";
-      class = "EditorCameraSpeedMenu";
-      
-      item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5";
-      item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35";
-      item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70";
-      item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100";
-      item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130";
-      item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165";
-      item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200";
-   };
-   %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions)
+      %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions)
+      {
+         superClass = "MenuBuilder";
+         class = "EditorCameraSpeedMenu";
+         
+         item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5";
+         item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35";
+         item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70";
+         item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100";
+         item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130";
+         item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165";
+         item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200";
+      };
+   }
+   if(!isObject(EditorFreeCameraTypeOptions))
    {
    {
-      superClass = "MenuBuilder";
-      class = "EditorFreeCameraTypeMenu";
-      
-      item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");";
-      item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");";
-      Item[2] = "-";
-      item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");";
-      item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");";
-   };
-   %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions)
+      %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions)
+      {
+         superClass = "MenuBuilder";
+         class = "EditorFreeCameraTypeMenu";
+         
+         item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");";
+         item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");";
+         Item[2] = "-";
+         item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");";
+         item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");";
+      };
+   }
+   if(!isObject(EditorPlayerCameraTypeOptions))
    {
    {
-      superClass = "MenuBuilder";
-      class = "EditorPlayerCameraTypeMenu";
-      
-      Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");";
-      Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");";
-   };
-   %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks)
+      %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions)
+      {
+         superClass = "MenuBuilder";
+         class = "EditorPlayerCameraTypeMenu";
+         
+         Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");";
+         Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");";
+      };
+   }
+   if(!isObject(EditorCameraBookmarks))
    {
    {
-      superClass = "MenuBuilder";
-      class = "EditorCameraBookmarksMenu";
-      
-      //item[0] = "None";
-   };
+      %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks)
+      {
+         superClass = "MenuBuilder";
+         class = "EditorCameraBookmarksMenu";
+         
+         //item[0] = "None";
+      };
+   }
    %this.viewTypeMenu = new PopupMenu()
    %this.viewTypeMenu = new PopupMenu()
    {
    {
       superClass = "MenuBuilder";
       superClass = "MenuBuilder";
@@ -98,7 +110,7 @@ function EditorGui::buildMenus(%this)
    };
    };
       
       
    // Menu bar
    // Menu bar
-   %this.menuBar = new MenuBar()
+   %this.menuBar = new MenuBar(WorldEditorMenubar)
    {
    {
       dynamicItemInsertPos = 3;
       dynamicItemInsertPos = 3;
    };
    };

+ 2 - 0
Templates/Full/game/art/datablocks/environment.cs

@@ -83,6 +83,8 @@ datablock LightningData(DefaultStorm)
    thunderSounds[1] = ThunderCrash2Sound;
    thunderSounds[1] = ThunderCrash2Sound;
    thunderSounds[2] = ThunderCrash3Sound;
    thunderSounds[2] = ThunderCrash3Sound;
    thunderSounds[3] = ThunderCrash4Sound;
    thunderSounds[3] = ThunderCrash4Sound;
+
+   strikeTextures[0] = "art/environment/lightning";
 };
 };
 
 
 datablock ReflectorDesc( DefaultCubeDesc )
 datablock ReflectorDesc( DefaultCubeDesc )

BIN
Templates/Full/game/art/environment/lightning.png


+ 1 - 1
Templates/Full/game/art/gui/mainMenuGui.gui

@@ -126,7 +126,7 @@
          profile = "GuiMenuButtonProfile";
          profile = "GuiMenuButtonProfile";
          visible = "1";
          visible = "1";
          active = "1";
          active = "1";
-         command = "GuiEdit();";
+         command = "toggleGuiEditor(1);";
          tooltipProfile = "GuiToolTipProfile";
          tooltipProfile = "GuiToolTipProfile";
          tooltip = "The GUI Editor is accessible in-game by pressing F10";
          tooltip = "The GUI Editor is accessible in-game by pressing F10";
          hovertime = "1000";
          hovertime = "1000";

BIN
Templates/Full/game/art/gui/splash.bmp


BIN
Templates/Full/game/art/gui/splash.png


+ 15 - 0
Templates/Full/game/core/scripts/client/screenshot.cs

@@ -55,6 +55,9 @@ function formatSessionNumber(%number)
 // Records a movie file from the Canvas content using the specified fps.
 // Records a movie file from the Canvas content using the specified fps.
 // Possible encoder values are "PNG" and "THEORA" (default).
 // Possible encoder values are "PNG" and "THEORA" (default).
 //---------------------------------------------------------------------------------------------
 //---------------------------------------------------------------------------------------------
+
+$RecordingMovie = false;
+
 function recordMovie(%movieName, %fps, %encoder)
 function recordMovie(%movieName, %fps, %encoder)
 {
 {
    // If the canvas doesn't exist yet, setup a flag so it'll 
    // If the canvas doesn't exist yet, setup a flag so it'll 
@@ -65,12 +68,24 @@ function recordMovie(%movieName, %fps, %encoder)
    if (%encoder $= "") 
    if (%encoder $= "") 
       %encoder = "THEORA";   
       %encoder = "THEORA";   
    %resolution = Canvas.getVideoMode();
    %resolution = Canvas.getVideoMode();
+   
+   // Start the movie recording
+   ChatHud.AddLine( "\c4Recording movie file to [\c2" @ %movieName @ "\cr].ogv.");
+   echo("Recording movie to: " @ %movieName);   
    startVideoCapture(Canvas, %movieName, %encoder, %fps); 
    startVideoCapture(Canvas, %movieName, %encoder, %fps); 
+   
+    $RecordingMovie = true;
 }
 }
 
 
 function stopMovie()
 function stopMovie()
 {
 {
+   // Stop the current recording
+   ChatHud.AddLine( "\c4Recording movie file finished.");
+   echo("Stopped movie recording");
+   
    stopVideoCapture();
    stopVideoCapture();
+
+   $RecordingMovie = false;
 }
 }
 
 
 /// This is bound in initializeCommon() to take
 /// This is bound in initializeCommon() to take

BIN
Templates/Full/game/core/torque.png


+ 2 - 0
Templates/Full/game/main.cs

@@ -28,6 +28,8 @@ $defaultGame = "scripts";
 
 
 // Set profile directory
 // Set profile directory
 $Pref::Video::ProfilePath = "core/profile";
 $Pref::Video::ProfilePath = "core/profile";
+$Core::windowIcon = "core/torque.png";
+$Core::splashWindowImage = "art/gui/splash.png";
 
 
 function createCanvas(%windowTitle)
 function createCanvas(%windowTitle)
 {
 {

+ 43 - 0
Templates/Full/game/scripts/client/default.bind.cs

@@ -583,6 +583,49 @@ function stopRecordingDemo( %val )
 moveMap.bind( keyboard, F3, startRecordingDemo );
 moveMap.bind( keyboard, F3, startRecordingDemo );
 moveMap.bind( keyboard, F4, stopRecordingDemo );
 moveMap.bind( keyboard, F4, stopRecordingDemo );
 
 
+//------------------------------------------------------------------------------
+// Theora Video Capture (Records a movie file)  
+//------------------------------------------------------------------------------
+
+function toggleMovieRecording(%val)
+{
+   if (!%val)
+      return;
+
+   %movieEncodingType = "THEORA";  // Valid encoder values are "PNG" and "THEORA" (default). 
+   %movieFPS = 30;  // video capture frame rate.
+   
+   if (!$RecordingMovie)
+   {
+       // locate a non-existent filename to use
+       for(%i = 0; %i < 1000; %i++)
+       {
+          %num = %i;
+          if(%num < 10)
+             %num = "0" @ %num;
+          if(%num < 100)
+             %num = "0" @ %num;
+       
+          %filePath = "movies/movie" @ %num;
+          if(!isfile(%filePath))
+             break;
+       }
+       if(%i == 1000)
+          return;
+
+      // Start the movie recording
+      recordMovie(%filePath, %movieFPS, %movieEncodingType);
+      
+   }
+   else
+   {
+      // Stop the current recording
+      stopMovie();
+   }
+}
+
+// Key binding works at any time and not just while in a game.
+GlobalActionMap.bind(keyboard, "alt m", toggleMovieRecording);
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 // Helper Functions
 // Helper Functions

+ 1 - 1
Templates/Full/game/tools/base/utils/inspector.ed.cs

@@ -105,7 +105,7 @@ function EditorInspectorBase::onAdd( %this )
          superClass = "MenuBuilder";
          superClass = "MenuBuilder";
          isPopup = true;
          isPopup = true;
 
 
-         item[ 0 ] = "Edit Profile" TAB "" TAB "if( !$InGuiEditor ) toggleGuiEditor( true ); GuiEditor.editProfile( %this.inspectorField.getData() );";
+         item[ 0 ] = "Edit Profile" TAB "" TAB "if( !GuiEditorIsActive() ) toggleGuiEditor( true ); GuiEditor.editProfile( %this.inspectorField.getData() );";
          item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );";
          item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );";
          item[ 2 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );";
          item[ 2 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );";
          item[ 3 ] = "-";
          item[ 3 ] = "-";

+ 1 - 1
Templates/Full/game/tools/forestEditor/forestEditorGui.gui

@@ -252,7 +252,7 @@
                   objectNamesOnly = "1";
                   objectNamesOnly = "1";
                   useInspectorTooltips = "0";
                   useInspectorTooltips = "0";
                   tooltipOnWidthOnly = "0";
                   tooltipOnWidthOnly = "0";
-                  compareToObjectID = "1";
+                  compareToObjectID = "0";
                   canRenameObjects = "1";
                   canRenameObjects = "1";
                   renameInternal = "0";
                   renameInternal = "0";
                   isContainer = "1";
                   isContainer = "1";

+ 1 - 1
Templates/Full/game/tools/guiEditor/gui/guiEditor.ed.gui

@@ -86,7 +86,7 @@
                minExtent = "8 8";
                minExtent = "8 8";
                canSave = "1";
                canSave = "1";
                visible = "1";
                visible = "1";
-               command = "GuiEditor.switchToWorldEditor();";
+               command = "toggleEditor(1);";
                tooltipProfile = "ToolsGuiToolTipProfile";
                tooltipProfile = "ToolsGuiToolTipProfile";
                ToolTip = "World Editor";
                ToolTip = "World Editor";
                hovertime = "1000";
                hovertime = "1000";

+ 39 - 4
Templates/Full/game/tools/guiEditor/scripts/guiEditor.ed.cs

@@ -75,11 +75,26 @@ function toggleGuiEditor( %make )
       if( EditorIsActive() && !GuiEditor.toggleIntoEditorGui )
       if( EditorIsActive() && !GuiEditor.toggleIntoEditorGui )
          toggleEditor( true );
          toggleEditor( true );
          
          
-      GuiEdit();
+      if( !isObject( GuiEditCanvas ) )
+         new GuiControl( GuiEditCanvas, EditorGuiGroup );
       
       
-	  // Cancel the scheduled event to prevent
-	  // the level from cycling after it's duration
-	  // has elapsed.
+      if( GuiEditorIsActive() )
+      {
+         GuiEditor.close();
+      }
+      else
+      {
+         GuiEditor.open();
+      
+         // Cancel the scheduled event to prevent
+         // the level from cycling after it's duration
+         // has elapsed.
+         cancel($Game::Schedule);
+      }
+      
+      // Cancel the scheduled event to prevent
+      // the level from cycling after it's duration
+      // has elapsed.
       cancel($Game::Schedule);
       cancel($Game::Schedule);
    }
    }
 }
 }
@@ -98,6 +113,26 @@ package GuiEditor_BlockDialogs
 
 
 //---------------------------------------------------------------------------------------------
 //---------------------------------------------------------------------------------------------
 
 
+function GuiEditor::open(%this)
+{
+   GuiEditCanvas.onCreateMenu();
+
+   GuiEditContent(Canvas.getContent());
+}
+
+function GuiEditor::close(%this)
+{
+   // prevent the mission editor from opening while the GuiEditor is open.
+   if(Canvas.getContent() != GuiEditorGui.getId())
+      return;
+
+   GuiGroup.add(GuiEditorGui);
+   
+   Canvas.setContent(GuiEditor.lastContent);
+   
+   GuiEditCanvas.onDestroyMenu();
+}
+
 function GuiEditor::openForEditing( %this, %content )
 function GuiEditor::openForEditing( %this, %content )
 {   
 {   
    Canvas.setContent( GuiEditorGui );
    Canvas.setContent( GuiEditorGui );

+ 1 - 1
Templates/Full/game/tools/worldEditor/gui/EditorGui.ed.gui

@@ -67,7 +67,7 @@
          MinExtent = "8 8";
          MinExtent = "8 8";
          canSave = "1";
          canSave = "1";
          Visible = "1";
          Visible = "1";
-         Command = "toggleEditor( true ); GuiEdit(); $GuiEditorBtnPressed = true;";
+         Command = "toggleGuiEditor(true); $GuiEditorBtnPressed = true;";
          tooltipprofile = "ToolsGuiToolTipProfile";
          tooltipprofile = "ToolsGuiToolTipProfile";
          ToolTip = "Open the GuiEditor";
          ToolTip = "Open the GuiEditor";
          hovertime = "1000";
          hovertime = "1000";

+ 17 - 2
Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs

@@ -35,8 +35,6 @@ function EditorGui::init(%this)
    $NextOperationId   = 1;
    $NextOperationId   = 1;
    $HeightfieldDirtyRow = -1;
    $HeightfieldDirtyRow = -1;
 
 
-   %this.buildMenus();
-
    if( !isObject( %this-->ToolsPaletteWindow ) )
    if( !isObject( %this-->ToolsPaletteWindow ) )
    {
    {
       // Load Creator/Inspector GUI
       // Load Creator/Inspector GUI
@@ -1914,6 +1912,8 @@ function Editor::open(%this)
    if(Canvas.getContent() == GuiEditorGui.getId())
    if(Canvas.getContent() == GuiEditorGui.getId())
       return;
       return;
       
       
+   EditorGui.buildMenus();
+      
    if( !EditorGui.isInitialized )
    if( !EditorGui.isInitialized )
       EditorGui.init();
       EditorGui.init();
 
 
@@ -1929,6 +1929,21 @@ function Editor::close(%this, %gui)
    if(isObject(MessageHud))
    if(isObject(MessageHud))
       MessageHud.close();   
       MessageHud.close();   
    EditorGui.writeCameraSettings();
    EditorGui.writeCameraSettings();
+   
+   EditorGui.onDestroyMenu();
+}
+
+function EditorGui::onDestroyMenu(%this)
+{
+   if( !isObject( %this.menuBar ) )
+      return;
+
+   // Destroy menus      
+   while( %this.menuBar.getCount() != 0 )
+      %this.menuBar.getObject( 0 ).delete();
+   
+   %this.menuBar.removeFromCanvas();
+   %this.menuBar.delete();
 }
 }
 
 
 $RelightCallback = "";
 $RelightCallback = "";

+ 9 - 23
Templates/Full/game/tools/worldEditor/scripts/editor.ed.cs

@@ -99,18 +99,12 @@ function Editor::checkActiveLoadDone()
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 function toggleEditor(%make)
 function toggleEditor(%make)
 {
 {
-   if (Canvas.isFullscreen())
-   {
-      MessageBoxOK("Windowed Mode Required", "Please switch to windowed mode to access the Mission Editor.");
-      return;
-   }
-   
    if (%make)
    if (%make)
-   {      
+   {  
       %timerId = startPrecisionTimer();
       %timerId = startPrecisionTimer();
       
       
-      if( $InGuiEditor )
-         GuiEdit();
+      if( GuiEditorIsActive() )
+         toggleGuiEditor(1);
          
          
       if( !$missionRunning )
       if( !$missionRunning )
       {
       {
@@ -141,29 +135,21 @@ function toggleEditor(%make)
                Editor.close("PlayGui");
                Editor.close("PlayGui");
             }
             }
          }
          }
-         else 
+         else
          {
          {
-            if ( !$GuiEditorBtnPressed )
-            {
-               canvas.pushDialog( EditorLoadingGui );
-               canvas.repaint();
-            }
-            else
-            {
-               $GuiEditorBtnPressed = false;
-            }
+            canvas.pushDialog( EditorLoadingGui );
+            canvas.repaint();
             
             
             Editor.open();
             Editor.open();
 			
 			
-			// Cancel the scheduled event to prevent
-			// the level from cycling after it's duration
-			// has elapsed.
+            // Cancel the scheduled event to prevent
+            // the level from cycling after it's duration
+            // has elapsed.
             cancel($Game::Schedule);
             cancel($Game::Schedule);
             
             
             if (theLevelInfo.type $= "DemoScene")
             if (theLevelInfo.type $= "DemoScene")
                commandToServer('dropCameraAtPlayer', true);
                commandToServer('dropCameraAtPlayer', true);
                
                
-            
             canvas.popDialog(EditorLoadingGui);
             canvas.popDialog(EditorLoadingGui);
          }
          }
          
          

+ 50 - 38
Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs

@@ -42,47 +42,59 @@ function EditorGui::buildMenus(%this)
    }
    }
 
 
    // Sub menus (temporary, until MenuBuilder gets updated)
    // Sub menus (temporary, until MenuBuilder gets updated)
-      // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState.
-      // The new min/max for the editor camera speed range can be set in each level's levelInfo object.
-   %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions)
+   // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState.
+   // The new min/max for the editor camera speed range can be set in each level's levelInfo object.
+   if(!isObject(EditorCameraSpeedOptions))
    {
    {
-      superClass = "MenuBuilder";
-      class = "EditorCameraSpeedMenu";
-      
-      item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5";
-      item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35";
-      item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70";
-      item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100";
-      item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130";
-      item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165";
-      item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200";
-   };
-   %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions)
+      %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions)
+      {
+         superClass = "MenuBuilder";
+         class = "EditorCameraSpeedMenu";
+         
+         item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5";
+         item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35";
+         item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70";
+         item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100";
+         item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130";
+         item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165";
+         item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200";
+      };
+   }
+   if(!isObject(EditorFreeCameraTypeOptions))
    {
    {
-      superClass = "MenuBuilder";
-      class = "EditorFreeCameraTypeMenu";
-      
-      item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");";
-      item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");";
-      Item[2] = "-";
-      item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");";
-      item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");";
-   };
-   %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions)
+      %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions)
+      {
+         superClass = "MenuBuilder";
+         class = "EditorFreeCameraTypeMenu";
+         
+         item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");";
+         item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");";
+         Item[2] = "-";
+         item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");";
+         item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");";
+      };
+   }
+   if(!isObject(EditorPlayerCameraTypeOptions))
    {
    {
-      superClass = "MenuBuilder";
-      class = "EditorPlayerCameraTypeMenu";
-      
-      Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");";
-      Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");";
-   };
-   %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks)
+      %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions)
+      {
+         superClass = "MenuBuilder";
+         class = "EditorPlayerCameraTypeMenu";
+         
+         Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");";
+         Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");";
+      };
+   }
+   if(!isObject(EditorCameraBookmarks))
    {
    {
-      superClass = "MenuBuilder";
-      class = "EditorCameraBookmarksMenu";
-      
-      //item[0] = "None";
-   };
+      %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks)
+      {
+         superClass = "MenuBuilder";
+         class = "EditorCameraBookmarksMenu";
+         
+         //item[0] = "None";
+      };
+   }
    %this.viewTypeMenu = new PopupMenu()
    %this.viewTypeMenu = new PopupMenu()
    {
    {
       superClass = "MenuBuilder";
       superClass = "MenuBuilder";
@@ -98,7 +110,7 @@ function EditorGui::buildMenus(%this)
    };
    };
       
       
    // Menu bar
    // Menu bar
-   %this.menuBar = new MenuBar()
+   %this.menuBar = new MenuBar(WorldEditorMenubar)
    {
    {
       dynamicItemInsertPos = 3;
       dynamicItemInsertPos = 3;
    };
    };

+ 113 - 10
Tools/CMake/torque3d.cmake

@@ -67,17 +67,63 @@ endif()
 option(TORQUE_SFX_OPENAL "OpenAL Sound" ON)
 option(TORQUE_SFX_OPENAL "OpenAL Sound" ON)
 #windows uses openal-soft
 #windows uses openal-soft
 if(WIN32)
 if(WIN32)
-#disable a few things that are not required
-set(ALSOFT_TESTS OFF CACHE BOOL "Build and install test programs" FORCE)
-set(ALSOFT_UTILS OFF CACHE BOOL "Build and install utility programs" FORCE)
-set(ALSOFT_EXAMPLES OFF CACHE BOOL "Build and install example programs" FORCE)
-set(ALSOFT_CONFIG OFF CACHE BOOL "Install alsoft.conf sample configuration file" FORCE)
-set(ALSOFT_INSTALL OFF CACHE BOOL "Install headers and libraries" FORCE)
-set(ALSOFT_NO_CONFIG_UTIL OFF CACHE BOOL "Disable building the alsoft-config utility" FORCE)
-set(ALSOFT_HRTF_DEFS OFF CACHE BOOL "Install HRTF definition files" FORCE)
-set(ALSOFT_AMBDEC_PRESETS OFF CACHE BOOL "Install AmbDec presets" FORCE)
-add_subdirectory( ${libDir}/openal-soft ${CMAKE_CURRENT_BINARY_DIR}/openal-soft)
+    #disable a few things that are not required
+    set(ALSOFT_TESTS OFF CACHE BOOL "Build and install test programs" FORCE)
+    set(ALSOFT_UTILS OFF CACHE BOOL "Build and install utility programs" FORCE)
+    set(ALSOFT_EXAMPLES OFF CACHE BOOL "Build and install example programs" FORCE)
+    set(ALSOFT_CONFIG OFF CACHE BOOL "Install alsoft.conf sample configuration file" FORCE)
+    set(ALSOFT_INSTALL OFF CACHE BOOL "Install headers and libraries" FORCE)
+    set(ALSOFT_NO_CONFIG_UTIL OFF CACHE BOOL "Disable building the alsoft-config utility" FORCE)
+    set(ALSOFT_HRTF_DEFS OFF CACHE BOOL "Install HRTF definition files" FORCE)
+    set(ALSOFT_AMBDEC_PRESETS OFF CACHE BOOL "Install AmbDec presets" FORCE)
+    
+    add_subdirectory( ${libDir}/openal-soft ${CMAKE_CURRENT_BINARY_DIR}/openal-soft)
+endif()
+
+if(TORQUE_SFX_OPENAL)
+    #Hide some unnecessary fields as advanced
+    mark_as_advanced(ALSOFT_AMBDEC_PRESETS)
+    mark_as_advanced(ALSOFT_BACKEND_DSOUND)
+    mark_as_advanced(ALSOFT_BACKEND_MMDEVAPI)
+    mark_as_advanced(ALSOFT_BACKEND_WAVE)
+    mark_as_advanced(ALSOFT_BACKEND_WINMM)
+    mark_as_advanced(ALSOFT_CONFIG)
+    mark_as_advanced(ALSOFT_CPUEXT_SSE)
+    mark_as_advanced(ALSOFT_CPUEXT_SSE2)
+    mark_as_advanced(ALSOFT_CPUEXT_SSE3)
+    mark_as_advanced(ALSOFT_CPUEXT_SSE4_1)
+    mark_as_advanced(ALSOFT_DLOPEN)
+    mark_as_advanced(ALSOFT_EMBED_HRTF_DATA)
+    mark_as_advanced(ALSOFT_EXAMPLES)
+    mark_as_advanced(ALSOFT_HRTF_DEFS)
+    mark_as_advanced(ALSOFT_INSTALL)
+    mark_as_advanced(ALSOFT_NO_CONFIG_UTIL)
+    mark_as_advanced(ALSOFT_NO_UID_DEFS)
+    mark_as_advanced(ALSOFT_REQUIRE_ALSA)
+    mark_as_advanced(ALSOFT_REQUIRE_COREAUDIO)
+    mark_as_advanced(ALSOFT_REQUIRE_DSOUND)
+    mark_as_advanced(ALSOFT_REQUIRE_JACK)
+    mark_as_advanced(ALSOFT_REQUIRE_MMDEVAPI)
+    mark_as_advanced(ALSOFT_REQUIRE_NEON)
+    mark_as_advanced(ALSOFT_REQUIRE_OPENSL)
+    mark_as_advanced(ALSOFT_REQUIRE_OSS)
+    mark_as_advanced(ALSOFT_REQUIRE_PORTAUDIO)
+    mark_as_advanced(ALSOFT_REQUIRE_PULSEAUDIO)
+    mark_as_advanced(ALSOFT_REQUIRE_QSA)
+    mark_as_advanced(ALSOFT_REQUIRE_SNDIO)
+    mark_as_advanced(ALSOFT_REQUIRE_SOLARIS)
+    mark_as_advanced(ALSOFT_REQUIRE_SSE)
+    mark_as_advanced(ALSOFT_REQUIRE_SSE2)
+    mark_as_advanced(ALSOFT_REQUIRE_SSE4_1)
+    mark_as_advanced(ALSOFT_REQUIRE_WINMM)
+    mark_as_advanced(ALSOFT_TESTS)
+    mark_as_advanced(ALSOFT_UTILS)
+    mark_as_advanced(ALSOFT_WERROR)
+    mark_as_advanced(COREAUDIO_FRAMEWORK)
+    mark_as_advanced(CMAKE_DEBUG_POSTFIX)
+    mark_as_advanced(FORCE_STATIC_VCRT)
 endif()
 endif()
+
 mark_as_advanced(TORQUE_SFX_OPENAL)
 mark_as_advanced(TORQUE_SFX_OPENAL)
 option(TORQUE_HIFI "HIFI? support" OFF)
 option(TORQUE_HIFI "HIFI? support" OFF)
 mark_as_advanced(TORQUE_HIFI)
 mark_as_advanced(TORQUE_HIFI)
@@ -691,6 +737,63 @@ if(TORQUE_SDL)
     addDef(TORQUE_SDL)
     addDef(TORQUE_SDL)
     addInclude(${libDir}/sdl/include)
     addInclude(${libDir}/sdl/include)
     addLib(SDL2)
     addLib(SDL2)
+
+    SET(VIDEO_WAYLAND OFF CACHE BOOL "" FORCE)
+    mark_as_advanced(3DNOW)
+    mark_as_advanced(ALSA)
+    mark_as_advanced(ALTIVEC)
+    mark_as_advanced(ARTS)
+    mark_as_advanced(ASSEMBLY)
+    mark_as_advanced(ASSERTIONS)
+    mark_as_advanced(DIRECTX)
+    mark_as_advanced(DISKAUDIO)
+    mark_as_advanced(DUMMYAUDIO)
+    mark_as_advanced(ESD)
+    mark_as_advanced(FUSIONSOUND)
+    mark_as_advanced(INPUT_TSLIB)
+    mark_as_advanced(LIBC)
+    mark_as_advanced(MMX)
+    mark_as_advanced(NAS)
+    mark_as_advanced(NAS_SHARED)
+    mark_as_advanced(OSS)
+    mark_as_advanced(PTHREADS)
+    mark_as_advanced(PULSEAUDIO)
+    mark_as_advanced(RENDER_D3D)
+    mark_as_advanced(RPATH)
+    mark_as_advanced(SNDIO)
+    mark_as_advanced(SSE)
+    mark_as_advanced(SSE2)
+    mark_as_advanced(SSEMATH)
+    mark_as_advanced(WINDRES)
+    mark_as_advanced(SDL_ATOMIC)
+    mark_as_advanced(SDL_AUDIO)
+    mark_as_advanced(SDL_CPUINFO)
+    mark_as_advanced(SDL_DLOPEN)
+    mark_as_advanced(SDL_EVENTS)
+    mark_as_advanced(SDL_FILE)
+    mark_as_advanced(SDL_FILESYSTEM)
+    mark_as_advanced(SDL_HAPTIC)
+    mark_as_advanced(SDL_JOYSTICK)
+    mark_as_advanced(SDL_LOADSO)
+    mark_as_advanced(SDL_POWER)
+    mark_as_advanced(SDL_RENDER)
+    mark_as_advanced(SDL_SHARED)
+    mark_as_advanced(SDL_STATIC)
+    mark_as_advanced(SDL_THREADS)
+    mark_as_advanced(SDL_TIMERS)
+    mark_as_advanced(SDL_VIDEO)
+    mark_as_advanced(CLOCK_GETTIME)
+    mark_as_advanced(GCC_ATOMICS)
+    mark_as_advanced(VIDEO_WAYLAND)
+    mark_as_advanced(VIDEO_COCOA)
+    mark_as_advanced(VIDEO_DIRECTFB)
+    mark_as_advanced(VIDEO_DUMMY)
+    mark_as_advanced(VIDEO_MIR)
+    mark_as_advanced(VIDEO_OPENGL)
+    mark_as_advanced(VIDEO_OPENGLES)
+    mark_as_advanced(VIDEO_RPI)
+    mark_as_advanced(VIDEO_VIVANTE)
+    mark_as_advanced(VIDEO_X11)
 endif()
 endif()
 
 
 if(TORQUE_STATIC_CODE_ANALYSIS)
 if(TORQUE_STATIC_CODE_ANALYSIS)