浏览代码

Merge pull request #960 from Azaezel/alpha41/audioGuiCtrl2

audio gui control
Brian Roberts 2 年之前
父节点
当前提交
6f2e9adc70
共有 2 个文件被更改,包括 311 次插入0 次删除
  1. 209 0
      Engine/source/gui/shiny/guiAudioCtrl.cpp
  2. 102 0
      Engine/source/gui/shiny/guiAudioCtrl.h

+ 209 - 0
Engine/source/gui/shiny/guiAudioCtrl.cpp

@@ -0,0 +1,209 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+#include "gui/shiny/guiAudioCtrl.h"
+#include "console/engineAPI.h"
+#include "sfx/sfxSystem.h"
+#include "sfx/sfxTrack.h"
+#include "sfx/sfxSource.h"
+#include "sfx/sfxTypes.h"
+
+#define TickMs      32
+
+IMPLEMENT_CONOBJECT( GuiAudioCtrl );
+
+ConsoleDocClass( GuiAudioCtrl,
+	"@brief Brief Description.\n\n"
+	"Audio PLayback.\n\n"
+
+	"@ingroup GuiUtil\n");
+
+GuiAudioCtrl::GuiAudioCtrl()
+{
+   INIT_ASSET(Sound);
+   mTickPeriodMS = 100;
+   mLastThink = 0;
+   mCurrTick = 0;
+   mPlayIf = "";
+   mSoundPlaying = NULL;
+
+   mUseTrackDescriptionOnly = false;
+   mDescription.mIs3D = false;
+   mDescription.mIsLooping = true;
+   mDescription.mIsStreaming = false;
+   mDescription.mFadeInTime = -1.f;
+   mDescription.mFadeOutTime = -1.f;
+
+   mVolume = 1;
+   mPitch = 1;
+   mFadeInTime = -1;
+   mFadeOutTime = -1;
+   mSourceGroup = NULL;
+   setProcessTicks();
+}
+
+GuiAudioCtrl::~GuiAudioCtrl()
+{
+   if (mSoundPlaying)
+      mSoundPlaying->stop();
+   SFX_DELETE(mSoundPlaying);
+}
+
+bool GuiAudioCtrl::onWake()
+{
+   return Parent::onWake();
+}
+
+void GuiAudioCtrl::onSleep()
+{
+   if (mSoundPlaying)
+      mSoundPlaying->stop();
+   SFX_DELETE(mSoundPlaying);
+   Parent::onSleep();
+}
+
+void GuiAudioCtrl::processTick()
+{
+
+   if (mLastThink + mTickPeriodMS < mCurrTick)
+   {
+      mCurrTick = 0;
+      mLastThink = 0;
+      if (isSoundValid())
+      {
+         _update();
+      }
+   }
+   else
+   {
+      mCurrTick += TickMs;
+   }
+}
+
+bool GuiAudioCtrl::testCondition()
+{
+   if (mPlayIf.isEmpty())
+      return true; //we've got no tests to run so just do it
+
+   //test the mapper plugged in condition line
+   String resVar = getIdString() + String(".result");
+   Con::setBoolVariable(resVar.c_str(), false);
+   String command = resVar + "=" + mPlayIf + ";";
+   Con::evaluatef(command.c_str());
+   if (Con::getBoolVariable(resVar.c_str()) == 1)
+   {
+      return true;
+   }
+   return false;
+}
+
+void GuiAudioCtrl::initPersistFields()
+{
+   addGroup("Sounds");
+      INITPERSISTFIELD_SOUNDASSET(Sound, GuiAudioCtrl, "Looping SoundAsset to play while GuiAudioCtrl is active.");
+      addField("tickPeriodMS", TypeS32, Offset(mTickPeriodMS, GuiAudioCtrl),
+         "@brief Time in milliseconds between calls to onTick().\n\n"
+         "@see onTickTrigger()\n");
+      addField("playIf", TypeCommand, Offset(mPlayIf, GuiAudioCtrl), "evaluation condition to trip playback (true/false)");
+      addField("useTrackDescriptionOnly", TypeBool, Offset(mUseTrackDescriptionOnly, GuiAudioCtrl),
+         "If this is true, all fields except for #playOnAdd and #track are ignored on the emitter object.\n"
+         "This is useful to prevent fields in the #track's description from being overridden by emitter fields.");
+      addField("sourceGroup", TypeSFXSourceName, Offset(mSourceGroup, GuiAudioCtrl),
+         "The SFXSource to which to assign the sound of this emitter as a child.\n"
+         "@note This field is ignored if #useTrackDescriptionOnly is true.\n\n"
+         "@see SFXDescription::sourceGroup");
+      addField("volume", TypeF32, Offset(mVolume, GuiAudioCtrl),
+         "Volume level to apply to the sound.\n"
+         "@note This field is ignored if #useTrackDescriptionOnly is true.\n\n"
+         "@see SFXDescription::volume");
+      addField("pitch", TypeF32, Offset(mPitch, GuiAudioCtrl),
+         "Pitch shift to apply to the sound.  Default is 1 = play at normal speed.\n"
+         "@note This field is ignored if #useTrackDescriptionOnly is true.\n\n"
+         "@see SFXDescription::pitch");
+      addField("fadeInTime", TypeF32, Offset(mFadeInTime, GuiAudioCtrl),
+         "Number of seconds to gradually fade in volume from zero when playback starts.\n"
+         "@note This field is ignored if #useTrackDescriptionOnly is true.\n\n"
+         "@see SFXDescription::fadeInTime");
+      addField("fadeOutTime", TypeF32, Offset(mFadeOutTime, GuiAudioCtrl),
+         "Number of seconds to gradually fade out volume down to zero when playback is stopped or paused.\n"
+         "@note This field is ignored if #useTrackDescriptionOnly is true.\n\n"
+         "@see SFXDescription::fadeOutTime");
+   endGroup("Sounds");
+
+   Parent::initPersistFields();
+}
+
+void GuiAudioCtrl::_update()
+{
+   if (isSoundValid())
+   {
+      //mLocalProfile = *mSoundAsset->getSfxProfile();
+      mDescription = *mSoundAsset->getSfxDescription();
+   }
+
+   // Make sure all the settings are valid.
+   mDescription.validate();
+
+   bool useTrackDescriptionOnly = (mUseTrackDescriptionOnly && getSoundProfile());
+
+   if (getSoundProfile())
+   {
+      if (mSoundPlaying == NULL)
+      {
+         mSoundPlaying = SFX->createSource(getSoundProfile());
+      }
+   }
+
+   // The rest only applies if we have a source.
+   if (mSoundPlaying && !useTrackDescriptionOnly)
+   {
+      
+      // Set the volume irrespective of the profile.
+      if (mSourceGroup)
+      {
+         mSourceGroup->addObject(mSoundPlaying);
+         mSoundPlaying->setVolume(mSourceGroup->getVolume() * mVolume);
+      }
+      else
+      {
+         mSoundPlaying->setVolume(mVolume);
+      }
+
+      mSoundPlaying->setPitch(mPitch);
+      mSoundPlaying->setFadeTimes(mFadeInTime, mFadeOutTime);
+
+   }
+
+   if (testCondition() && isActive() && isAwake())
+   {
+      if (mSoundPlaying && !mSoundPlaying->isPlaying())
+      {
+         mSoundPlaying->play();
+      }
+   }
+   else
+   {
+      if (mSoundPlaying != NULL)
+      {
+         mSoundPlaying->stop();
+      }
+   }
+}

