Răsfoiți Sursa

SFXEmitter play pause and stop buttons (#1115)

-Add buttons to the inspector for SFXEmitter that will play pause and stop the sfxEmitter.
NOTE: Purely effects the state of the emitter when in the editor this will not effect sfxEmitter functionality in a level.
marauder2k7 1 an în urmă
părinte
comite
54959f0d19

+ 146 - 0
Engine/source/T3D/sfx/sfxEmitter.cpp

@@ -89,6 +89,120 @@ ColorI SFXEmitter::smRenderColorOutsideVolume( 255, 0, 0, 255 );
 ColorI SFXEmitter::smRenderColorRangeSphere( 200, 0, 0, 90 );
 
 
+
+//-----------------------------------------------------------------------------
+
+ConsoleType(SoundControls, TypeSoundControls, bool, "")
+
+ConsoleGetType(TypeSoundControls)
+{
+   return "";
+}
+ConsoleSetType(TypeSoundControls)
+{
+}
+
+IMPLEMENT_CONOBJECT(GuiInspectorTypeSoundControls);
+ConsoleDocClass(GuiInspectorTypeSoundControls,
+   "@brief Inspector field type for Controlling playback of sounds\n\n"
+   "Editor use only.\n\n"
+   "@internal"
+);
+
+void GuiInspectorTypeSoundControls::consoleInit()
+{
+   Parent::consoleInit();
+
+   ConsoleBaseType::getType(TypeSoundControls)->setInspectorFieldType("GuiInspectorTypeSoundControls");
+}
+
+GuiControl* GuiInspectorTypeSoundControls::constructEditControl()
+{
+   // Create base filename edit controls
+   GuiControl* retCtrl = Parent::constructEditControl();
+   if (retCtrl == NULL)
+      return retCtrl;
+
+   char szBuffer[512];
+
+   setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString());
+
+   mPlayButton = new GuiBitmapButtonCtrl();
+   dSprintf(szBuffer, sizeof(szBuffer), "%d.play();", mInspector->getInspectObject()->getId());
+   mPlayButton->setField("Command", szBuffer);
+
+   mPlayButton->setBitmap(StringTable->insert("ToolsModule:playbutton_n_image"));
+
+   mPlayButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
+   mPlayButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
+   mPlayButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
+   mPlayButton->setDataField(StringTable->insert("tooltip"), NULL, "Play this sound emitter");
+
+   mPlayButton->registerObject();
+   addObject(mPlayButton);
+
+   mPauseButton = new GuiBitmapButtonCtrl();
+   dSprintf(szBuffer, sizeof(szBuffer), "%d.pause();", mInspector->getInspectObject()->getId());
+   mPauseButton->setField("Command", szBuffer);
+
+   mPauseButton->setBitmap(StringTable->insert("ToolsModule:pausebutton_n_image"));
+
+   mPauseButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
+   mPauseButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
+   mPauseButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
+   mPauseButton->setDataField(StringTable->insert("tooltip"), NULL, "Pause this sound emitter");
+
+   mPauseButton->registerObject();
+   addObject(mPauseButton);
+
+   mStopButton = new GuiBitmapButtonCtrl();
+   dSprintf(szBuffer, sizeof(szBuffer), "%d.stop();", mInspector->getInspectObject()->getId());
+   mStopButton->setField("Command", szBuffer);
+
+   mStopButton->setBitmap(StringTable->insert("ToolsModule:stopbutton_n_image"));
+
+   mStopButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
+   mStopButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
+   mStopButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
+   mStopButton->setDataField(StringTable->insert("tooltip"), NULL, "Stop this sound emitter");
+
+   mStopButton->registerObject();
+   addObject(mStopButton);
+
+   return retCtrl;
+}
+
+bool GuiInspectorTypeSoundControls::updateRects()
+{
+   S32 dividerPos, dividerMargin;
+   mInspector->getDivider(dividerPos, dividerMargin);
+   Point2I fieldExtent = getExtent();
+   Point2I fieldPos = getPosition();
+
+   bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
+
+   if (mPlayButton != NULL)
+   {
+      RectI shapeEdRect(2, 2, 16, 16);
+      resized |= mPlayButton->resize(shapeEdRect.point, shapeEdRect.extent);
+   }
+
+   if (mPauseButton != NULL)
+   {
+      RectI shapeEdRect(20, 2, 16, 16);
+      resized |= mPauseButton->resize(shapeEdRect.point, shapeEdRect.extent);
+   }
+
+   if (mStopButton != NULL)
+   {
+      RectI shapeEdRect(38, 2, 16, 16);
+      resized |= mStopButton->resize(shapeEdRect.point, shapeEdRect.extent);
+   }
+
+   return resized;
+}
+
+
 //-----------------------------------------------------------------------------
 
 SFXEmitter::SFXEmitter()
@@ -192,6 +306,8 @@ void SFXEmitter::initPersistFields()
 
    addGroup( "Sound" );
 
+      addField("Controls", TypeSoundControls, 0, "");
+
       addField( "playOnAdd",           TypeBool,      Offset( mPlayOnAdd, SFXEmitter ),
          "Whether playback of the emitter's sound should start as soon as the emitter object is added to the level.\n"
          "If this is true, the emitter will immediately start to play when the level is loaded." );
@@ -366,6 +482,7 @@ U32 SFXEmitter::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
 
    // Write the source playback state.
    stream->writeFlag( mask & SourcePlayMask );