+ 102 - 0
Engine/source/gui/shiny/guiAudioCtrl.h

@@ -0,0 +1,102 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _GUIAUDIOCTRL_H_
+#define _GUIAUDIOCTRL_H_
+
+#ifndef _GUITICKCTRL_H_
+#include "gui/shiny/guiTickCtrl.h"
+#endif
+
+#ifndef SOUND_ASSET_H
+#include "T3D/assets/SoundAsset.h"
+#endif
+
+/// This Gui Control is designed to be subclassed to let people create controls
+/// which want to receive update ticks at a constant interval. This class was
+/// created to be the Parent class of a control which used a DynamicTexture
+/// along with a VectorField to create warping effects much like the ones found
+/// in visualization displays for iTunes or Winamp. Those displays are updated
+/// at the framerate frequency. This works fine for those effects, however for
+/// an application of the same type of effects for things like Gui transitions
+/// the framerate-driven update frequency is not desirable because it does not
+/// allow the developer to be able to have any idea of a consistent user-experience.
+///
+/// Enter the ITickable interface. This lets the Gui control, in this case, update
+/// the dynamic texture at a constant rate of once per tick, even though it gets
+/// rendered every frame, thus creating a framerate-independent update frequency
+/// so that the effects are at a consistent speed regardless of the specifics
+/// of the system the user is on. This means that the screen-transitions will
+/// occur in the same time on a machine getting 300fps in the Gui shell as a
+/// machine which gets 150fps in the Gui shell.
+/// @see ITickable
+class GuiAudioCtrl : public GuiTickCtrl
+{
+   typedef GuiTickCtrl Parent;
+
+private:
+
+protected:
+
+   // So this can be instantiated and not be a pure virtual class
+   void interpolateTick( F32 delta ) {};
+   void processTick();
+   void advanceTime( F32 timeDelta ) {};
+
+   S32 mTickPeriodMS;
+   U32 mLastThink;
+   U32 mCurrTick;
+   String mPlayIf;
+   SFXSource* mSoundPlaying;
+   /// Whether to leave sound setup exclusively to the assigned mTrack and not
+   /// override part of the track's description with emitter properties.
+   bool mUseTrackDescriptionOnly;
+
+   /// The description and variant values used by the local profile.
+   SFXDescription mDescription;
+   SFXSource* mSourceGroup;
+   F32 mVolume;
+   F32 mPitch;
+   F32 mFadeInTime;
+   F32 mFadeOutTime;
+
+   /// Called when the emitter state has been marked
+   /// dirty and the source needs to be updated.
+   void _update();
+
+public:
+   DECLARE_SOUNDASSET(GuiAudioCtrl, Sound);
+   DECLARE_ASSET_SETGET(GuiAudioCtrl, Sound);
+   GuiAudioCtrl();
+   ~GuiAudioCtrl();
+   // GuiControl.
+   bool onWake();
+   void onSleep();
+   void setActive(bool value) {};
+   bool testCondition();
+   static void initPersistFields();
+   DECLARE_CONOBJECT(GuiAudioCtrl);
+   DECLARE_CATEGORY( "Gui Other" );
+};
+
+
+#endif