+   stream->writeFlag( mask & SourcePauseMask );
    stream->writeFlag( mask & SourceStopMask );
 
    return retMask;
@@ -491,6 +608,8 @@ void SFXEmitter::unpackUpdate( NetConnection *conn, BitStream *stream )
    // Check the source playback masks.
    if ( stream->readFlag() ) // SourcePlayMask
       play();
+   if (stream->readFlag()) //SourcePauseMask
+      pause();
    if ( stream->readFlag() ) // SourceStopMask
       stop();
 }
@@ -1000,6 +1119,23 @@ void SFXEmitter::play()
 
 //-----------------------------------------------------------------------------
 
+void SFXEmitter::pause()
+{
+   if (mSource)
+      mSource->pause();
+   else
+   {
+      // By clearing the playback masks first we
+      // ensure the last playback command called 
+      // within a single tick is the one obeyed.
+      clearMaskBits(AllSourceMasks);
+
+      setMaskBits(SourcePauseMask);
+   }
+}
+
+//-----------------------------------------------------------------------------
+
 void SFXEmitter::stop()
 {
    if ( mSource )
@@ -1114,6 +1250,15 @@ DefineEngineMethod( SFXEmitter, play, void, (),,
 
 //-----------------------------------------------------------------------------
 
+DefineEngineMethod(SFXEmitter, pause, void, (), ,
+   "Manually pause playback of the emitter's sound.\n"
+   "If this is called on the server-side object, the pause command will be related to all client-side ghosts.\n")
+{
+   object->pause();
+}
+
+//-----------------------------------------------------------------------------
+
 DefineEngineMethod( SFXEmitter, stop, void, (),,
    "Manually stop playback of the emitter's sound.\n"
    "If this is called on the server-side object, the stop command will be related to all client-side ghosts.\n" )
@@ -1131,3 +1276,4 @@ DefineEngineMethod( SFXEmitter, getSource, SFXSource*, (),,
 {
    return object->getSource();
 }
+

+ 21 - 1
Engine/source/T3D/sfx/sfxEmitter.h

@@ -41,6 +41,21 @@
 class SFXSource;
 class SFXTrack;
 
+DefineConsoleType(TypeSoundControls, bool)
+class GuiInspectorTypeSoundControls : public GuiInspectorField
+{
+   typedef GuiInspectorField Parent;
+public:
+   GuiBitmapButtonCtrl* mPlayButton;
+   GuiBitmapButtonCtrl* mPauseButton;
+   GuiBitmapButtonCtrl* mStopButton;
+
+   DECLARE_CONOBJECT(GuiInspectorTypeSoundControls);
+   static void consoleInit();
+
+   virtual GuiControl* constructEditControl();
+   virtual bool updateRects();
+};
 //RDTODO: make 3D sound emitters yield their source when being culled
 
 /// The SFXEmitter is used to place 2D or 3D sounds into a 
@@ -69,7 +84,8 @@ class SFXEmitter : public SceneObject
          DirtyUpdateMask      = BIT(2),
 
          SourcePlayMask       = BIT(3),
-         SourceStopMask       = BIT(4),
+         SourcePauseMask       = BIT(4),
+         SourceStopMask       = BIT(5),
 
          AllSourceMasks = SourcePlayMask | SourceStopMask,
       };
@@ -219,6 +235,10 @@ class SFXEmitter : public SceneObject
       /// the emitter source is not already playing.
       void play();
 
+      /// Sends network event to pause playback if 
+      /// the emitter source is already playing.
+      void pause();
+
       /// Sends network event to stop emitter 
       /// playback on all ghosted clients.
       void stop();

BIN
Templates/BaseGame/game/tools/worldEditor/images/toolbar/pausebutton_h.png


+ 8 - 0
Templates/BaseGame/game/tools/worldEditor/images/toolbar/pausebutton_h_image.asset.taml

@@ -0,0 +1,8 @@
+<ImageAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="pausebutton_h_image"
+    imageFile="@assetFile=pausebutton_h.png"
+    UseMips="true"
+    isHDRImage="false"
+    imageType="Albedo" />

BIN
Templates/BaseGame/game/tools/worldEditor/images/toolbar/pausebutton_n.png


+ 8 - 0
Templates/BaseGame/game/tools/worldEditor/images/toolbar/pausebutton_n_image.asset.taml

@@ -0,0 +1,8 @@
+<ImageAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="pausebutton_n_image"
+    imageFile="@assetFile=pausebutton_n.png"
+    UseMips="true"
+    isHDRImage="false"
+    imageType="Albedo" />

BIN
Templates/BaseGame/game/tools/worldEditor/images/toolbar/stopbutton_h.png


+ 8 - 0
Templates/BaseGame/game/tools/worldEditor/images/toolbar/stopbutton_h_image.asset.taml

@@ -0,0 +1,8 @@
+<ImageAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="stopbutton_h_image"
+    imageFile="@assetFile=stopbutton_h.png"
+    UseMips="true"
+    isHDRImage="false"
+    imageType="Albedo" />

BIN
Templates/BaseGame/game/tools/worldEditor/images/toolbar/stopbutton_n.png


+ 8 - 0
Templates/BaseGame/game/tools/worldEditor/images/toolbar/stopbutton_n_image.asset.taml

@@ -0,0 +1,8 @@
+<ImageAsset
+    canSave="true"
+    canSaveDynamicFields="true"
+    AssetName="stopbutton_n_image"
+    imageFile="@assetFile=stopbutton_n.png"
+    UseMips="true"
+    isHDRImage="false"
+    imageType="Albedo" />