mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 08:04:40 +00:00
Merge remote-tracking branch 'upstream/development' into AppleToolchainTest
This commit is contained in:
commit
2b2ce0229c
22 changed files with 749 additions and 246 deletions
|
|
@ -44,6 +44,10 @@
|
||||||
#include "sfx/sfxSource.h"
|
#include "sfx/sfxSource.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _SFXPROFILE_H_
|
||||||
|
#include "sfx/sfxProfile.h"
|
||||||
|
#endif // !_SFXPROFILE_H_
|
||||||
|
|
||||||
// Debug Profiling.
|
// Debug Profiling.
|
||||||
#include "platform/profiler.h"
|
#include "platform/profiler.h"
|
||||||
#include "sfx/sfxTypes.h"
|
#include "sfx/sfxTypes.h"
|
||||||
|
|
@ -119,8 +123,28 @@ const String SoundAsset::mErrCodeStrings[] =
|
||||||
SoundAsset::SoundAsset()
|
SoundAsset::SoundAsset()
|
||||||
: AssetBase()
|
: AssetBase()
|
||||||
{
|
{
|
||||||
mSoundFile = StringTable->EmptyString();
|
dMemset(mPlaylist.mSlots.mReplayMode, 0, sizeof(mPlaylist.mSlots.mReplayMode));
|
||||||
mSoundPath = StringTable->EmptyString();
|
dMemset(mPlaylist.mSlots.mTransitionIn, 0, sizeof(mPlaylist.mSlots.mTransitionIn));
|
||||||
|
dMemset(mPlaylist.mSlots.mRepeatCount, 0, sizeof(mPlaylist.mSlots.mRepeatCount));
|
||||||
|
dMemset(mPlaylist.mSlots.mState, 0, sizeof(mPlaylist.mSlots.mState));
|
||||||
|
dMemset(mPlaylist.mSlots.mTrack, 0, sizeof(mPlaylist.mSlots.mTrack));
|
||||||
|
dMemset(mPlaylist.mSlots.mStateMode, 0, sizeof(mPlaylist.mSlots.mStateMode));
|
||||||
|
|
||||||
|
for (U32 i = 0; i < SFXPlayList::NUM_SLOTS; i++)
|
||||||
|
{
|
||||||
|
mSoundFile[i] = StringTable->EmptyString();
|
||||||
|
mSoundPath[i] = StringTable->EmptyString();
|
||||||
|
|
||||||
|
mPlaylist.mSlots.mTransitionOut[i] = SFXPlayList::TRANSITION_Wait;
|
||||||
|
mPlaylist.mSlots.mVolumeScale.mValue[i] = 1.f;
|
||||||
|
mPlaylist.mSlots.mPitchScale.mValue[i] = 1.f;
|
||||||
|
mPlaylist.mSlots.mFadeTimeIn.mValue[i] = -1.f; // Don't touch by default.
|
||||||
|
mPlaylist.mSlots.mFadeTimeOut.mValue[i] = -1.f; // Don't touch by default.
|
||||||
|
mPlaylist.mSlots.mMinDistance.mValue[i] = -1.f; // Don't touch by default.
|
||||||
|
mPlaylist.mSlots.mMaxDistance.mValue[i] = -1.f; // Don't touch by default.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
mSubtitleString = StringTable->EmptyString();
|
mSubtitleString = StringTable->EmptyString();
|
||||||
|
|
||||||
mLoadedState = AssetErrCode::NotLoaded;
|
mLoadedState = AssetErrCode::NotLoaded;
|
||||||
|
|
@ -143,6 +167,14 @@ SoundAsset::SoundAsset()
|
||||||
mProfileDesc.mPriority = 1.0f;
|
mProfileDesc.mPriority = 1.0f;
|
||||||
mProfileDesc.mSourceGroup = NULL;
|
mProfileDesc.mSourceGroup = NULL;
|
||||||
|
|
||||||
|
mIsPlaylist = false;
|
||||||
|
|
||||||
|
mPlaylist.mNumSlotsToPlay = SFXPlayList::SFXPlaylistSettings::NUM_SLOTS;
|
||||||
|
mPlaylist.mRandomMode = SFXPlayList::RANDOM_NotRandom;
|
||||||
|
mPlaylist.mTrace = false;
|
||||||
|
mPlaylist.mLoopMode = SFXPlayList::LOOP_All;
|
||||||
|
mPlaylist.mActiveSlots = 12;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -158,9 +190,79 @@ void SoundAsset::initPersistFields()
|
||||||
docsURL;
|
docsURL;
|
||||||
// Call parent.
|
// Call parent.
|
||||||
Parent::initPersistFields();
|
Parent::initPersistFields();
|
||||||
|
addArray("slots", SFXPlayList::SFXPlaylistSettings::NUM_SLOTS);
|
||||||
|
addProtectedField("soundFile", TypeAssetLooseFilePath, Offset(mSoundFile, SoundAsset),
|
||||||
|
&_setSoundFile, &_getSoundFile, SFXPlayList::SFXPlaylistSettings::NUM_SLOTS, "Path to the sound file.");
|
||||||
|
|
||||||
addProtectedField("soundFile", TypeAssetLooseFilePath, Offset(mSoundFile, SoundAsset),
|
addField("replay", TYPEID< SFXPlayList::EReplayMode >(), Offset(mPlaylist.mSlots.mReplayMode, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
&setSoundFile, &getSoundFile, "Path to the sound file.");
|
"Behavior when an already playing sound is encountered on this slot from a previous cycle.\n"
|
||||||
|
"Each slot can have an arbitrary number of sounds playing on it from previous cycles. This field determines "
|
||||||
|
"how SFXController will handle these sources.");
|
||||||
|
addField("transitionIn", TYPEID< SFXPlayList::ETransitionMode >(), Offset(mPlaylist.mSlots.mTransitionIn, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Behavior when moving into this slot.\n"
|
||||||
|
"After the delayIn time has expired (if any), this slot determines what the controller "
|
||||||
|
"will do before actually playing the slot.");
|
||||||
|
addField("transitionOut", TYPEID< SFXPlayList::ETransitionMode >(), Offset(mPlaylist.mSlots.mTransitionOut, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Behavior when moving out of this slot.\n"
|
||||||
|
"After the #detailTimeOut has expired (if any), this slot determines what the controller "
|
||||||
|
"will do before moving on to the next slot.");
|
||||||
|
addField("delayTimeIn", TypeF32, Offset(mPlaylist.mSlots.mDelayTimeIn.mValue, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Seconds to wait after moving into slot before #transitionIn.");
|
||||||
|
addField("delayTimeInVariance", TypePoint2F, Offset(mPlaylist.mSlots.mDelayTimeIn.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Bounds on randomization of #delayTimeIn.\n\n"
|
||||||
|
"@ref SFXPlayList_randomization\n");
|
||||||
|
addField("delayTimeOut", TypeF32, Offset(mPlaylist.mSlots.mDelayTimeOut.mValue, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Seconds to wait before moving out of slot after #transitionOut.");
|
||||||
|
addField("delayTimeOutVariance", TypePoint2F, Offset(mPlaylist.mSlots.mDelayTimeOut.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Bounds on randomization of #delayTimeOut.\n\n"
|
||||||
|
"@ref SFXPlayList_randomization\n");
|
||||||
|
addField("fadeTimeIn", TypeF32, Offset(mPlaylist.mSlots.mFadeTimeIn.mValue, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Seconds to fade sound in (-1 to use the track's own fadeInTime.)\n"
|
||||||
|
"@see SFXDescription::fadeTimeIn");
|
||||||
|
addField("fadeTimeInVariance", TypePoint2F, Offset(mPlaylist.mSlots.mFadeTimeIn.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Bounds on randomization of #fadeInTime.\n\n"
|
||||||
|
"@ref SFXPlayList_randomization\n");
|
||||||
|
addField("fadeTimeOut", TypeF32, Offset(mPlaylist.mSlots.mFadeTimeOut.mValue, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Seconds to fade sound out (-1 to use the track's own fadeOutTime.)\n"
|
||||||
|
"@see SFXDescription::fadeTimeOut");
|
||||||
|
addField("fadeTimeOutVariance", TypePoint2F, Offset(mPlaylist.mSlots.mFadeTimeOut.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Bounds on randomization of #fadeOutTime\n\n"
|
||||||
|
"@ref SFXPlayList_randomization\n");
|
||||||
|
addField("referenceDistance", TypeF32, Offset(mPlaylist.mSlots.mMinDistance.mValue, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"@c referenceDistance to set for 3D sounds in this slot (<1 to use @c referenceDistance of track's own description).\n"
|
||||||
|
"@see SFXDescription::referenceDistance");
|
||||||
|
addField("referenceDistanceVariance", TypePoint2F, Offset(mPlaylist.mSlots.mMinDistance.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Bounds on randomization of #referenceDistance.\n\n"
|
||||||
|
"@ref SFXPlayList_randomization\n");
|
||||||
|
addField("maxDistance", TypeF32, Offset(mPlaylist.mSlots.mMaxDistance.mValue, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"@c maxDistance to apply to 3D sounds in this slot (<1 to use @c maxDistance of track's own description).\n"
|
||||||
|
"@see SFXDescription::maxDistance");
|
||||||
|
addField("maxDistanceVariance", TypePoint2F, Offset(mPlaylist.mSlots.mMaxDistance.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Bounds on randomization of #maxDistance.\n\n"
|
||||||
|
"@ref SFXPlayList_randomization\n");
|
||||||
|
addField("volumeScale", TypeF32, Offset(mPlaylist.mSlots.mVolumeScale.mValue, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Scale factor to apply to volume of sounds played on this list slot.\n"
|
||||||
|
"This value will scale the actual volume level set on the track assigned to the slot, i.e. a value of 0.5 will "
|
||||||
|
"cause the track to play at half-volume.");
|
||||||
|
addField("volumeScaleVariance", TypePoint2F, Offset(mPlaylist.mSlots.mVolumeScale.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Bounds on randomization of #volumeScale.\n\n"
|
||||||
|
"@ref SFXPlayList_randomization\n");
|
||||||
|
addField("pitchScale", TypeF32, Offset(mPlaylist.mSlots.mPitchScale.mValue, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Scale factor to apply to pitch of sounds played on this list slot.\n"
|
||||||
|
"This value will scale the actual pitch set on the track assigned to the slot, i.e. a value of 0.5 will "
|
||||||
|
"cause the track to play at half its assigned speed.");
|
||||||
|
addField("pitchScaleVariance", TypePoint2F, Offset(mPlaylist.mSlots.mPitchScale.mVariance, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Bounds on randomization of #pitchScale.\n\n"
|
||||||
|
"@ref SFXPlayList_randomization\n");
|
||||||
|
addField("repeatCount", TypeS32, Offset(mPlaylist.mSlots.mRepeatCount, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Number of times to loop this slot.");
|
||||||
|
addField("state", TypeSFXStateName, Offset(mPlaylist.mSlots.mState, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"State that must be active for this slot to play.\n\n"
|
||||||
|
"@ref SFXPlayList_states");
|
||||||
|
addField("stateMode", TYPEID< SFXPlayList::EStateMode >(), Offset(mPlaylist.mSlots.mStateMode, SoundAsset), SFXPlayList::SFXPlaylistSettings::NUM_SLOTS,
|
||||||
|
"Behavior when assigned state is deactivated while slot is playing.\n\n"
|
||||||
|
"@ref SFXPlayList_states");
|
||||||
|
endArray("slots");
|
||||||
|
|
||||||
addField("pitchAdjust", TypeF32, Offset(mProfileDesc.mPitch, SoundAsset), "Adjustment of the pitch value 1 is default.");
|
addField("pitchAdjust", TypeF32, Offset(mProfileDesc.mPitch, SoundAsset), "Adjustment of the pitch value 1 is default.");
|
||||||
addField("volumeAdjust", TypeF32, Offset(mProfileDesc.mVolume, SoundAsset), "Adjustment to the volume.");
|
addField("volumeAdjust", TypeF32, Offset(mProfileDesc.mVolume, SoundAsset), "Adjustment to the volume.");
|
||||||
|
|
@ -170,16 +272,33 @@ void SoundAsset::initPersistFields()
|
||||||
addField("isStreaming", TypeBool, Offset(mProfileDesc.mIsStreaming, SoundAsset), "Use streaming.");
|
addField("isStreaming", TypeBool, Offset(mProfileDesc.mIsStreaming, SoundAsset), "Use streaming.");
|
||||||
//....why?
|
//....why?
|
||||||
addField("useHardware", TypeBool, Offset(mProfileDesc.mUseHardware, SoundAsset), "Use hardware mixing for this sound.");
|
addField("useHardware", TypeBool, Offset(mProfileDesc.mUseHardware, SoundAsset), "Use hardware mixing for this sound.");
|
||||||
addField("minDistance", TypeF32, Offset(mProfileDesc.mMinDistance, SoundAsset), "Minimum distance for sound.");
|
|
||||||
// more like it.
|
|
||||||
addField("maxDistance", TypeF32, Offset(mProfileDesc.mMaxDistance, SoundAsset), "Max distance for sound.");
|
|
||||||
addField("coneInsideAngle", TypeS32, Offset(mProfileDesc.mConeInsideAngle, SoundAsset), "Cone inside angle.");
|
|
||||||
addField("coneOutsideAngle", TypeS32, Offset(mProfileDesc.mConeOutsideAngle, SoundAsset), "Cone outside angle.");
|
|
||||||
addField("coneOutsideVolume", TypeF32, Offset(mProfileDesc.mConeOutsideVolume, SoundAsset), "Cone outside volume.");
|
|
||||||
addField("rolloffFactor", TypeF32, Offset(mProfileDesc.mRolloffFactor, SoundAsset), "Rolloff factor.");
|
|
||||||
addField("scatterDistance", TypePoint3F, Offset(mProfileDesc.mScatterDistance, SoundAsset), "Randomization to the spacial position of the sound.");
|
|
||||||
addField("sourceGroup", TypeSFXSourceName, Offset(mProfileDesc.mSourceGroup, SoundAsset), "Group that sources playing with this description should be put into.");
|
addField("sourceGroup", TypeSFXSourceName, Offset(mProfileDesc.mSourceGroup, SoundAsset), "Group that sources playing with this description should be put into.");
|
||||||
|
addField("preload", TypeBool, Offset(mPreload, SoundAsset), "Whether to preload sound data when the profile is added to system.");
|
||||||
|
|
||||||
|
addGroup("Fading");
|
||||||
|
addField("fadeInTime", TypeF32, Offset(mProfileDesc.mFadeInTime, SoundAsset), "Number of seconds to gradually fade in volume from zero when playback starts.");
|
||||||
|
addField("fadeOutTime", TypeF32, Offset(mProfileDesc.mFadeOutTime, SoundAsset), "Number of seconds to gradually fade out volume down to zero when playback is stopped or paused.");
|
||||||
|
addField("fadeInEase", TypeEaseF, Offset(mProfileDesc.mFadeInEase, SoundAsset), "Easing curve for fade-in transition.");
|
||||||
|
addField("fadeOutEase", TypeEaseF, Offset(mProfileDesc.mFadeOutEase, SoundAsset), "Easing curve for fade-out transition.");
|
||||||
|
addField("fadeLoops", TypeBool, Offset(mProfileDesc.mFadeLoops, SoundAsset), "Fade each cycle of a loop in and/or out; otherwise only fade-in first cycle.");
|
||||||
|
endGroup("Fading");
|
||||||
|
|
||||||
|
addGroup("3D");
|
||||||
|
addField("minDistance", TypeF32, Offset(mProfileDesc.mMinDistance, SoundAsset), "Minimum distance for sound.");
|
||||||
|
addField("maxDistance", TypeF32, Offset(mProfileDesc.mMaxDistance, SoundAsset), "Max distance for sound.");
|
||||||
|
addField("coneInsideAngle", TypeS32, Offset(mProfileDesc.mConeInsideAngle, SoundAsset), "Cone inside angle.");
|
||||||
|
addField("coneOutsideAngle", TypeS32, Offset(mProfileDesc.mConeOutsideAngle, SoundAsset), "Cone outside angle.");
|
||||||
|
addField("coneOutsideVolume", TypeF32, Offset(mProfileDesc.mConeOutsideVolume, SoundAsset), "Cone outside volume.");
|
||||||
|
addField("rolloffFactor", TypeF32, Offset(mProfileDesc.mRolloffFactor, SoundAsset), "Rolloff factor.");
|
||||||
|
addField("scatterDistance", TypePoint3F, Offset(mProfileDesc.mScatterDistance, SoundAsset), "Randomization to the spacial position of the sound.");
|
||||||
|
endGroup("3D");
|
||||||
|
|
||||||
|
addGroup("Playlist settings");
|
||||||
|
addField("random", TYPEID< SFXPlayList::ERandomMode >(), Offset(mPlaylist.mRandomMode, SoundAsset), "Slot playback order randomization pattern.");
|
||||||
|
addField("loopMode", TYPEID< SFXPlayList::ELoopMode >(), Offset(mPlaylist.mLoopMode, SoundAsset), "Behavior when description has looping enabled.");
|
||||||
|
addField("numSlotsToPlay", TypeS32, Offset(mPlaylist.mNumSlotsToPlay, SoundAsset), "Number of slots to play.");
|
||||||
|
addField("trace", TypeBool, Offset(mPlaylist.mTrace, SoundAsset), "Enable/disable execution tracing for this playlist (local only).");
|
||||||
|
endGroup("Playlist settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
@ -193,67 +312,153 @@ void SoundAsset::copyTo(SimObject* object)
|
||||||
void SoundAsset::initializeAsset(void)
|
void SoundAsset::initializeAsset(void)
|
||||||
{
|
{
|
||||||
Parent::initializeAsset();
|
Parent::initializeAsset();
|
||||||
|
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; i++)
|
||||||
|
{
|
||||||
|
if (i == 0 && mSoundFile[i] == StringTable->EmptyString())
|
||||||
|
return;
|
||||||
|
|
||||||
if (mSoundFile == StringTable->EmptyString())
|
if (mSoundFile[i] == StringTable->EmptyString())
|
||||||
return;
|
break;
|
||||||
|
|
||||||
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
|
mSoundPath[i] = getOwned() ? expandAssetFilePath(mSoundFile[i]) : mSoundPath[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
//loadSound(slotCount);
|
||||||
|
//mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
|
||||||
//loadSound();
|
//loadSound();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundAsset::_onResourceChanged(const Torque::Path &path)
|
void SoundAsset::_onResourceChanged(const Torque::Path &path)
|
||||||
{
|
{
|
||||||
if (path != Torque::Path(mSoundPath))
|
for (U32 i = 0; i < SFXPlayList::NUM_SLOTS; i++)
|
||||||
return;
|
{
|
||||||
|
|
||||||
|
if (path != Torque::Path(mSoundPath[i]))
|
||||||
|
return;
|
||||||
|
}
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
||||||
|
//loadSound(slotCount);
|
||||||
//loadSound();
|
//loadSound();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundAsset::onAssetRefresh(void)
|
void SoundAsset::onAssetRefresh(void)
|
||||||
{
|
{
|
||||||
if (mSoundFile == StringTable->EmptyString())
|
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; i++)
|
||||||
return;
|
{
|
||||||
|
if (i == 0 && mSoundFile[i] == StringTable->EmptyString())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mSoundFile[i] == StringTable->EmptyString())
|
||||||
|
break;
|
||||||
|
|
||||||
|
mSoundPath[i] = getOwned() ? expandAssetFilePath(mSoundFile[i]) : mSoundPath[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
//loadSound(slotCount);
|
||||||
//Update
|
//Update
|
||||||
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
|
//mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
|
||||||
//loadSound();
|
//loadSound();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoundAsset::loadSound()
|
bool SoundAsset::loadSound()
|
||||||
{
|
{
|
||||||
if (mLoadedState == AssetErrCode::Ok) return true;
|
if (mLoadedState == AssetErrCode::Ok) return true;
|
||||||
if (mSoundPath)
|
|
||||||
|
// find out how many active slots we have.
|
||||||
|
U32 numSlots = 0;
|
||||||
|
for (U32 i = 0; i < SFXPlayList::SFXPlaylistSettings::NUM_SLOTS; i++)
|
||||||
{
|
{
|
||||||
if (!Torque::FS::IsFile(mSoundPath))
|
if (i == 0 && mSoundPath[i] == StringTable->EmptyString())
|
||||||
{
|
|
||||||
Con::errorf("SoundAsset::initializeAsset: Attempted to load file %s but it was not valid!", mSoundFile);
|
|
||||||
mLoadedState = BadFileReference;
|
|
||||||
mSFXProfile.setDescription(NULL);
|
|
||||||
mSFXProfile.setSoundFileName(StringTable->insert(StringTable->EmptyString()));
|
|
||||||
mSFXProfile.setPreload(false);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
else
|
|
||||||
{// = new SFXProfile(mProfileDesc, mSoundFile, mPreload);
|
|
||||||
if (mProfileDesc.mSourceGroup == NULL)
|
|
||||||
mProfileDesc.mSourceGroup = dynamic_cast<SFXSource*>(Sim::findObject("AudioChannelMaster"));
|
|
||||||
mSFXProfile.setDescription(&mProfileDesc);
|
|
||||||
mSFXProfile.setSoundFileName(mSoundPath);
|
|
||||||
mSFXProfile.setPreload(mPreload);
|
|
||||||
|
|
||||||
//give it a nudge to preload if required
|
if (mSoundPath[i] == StringTable->EmptyString())
|
||||||
mSFXProfile.getBuffer();
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
|
numSlots++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (numSlots > 1)
|
||||||
|
{
|
||||||
|
mIsPlaylist = true;
|
||||||
|
|
||||||
|
for (U32 i = 0; i < numSlots; i++)
|
||||||
|
{
|
||||||
|
if (mSoundPath[i])
|
||||||
|
{
|
||||||
|
if (!Torque::FS::IsFile(mSoundPath[i]))
|
||||||
|
{
|
||||||
|
Con::errorf("SoundAsset::initializeAsset: Attempted to load file %s but it was not valid!", mSoundFile[i]);
|
||||||
|
mLoadedState = BadFileReference;
|
||||||
|
mSFXProfile[i].setDescription(NULL);
|
||||||
|
mSFXProfile[i].setSoundFileName(StringTable->insert(StringTable->EmptyString()));
|
||||||
|
mSFXProfile[i].setPreload(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{// = new SFXProfile(mProfileDesc, mSoundFile, mPreload);
|
||||||
|
if (mProfileDesc.mSourceGroup == NULL)
|
||||||
|
mProfileDesc.mSourceGroup = dynamic_cast<SFXSource*>(Sim::findObject("AudioChannelMaster"));
|
||||||
|
SFXProfile* trackProfile = new SFXProfile();
|
||||||
|
trackProfile->setDescription(&mProfileDesc);
|
||||||
|
trackProfile->setSoundFileName(mSoundPath[i]);
|
||||||
|
trackProfile->setPreload(mPreload);
|
||||||
|
trackProfile->getBuffer();
|
||||||
|
|
||||||
|
mSFXProfile[i] = *trackProfile;
|
||||||
|
|
||||||
|
mPlaylist.mSlots.mTrack[i] = trackProfile;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mPlaylist.setDescription(&mProfileDesc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mSoundPath[0])
|
||||||
|
{
|
||||||
|
if (!Torque::FS::IsFile(mSoundPath[0]))
|
||||||
|
{
|
||||||
|
Con::errorf("SoundAsset::initializeAsset: Attempted to load file %s but it was not valid!", mSoundFile[0]);
|
||||||
|
mLoadedState = BadFileReference;
|
||||||
|
mSFXProfile[0].setDescription(NULL);
|
||||||
|
mSFXProfile[0].setSoundFileName(StringTable->insert(StringTable->EmptyString()));
|
||||||
|
mSFXProfile[0].setPreload(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{// = new SFXProfile(mProfileDesc, mSoundFile, mPreload);
|
||||||
|
if (mProfileDesc.mSourceGroup == NULL)
|
||||||
|
mProfileDesc.mSourceGroup = dynamic_cast<SFXSource*>(Sim::findObject("AudioChannelMaster"));
|
||||||
|
mSFXProfile[0].setDescription(&mProfileDesc);
|
||||||
|
mSFXProfile[0].setSoundFileName(mSoundPath[0]);
|
||||||
|
mSFXProfile[0].setPreload(mPreload);
|
||||||
|
|
||||||
|
//give it a nudge to preload if required
|
||||||
|
mSFXProfile[0].getBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mChangeSignal.trigger();
|
mChangeSignal.trigger();
|
||||||
mLoadedState = Ok;
|
mLoadedState = Ok;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundAsset::setSoundFile(const char* pSoundFile)
|
StringTableEntry SoundAsset::getSoundFile(const char* pSoundFile, const U32 slotId)
|
||||||
|
{
|
||||||
|
for (U32 i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
if(mSoundFile[i] == pSoundFile)
|
||||||
|
return mSoundFile[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundAsset::setSoundFile(const char* pSoundFile, const U32 slotId)
|
||||||
{
|
{
|
||||||
// Sanity!
|
// Sanity!
|
||||||
AssertFatal(pSoundFile != NULL, "Cannot use a NULL sound file.");
|
AssertFatal(pSoundFile != NULL, "Cannot use a NULL sound file.");
|
||||||
|
|
@ -261,12 +466,12 @@ void SoundAsset::setSoundFile(const char* pSoundFile)
|
||||||
// Fetch sound file.
|
// Fetch sound file.
|
||||||
pSoundFile = StringTable->insert(pSoundFile, true);
|
pSoundFile = StringTable->insert(pSoundFile, true);
|
||||||
|
|
||||||
// Ignore no change,
|
//Ignore no change,
|
||||||
if (pSoundFile == mSoundFile)
|
if (pSoundFile == mSoundFile[slotId])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mSoundFile = getOwned() ? expandAssetFilePath(pSoundFile) : pSoundFile;
|
mSoundFile[slotId] = getOwned() ? expandAssetFilePath(pSoundFile) : pSoundFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -353,11 +558,11 @@ DefineEngineMethod(SoundAsset, playSound, S32, (Point3F position), (Point3F::Zer
|
||||||
"Plays the sound for this asset.\n"
|
"Plays the sound for this asset.\n"
|
||||||
"@return (sound plays).\n")
|
"@return (sound plays).\n")
|
||||||
{
|
{
|
||||||
if (object->getSfxProfile())
|
if (object->getSFXTrack())
|
||||||
{
|
{
|
||||||
MatrixF transform;
|
MatrixF transform;
|
||||||
transform.setPosition(position);
|
transform.setPosition(position);
|
||||||
SFXSource* source = SFX->playOnce(object->getSfxProfile(), &transform, NULL, -1);
|
SFXSource* source = SFX->playOnce(object->getSFXTrack(), &transform, NULL, -1);
|
||||||
if(source)
|
if(source)
|
||||||
return source->getId();
|
return source->getId();
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,11 @@
|
||||||
#include "sfx/sfxDescription.h"
|
#include "sfx/sfxDescription.h"
|
||||||
#endif // !_SFXDESCRIPTION_H_
|
#endif // !_SFXDESCRIPTION_H_
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _SFXTRACK_H_
|
||||||
|
#include "sfx/sfxTrack.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _SFXPROFILE_H_
|
#ifndef _SFXPROFILE_H_
|
||||||
#include "sfx/sfxProfile.h"
|
#include "sfx/sfxProfile.h"
|
||||||
#endif // !_SFXPROFILE_H_
|
#endif // !_SFXPROFILE_H_
|
||||||
|
|
@ -63,8 +68,17 @@
|
||||||
#include "core/resourceManager.h"
|
#include "core/resourceManager.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _SFXPLAYLIST_H_
|
||||||
|
#include "sfx/sfxPlayList.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _SFXTYPES_H_
|
||||||
|
#include "sfx/sfxTypes.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "assetMacroHelpers.h"
|
#include "assetMacroHelpers.h"
|
||||||
class SFXResource;
|
class SFXResource;
|
||||||
|
class SFXPlayList;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
class SoundAsset : public AssetBase
|
class SoundAsset : public AssetBase
|
||||||
|
|
@ -73,13 +87,17 @@ class SoundAsset : public AssetBase
|
||||||
typedef AssetPtr<SoundAsset> ConcreteAssetPtr;
|
typedef AssetPtr<SoundAsset> ConcreteAssetPtr;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StringTableEntry mSoundFile;
|
StringTableEntry mSoundFile[12];
|
||||||
StringTableEntry mSoundPath;
|
StringTableEntry mSoundPath[12];
|
||||||
SFXProfile mSFXProfile;
|
SFXProfile mSFXProfile[12];
|
||||||
|
|
||||||
SFXDescription mProfileDesc;
|
SFXDescription mProfileDesc;
|
||||||
|
SFXPlayList mPlaylist;
|
||||||
// subtitles
|
// subtitles
|
||||||
StringTableEntry mSubtitleString;
|
StringTableEntry mSubtitleString;
|
||||||
bool mPreload;
|
bool mPreload;
|
||||||
|
bool mIsPlaylist;
|
||||||
|
//SFXPlayList::SlotData mSlots;
|
||||||
|
|
||||||
/*These will be needed in the refactor!
|
/*These will be needed in the refactor!
|
||||||
Resource<SFXResource> mSoundResource;
|
Resource<SFXResource> mSoundResource;
|
||||||
|
|
@ -132,17 +150,20 @@ public:
|
||||||
virtual void copyTo(SimObject* object);
|
virtual void copyTo(SimObject* object);
|
||||||
|
|
||||||
//SFXResource* getSound() { return mSoundResource; }
|
//SFXResource* getSound() { return mSoundResource; }
|
||||||
Resource<SFXResource> getSoundResource() { loadSound(); return mSFXProfile.getResource(); }
|
Resource<SFXResource> getSoundResource(const U32 slotId = 0) { loadSound(); return mSFXProfile[slotId].getResource(); }
|
||||||
|
|
||||||
/// Declare Console Object.
|
/// Declare Console Object.
|
||||||
DECLARE_CONOBJECT(SoundAsset);
|
DECLARE_CONOBJECT(SoundAsset);
|
||||||
|
|
||||||
void setSoundFile(const char* pSoundFile);
|
void setSoundFile(const char* pSoundFile, const U32 slotId = 0);
|
||||||
bool loadSound();
|
bool loadSound();
|
||||||
inline StringTableEntry getSoundFile(void) const { return mSoundFile; };
|
StringTableEntry getSoundFile(const char* pSoundFile, const U32 slotId = 0);
|
||||||
inline StringTableEntry getSoundPath(void) const { return mSoundPath; };
|
inline StringTableEntry getSoundPath(const U32 slotId = 0) const { return mSoundPath[slotId]; };
|
||||||
SFXProfile* getSfxProfile() { return &mSFXProfile; }
|
SFXProfile* getSfxProfile(const U32 slotId = 0) { return &mSFXProfile[slotId]; }
|
||||||
|
SFXPlayList* getSfxPlaylist() { return &mPlaylist; }
|
||||||
|
SFXTrack* getSFXTrack() { return mIsPlaylist ? dynamic_cast<SFXTrack*>(&mPlaylist) : dynamic_cast<SFXTrack*>(&mSFXProfile[0]); }
|
||||||
SFXDescription* getSfxDescription() { return &mProfileDesc; }
|
SFXDescription* getSfxDescription() { return &mProfileDesc; }
|
||||||
|
bool isPlaylist(){ return mIsPlaylist; }
|
||||||
|
|
||||||
bool isLoop() { return mProfileDesc.mIsLooping; }
|
bool isLoop() { return mProfileDesc.mIsLooping; }
|
||||||
bool is3D() { return mProfileDesc.mIs3D; }
|
bool is3D() { return mProfileDesc.mIs3D; }
|
||||||
|
|
@ -156,8 +177,8 @@ protected:
|
||||||
void _onResourceChanged(const Torque::Path & path);
|
void _onResourceChanged(const Torque::Path & path);
|
||||||
virtual void onAssetRefresh(void);
|
virtual void onAssetRefresh(void);
|
||||||
|
|
||||||
static bool setSoundFile(void *obj, const char *index, const char *data) { static_cast<SoundAsset*>(obj)->setSoundFile(data); return false; }
|
static bool _setSoundFile(void *obj, const char *index, const char *data) { static_cast<SoundAsset*>(obj)->setSoundFile(data, index ? dAtoi(index) : 0); return false; }
|
||||||
static const char* getSoundFile(void* obj, const char* data) { return static_cast<SoundAsset*>(obj)->getSoundFile(); }
|
static const char* _getSoundFile(void* obj, const char* data) { return static_cast<SoundAsset*>(obj)->getSoundFile(data); }
|
||||||
};
|
};
|
||||||
|
|
||||||
DefineConsoleType(TypeSoundAssetPtr, SoundAsset)
|
DefineConsoleType(TypeSoundAssetPtr, SoundAsset)
|
||||||
|
|
@ -175,7 +196,7 @@ DefineConsoleType(TypeSoundAssetId, String)
|
||||||
StringTableEntry m##name##Name; \
|
StringTableEntry m##name##Name; \
|
||||||
StringTableEntry m##name##AssetId;\
|
StringTableEntry m##name##AssetId;\
|
||||||
AssetPtr<SoundAsset> m##name##Asset = NULL;\
|
AssetPtr<SoundAsset> m##name##Asset = NULL;\
|
||||||
SFXProfile* m##name##Profile = NULL;\
|
SFXTrack* m##name##Profile = NULL;\
|
||||||
SFXDescription* m##name##Desc = NULL;\
|
SFXDescription* m##name##Desc = NULL;\
|
||||||
SimObjectId m##name##SFXId = 0;\
|
SimObjectId m##name##SFXId = 0;\
|
||||||
public: \
|
public: \
|
||||||
|
|
@ -268,11 +289,12 @@ public: \
|
||||||
{\
|
{\
|
||||||
return m##name;\
|
return m##name;\
|
||||||
}\
|
}\
|
||||||
SFXProfile* get##name##Profile()\
|
SFXTrack* get##name##Profile()\
|
||||||
{\
|
{\
|
||||||
if (get##name() != StringTable->EmptyString() && m##name##Asset.notNull()){\
|
if (get##name() != StringTable->EmptyString() && m##name##Asset.notNull()){\
|
||||||
m##name##Profile = m##name##Asset->getSfxProfile();\
|
m##name##Profile = m##name##Asset->getSFXTrack(); \
|
||||||
return m##name##Profile;}\
|
return m##name##Profile;\
|
||||||
|
}\
|
||||||
return NULL;\
|
return NULL;\
|
||||||
}\
|
}\
|
||||||
SFXDescription* get##name##Description()\
|
SFXDescription* get##name##Description()\
|
||||||
|
|
@ -308,9 +330,9 @@ public: \
|
||||||
{\
|
{\
|
||||||
if(stream->writeFlag(Sim::findObject(m##name##Name)))\
|
if(stream->writeFlag(Sim::findObject(m##name##Name)))\
|
||||||
{\
|
{\
|
||||||
SFXTrack* sndTrack;\
|
SFXTrack* sndTrack = get##name##Profile();\
|
||||||
Sim::findObject(m##name##Name, sndTrack);\
|
|
||||||
stream->writeRangedU32(SimObjectId(sndTrack->getId()), DataBlockObjectIdFirst, DataBlockObjectIdLast);\
|
stream->writeRangedU32(SimObjectId(sndTrack->getId()), DataBlockObjectIdFirst, DataBlockObjectIdLast);\
|
||||||
|
sfxWrite(stream, sndTrack);\
|
||||||
}\
|
}\
|
||||||
else\
|
else\
|
||||||
{\
|
{\
|
||||||
|
|
@ -330,7 +352,10 @@ public: \
|
||||||
{\
|
{\
|
||||||
if(stream->readFlag())\
|
if(stream->readFlag())\
|
||||||
{\
|
{\
|
||||||
|
String errorStr;\
|
||||||
m##name##SFXId = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );\
|
m##name##SFXId = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );\
|
||||||
|
sfxReadAndResolve(stream, &m##name##Profile, errorStr);\
|
||||||
|
Con::errorf("%s", errorStr.c_str());\
|
||||||
}\
|
}\
|
||||||
else\
|
else\
|
||||||
{\
|
{\
|
||||||
|
|
@ -359,7 +384,7 @@ public: \
|
||||||
StringTableEntry m##name##Name[max]; \
|
StringTableEntry m##name##Name[max]; \
|
||||||
StringTableEntry m##name##AssetId[max];\
|
StringTableEntry m##name##AssetId[max];\
|
||||||
AssetPtr<SoundAsset> m##name##Asset[max];\
|
AssetPtr<SoundAsset> m##name##Asset[max];\
|
||||||
SFXProfile* m##name##Profile[max];\
|
SFXTrack* m##name##Profile[max];\
|
||||||
SimObjectId m##name##SFXId[max];\
|
SimObjectId m##name##SFXId[max];\
|
||||||
public: \
|
public: \
|
||||||
const StringTableEntry get##name##File(const U32& index) const { return m##name##Name[index]; }\
|
const StringTableEntry get##name##File(const U32& index) const { return m##name##Name[index]; }\
|
||||||
|
|
@ -461,10 +486,10 @@ public: \
|
||||||
return ResourceManager::get().load( "" );\
|
return ResourceManager::get().load( "" );\
|
||||||
return m##name[id];\
|
return m##name[id];\
|
||||||
}\
|
}\
|
||||||
SFXProfile* get##name##Profile(const U32& id)\
|
SFXTrack* get##name##Profile(const U32& id)\
|
||||||
{\
|
{\
|
||||||
if (get##name(id) != StringTable->EmptyString() && m##name##Asset[id].notNull())\
|
if (m##name##Asset[id].notNull())\
|
||||||
return m##name##Asset[id]->getSfxProfile();\
|
return m##name##Asset[id]->getSFXTrack(); \
|
||||||
return NULL;\
|
return NULL;\
|
||||||
}\
|
}\
|
||||||
bool is##name##Valid(const U32& id) {return (get##name(id) != StringTable->EmptyString() && m##name##Asset[id] && m##name##Asset[id]->getStatus() == AssetBase::Ok); }
|
bool is##name##Valid(const U32& id) {return (get##name(id) != StringTable->EmptyString() && m##name##Asset[id] && m##name##Asset[id]->getStatus() == AssetBase::Ok); }
|
||||||
|
|
@ -518,9 +543,12 @@ if (m##name##AssetId[index] != StringTable->EmptyString())\
|
||||||
{\
|
{\
|
||||||
if(stream->writeFlag(Sim::findObject(m##name##Name[index])))\
|
if(stream->writeFlag(Sim::findObject(m##name##Name[index])))\
|
||||||
{\
|
{\
|
||||||
SFXTrack* sndTrack;\
|
SFXTrack* sndTrack = get##name##Profile(index);\
|
||||||
Sim::findObject(m##name##Name[index], sndTrack);\
|
if(stream->writeFlag(sndTrack != nullptr))\
|
||||||
stream->writeRangedU32(SimObjectId(sndTrack->getId()), DataBlockObjectIdFirst, DataBlockObjectIdLast);\
|
{\
|
||||||
|
stream->writeRangedU32(SimObjectId(sndTrack->getId()), DataBlockObjectIdFirst, DataBlockObjectIdLast);\
|
||||||
|
sfxWrite(stream, sndTrack);\
|
||||||
|
}\
|
||||||
}\
|
}\
|
||||||
else\
|
else\
|
||||||
{\
|
{\
|
||||||
|
|
@ -540,7 +568,12 @@ if (m##name##AssetId[index] != StringTable->EmptyString())\
|
||||||
{\
|
{\
|
||||||
if(stream->readFlag())\
|
if(stream->readFlag())\
|
||||||
{\
|
{\
|
||||||
m##name##SFXId[index] = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );\
|
String errorStr;\
|
||||||
|
if(stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##SFXId[index] = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );\
|
||||||
|
sfxReadAndResolve(stream, &m##name##Profile[index], errorStr);\
|
||||||
|
}\
|
||||||
}\
|
}\
|
||||||
else\
|
else\
|
||||||
{\
|
{\
|
||||||
|
|
|
||||||
|
|
@ -1403,7 +1403,7 @@ bool Explosion::explode()
|
||||||
resetWorldBox();
|
resetWorldBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
SFXProfile* sound_prof = mDataBlock->getSoundProfile();
|
SFXProfile* sound_prof = static_cast<SFXProfile*>(mDataBlock->getSoundProfile());
|
||||||
if (sound_prof)
|
if (sound_prof)
|
||||||
{
|
{
|
||||||
soundProfile_clone = sound_prof->cloneAndPerformSubstitutions(ss_object, ss_index);
|
soundProfile_clone = sound_prof->cloneAndPerformSubstitutions(ss_object, ss_index);
|
||||||
|
|
|
||||||
|
|
@ -686,7 +686,7 @@ void Splash::spawnExplosion()
|
||||||
|
|
||||||
/// could just play the explosion one, but explosion could be weapon specific,
|
/// could just play the explosion one, but explosion could be weapon specific,
|
||||||
/// splash sound could be liquid specific. food for thought.
|
/// splash sound could be liquid specific. food for thought.
|
||||||
SFXProfile* sound_prof = mDataBlock->getSoundProfile();
|
SFXTrack* sound_prof = mDataBlock->getSoundProfile();
|
||||||
if (sound_prof)
|
if (sound_prof)
|
||||||
{
|
{
|
||||||
SFX->playOnce(sound_prof, &getTransform());
|
SFX->playOnce(sound_prof, &getTransform());
|
||||||
|
|
|
||||||
|
|
@ -387,9 +387,9 @@ void SimSoundAssetEvent::process(NetConnection* con)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (mAsset->is3D())
|
if (mAsset->is3D())
|
||||||
SFX->playOnce(mAsset->getSfxProfile(), &mTransform);
|
SFX->playOnce(mAsset->getSFXTrack(), &mTransform);
|
||||||
else
|
else
|
||||||
SFX->playOnce(mAsset->getSfxProfile());
|
SFX->playOnce(mAsset->getSFXTrack());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,120 @@ ColorI SFXEmitter::smRenderColorOutsideVolume( 255, 0, 0, 255 );
|
||||||
ColorI SFXEmitter::smRenderColorRangeSphere( 200, 0, 0, 90 );
|
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()
|
SFXEmitter::SFXEmitter()
|
||||||
|
|
@ -106,8 +220,7 @@ SFXEmitter::SFXEmitter()
|
||||||
mDescription.mFadeInTime = -1.f;
|
mDescription.mFadeInTime = -1.f;
|
||||||
mDescription.mFadeOutTime = -1.f;
|
mDescription.mFadeOutTime = -1.f;
|
||||||
mInstanceDescription = &mDescription;
|
mInstanceDescription = &mDescription;
|
||||||
mLocalProfile.mFilename = StringTable->EmptyString();
|
mLocalProfile = NULL;
|
||||||
mLocalProfile._registerSignals();
|
|
||||||
|
|
||||||
INIT_ASSET(Sound);
|
INIT_ASSET(Sound);
|
||||||
|
|
||||||
|
|
@ -119,7 +232,9 @@ SFXEmitter::SFXEmitter()
|
||||||
|
|
||||||
SFXEmitter::~SFXEmitter()
|
SFXEmitter::~SFXEmitter()
|
||||||
{
|
{
|
||||||
mLocalProfile.onRemove();
|
if(mLocalProfile != NULL)
|
||||||
|
mLocalProfile->onRemove();
|
||||||
|
|
||||||
SFX_DELETE( mSource );
|
SFX_DELETE( mSource );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,6 +306,8 @@ void SFXEmitter::initPersistFields()
|
||||||
|
|
||||||
addGroup( "Sound" );
|
addGroup( "Sound" );
|
||||||
|
|
||||||
|
addField("Controls", TypeSoundControls, 0, "");
|
||||||
|
|
||||||
addField( "playOnAdd", TypeBool, Offset( mPlayOnAdd, SFXEmitter ),
|
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"
|
"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." );
|
"If this is true, the emitter will immediately start to play when the level is loaded." );
|
||||||
|
|
@ -365,6 +482,7 @@ U32 SFXEmitter::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
|
||||||
|
|
||||||
// Write the source playback state.
|
// Write the source playback state.
|
||||||
stream->writeFlag( mask & SourcePlayMask );
|
stream->writeFlag( mask & SourcePlayMask );
|
||||||
|
stream->writeFlag( mask & SourcePauseMask );
|
||||||
stream->writeFlag( mask & SourceStopMask );
|
stream->writeFlag( mask & SourceStopMask );
|
||||||
|
|
||||||
return retMask;
|
return retMask;
|
||||||
|
|
@ -490,6 +608,8 @@ void SFXEmitter::unpackUpdate( NetConnection *conn, BitStream *stream )
|
||||||
// Check the source playback masks.
|
// Check the source playback masks.
|
||||||
if ( stream->readFlag() ) // SourcePlayMask
|
if ( stream->readFlag() ) // SourcePlayMask
|
||||||
play();
|
play();
|
||||||
|
if (stream->readFlag()) //SourcePauseMask
|
||||||
|
pause();
|
||||||
if ( stream->readFlag() ) // SourceStopMask
|
if ( stream->readFlag() ) // SourceStopMask
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
@ -653,7 +773,7 @@ void SFXEmitter::_update()
|
||||||
SFXStatus prevState = mSource ? mSource->getStatus() : SFXStatusNull;
|
SFXStatus prevState = mSource ? mSource->getStatus() : SFXStatusNull;
|
||||||
|
|
||||||
// are we overriding the asset properties?
|
// are we overriding the asset properties?
|
||||||
bool useTrackDescriptionOnly = (mUseTrackDescriptionOnly && mSoundAsset.notNull() && mSoundAsset->getSfxProfile());
|
bool useTrackDescriptionOnly = (mUseTrackDescriptionOnly && mSoundAsset.notNull() && getSoundProfile());
|
||||||
|
|
||||||
if (mSoundAsset.notNull())
|
if (mSoundAsset.notNull())
|
||||||
{
|
{
|
||||||
|
|
@ -662,12 +782,12 @@ void SFXEmitter::_update()
|
||||||
else
|
else
|
||||||
mInstanceDescription = &mDescription;
|
mInstanceDescription = &mDescription;
|
||||||
|
|
||||||
mLocalProfile = *mSoundAsset->getSfxProfile();
|
mLocalProfile = getSoundProfile();
|
||||||
}
|
|
||||||
// Make sure all the settings are valid.
|
|
||||||
mInstanceDescription->validate();
|
|
||||||
mLocalProfile.setDescription(mInstanceDescription);
|
|
||||||
|
|
||||||
|
// Make sure all the settings are valid.
|
||||||
|
mInstanceDescription->validate();
|
||||||
|
mLocalProfile->setDescription(mInstanceDescription);
|
||||||
|
}
|
||||||
|
|
||||||
const MatrixF& transform = getTransform();
|
const MatrixF& transform = getTransform();
|
||||||
const VectorF& velocity = getVelocity();
|
const VectorF& velocity = getVelocity();
|
||||||
|
|
@ -676,12 +796,12 @@ void SFXEmitter::_update()
|
||||||
if( mDirty.test( Track | Is3D | IsLooping | IsStreaming | TrackOnly ) )
|
if( mDirty.test( Track | Is3D | IsLooping | IsStreaming | TrackOnly ) )
|
||||||
{
|
{
|
||||||
SFX_DELETE( mSource );
|
SFX_DELETE( mSource );
|
||||||
if (mLocalProfile.getSoundFileName().isNotEmpty())
|
if (getSoundProfile())
|
||||||
{
|
{
|
||||||
mSource = SFX->createSource(&mLocalProfile, &transform, &velocity);
|
mSource = SFX->createSource(mLocalProfile, &transform, &velocity);
|
||||||
if (!mSource)
|
if (!mSource)
|
||||||
Con::errorf("SFXEmitter::_update() - failed to create sound for track %i (%s)",
|
Con::errorf("SFXEmitter::_update() - failed to create sound for track %i (%s)",
|
||||||
mSoundAsset->getSfxProfile()->getId(), mSoundAsset->getSfxProfile()->getName());
|
getSoundProfile()->getId(), getSoundProfile()->getName());
|
||||||
|
|
||||||
// If we're supposed to play when the emitter is
|
// If we're supposed to play when the emitter is
|
||||||
// added to the scene then also restart playback
|
// added to the scene then also restart playback
|
||||||
|
|
@ -999,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()
|
void SFXEmitter::stop()
|
||||||
{
|
{
|
||||||
if ( mSource )
|
if ( mSource )
|
||||||
|
|
@ -1043,8 +1180,8 @@ SFXStatus SFXEmitter::_getPlaybackStatus() const
|
||||||
|
|
||||||
bool SFXEmitter::is3D() const
|
bool SFXEmitter::is3D() const
|
||||||
{
|
{
|
||||||
if( mSoundAsset.notNull() && mSoundAsset->getSfxProfile() != NULL )
|
if( mSoundAsset.notNull() )
|
||||||
return mSoundAsset->getSfxProfile()->getDescription()->mIs3D;
|
return mSoundAsset->getSfxDescription()->mIs3D;
|
||||||
else
|
else
|
||||||
return mInstanceDescription->mIs3D;
|
return mInstanceDescription->mIs3D;
|
||||||
}
|
}
|
||||||
|
|
@ -1080,8 +1217,8 @@ void SFXEmitter::setScale( const VectorF &scale )
|
||||||
{
|
{
|
||||||
F32 maxDistance;
|
F32 maxDistance;
|
||||||
|
|
||||||
if( mUseTrackDescriptionOnly && mSoundAsset.notNull() && mSoundAsset->getSfxProfile())
|
if( mUseTrackDescriptionOnly && mSoundAsset.notNull() && getSoundProfile())
|
||||||
maxDistance = mSoundAsset->getSfxProfile()->getDescription()->mMaxDistance;
|
maxDistance = mSoundAsset->getSfxDescription()->mMaxDistance;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Use the average of the three coords.
|
// Use the average of the three coords.
|
||||||
|
|
@ -1113,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, (),,
|
DefineEngineMethod( SFXEmitter, stop, void, (),,
|
||||||
"Manually stop playback of the emitter's sound.\n"
|
"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" )
|
"If this is called on the server-side object, the stop command will be related to all client-side ghosts.\n" )
|
||||||
|
|
@ -1130,3 +1276,4 @@ DefineEngineMethod( SFXEmitter, getSource, SFXSource*, (),,
|
||||||
{
|
{
|
||||||
return object->getSource();
|
return object->getSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,21 @@
|
||||||
class SFXSource;
|
class SFXSource;
|
||||||
class SFXTrack;
|
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
|
//RDTODO: make 3D sound emitters yield their source when being culled
|
||||||
|
|
||||||
/// The SFXEmitter is used to place 2D or 3D sounds into a
|
/// The SFXEmitter is used to place 2D or 3D sounds into a
|
||||||
|
|
@ -69,7 +84,8 @@ class SFXEmitter : public SceneObject
|
||||||
DirtyUpdateMask = BIT(2),
|
DirtyUpdateMask = BIT(2),
|
||||||
|
|
||||||
SourcePlayMask = BIT(3),
|
SourcePlayMask = BIT(3),
|
||||||
SourceStopMask = BIT(4),
|
SourcePauseMask = BIT(4),
|
||||||
|
SourceStopMask = BIT(5),
|
||||||
|
|
||||||
AllSourceMasks = SourcePlayMask | SourceStopMask,
|
AllSourceMasks = SourcePlayMask | SourceStopMask,
|
||||||
};
|
};
|
||||||
|
|
@ -116,7 +132,7 @@ class SFXEmitter : public SceneObject
|
||||||
|
|
||||||
/// A local profile object used to coax the
|
/// A local profile object used to coax the
|
||||||
/// sound system to play a custom sound.
|
/// sound system to play a custom sound.
|
||||||
SFXProfile mLocalProfile;
|
SFXTrack* mLocalProfile;
|
||||||
|
|
||||||
/// The description used by the local profile.
|
/// The description used by the local profile.
|
||||||
SFXDescription mDescription;
|
SFXDescription mDescription;
|
||||||
|
|
@ -219,6 +235,10 @@ class SFXEmitter : public SceneObject
|
||||||
/// the emitter source is not already playing.
|
/// the emitter source is not already playing.
|
||||||
void play();
|
void play();
|
||||||
|
|
||||||
|
/// Sends network event to pause playback if
|
||||||
|
/// the emitter source is already playing.
|
||||||
|
void pause();
|
||||||
|
|
||||||
/// Sends network event to stop emitter
|
/// Sends network event to stop emitter
|
||||||
/// playback on all ghosted clients.
|
/// playback on all ghosted clients.
|
||||||
void stop();
|
void stop();
|
||||||
|
|
|
||||||
|
|
@ -2303,7 +2303,7 @@ void ShapeBase::updateAudioState(SoundThread& st)
|
||||||
// if asset is valid, play
|
// if asset is valid, play
|
||||||
if (st.asset->isAssetValid() )
|
if (st.asset->isAssetValid() )
|
||||||
{
|
{
|
||||||
st.sound = SFX->createSource( st.asset->getSfxProfile() , &getTransform() );
|
st.sound = SFX->createSource( st.asset->getSFXTrack() , &getTransform() );
|
||||||
if ( st.sound )
|
if ( st.sound )
|
||||||
st.sound->play();
|
st.sound->play();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2785,7 +2785,7 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState, bool force)
|
||||||
// Delete any loooping sounds that were in the previous state.
|
// Delete any loooping sounds that were in the previous state.
|
||||||
// this is the crazy bit =/ needs to know prev state in order to stop sounds.
|
// this is the crazy bit =/ needs to know prev state in order to stop sounds.
|
||||||
// lastState does not return an id for the prev state so we keep track of it.
|
// lastState does not return an id for the prev state so we keep track of it.
|
||||||
if (lastState->sound && lastState->sound->getSfxProfile()->getDescription()->mIsLooping)
|
if (lastState->sound && lastState->sound->getSFXTrack()->getDescription()->mIsLooping)
|
||||||
{
|
{
|
||||||
for (Vector<SFXSource*>::iterator i = image.mSoundSources.begin(); i != image.mSoundSources.end(); i++)
|
for (Vector<SFXSource*>::iterator i = image.mSoundSources.begin(); i != image.mSoundSources.end(); i++)
|
||||||
SFX_DELETE((*i));
|
SFX_DELETE((*i));
|
||||||
|
|
@ -2799,7 +2799,7 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState, bool force)
|
||||||
if (stateData.sound)
|
if (stateData.sound)
|
||||||
{
|
{
|
||||||
const Point3F& velocity = getVelocity();
|
const Point3F& velocity = getVelocity();
|
||||||
image.addSoundSource(SFX->createSource(stateData.sound->getSfxProfile(), &getRenderTransform(), &velocity));
|
image.addSoundSource(SFX->createSource(stateData.sound->getSFXTrack(), &getRenderTransform(), &velocity));
|
||||||
}
|
}
|
||||||
if (stateData.soundTrack)
|
if (stateData.soundTrack)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ void SFXController::_compileList( SFXPlayList* playList )
|
||||||
|
|
||||||
// If there's no track in this slot, ignore it.
|
// If there's no track in this slot, ignore it.
|
||||||
|
|
||||||
if( !playList->getTrackProfile(slotIndex))
|
if( !playList->getSlots().mTrack[slotIndex])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If this is a looped slot and the list is not set to loop
|
// If this is a looped slot and the list is not set to loop
|
||||||
|
|
@ -394,7 +394,13 @@ bool SFXController::_execInsn()
|
||||||
case OP_Play:
|
case OP_Play:
|
||||||
{
|
{
|
||||||
SFXPlayList* playList = getPlayList();
|
SFXPlayList* playList = getPlayList();
|
||||||
SFXTrack* track = playList->getTrackProfile(insn.mSlotIndex);
|
if (playList == NULL)
|
||||||
|
{
|
||||||
|
endUpdate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SFXTrack* track = playList->getSlots().mTrack[insn.mSlotIndex];
|
||||||
|
|
||||||
// Handle existing sources playing on this slot and find
|
// Handle existing sources playing on this slot and find
|
||||||
// whether we need to start a new source.
|
// whether we need to start a new source.
|
||||||
|
|
@ -817,6 +823,9 @@ void SFXController::_update()
|
||||||
|
|
||||||
SFXPlayList* playList = getPlayList();
|
SFXPlayList* playList = getPlayList();
|
||||||
|
|
||||||
|
if (!playList)
|
||||||
|
Parent::stop();
|
||||||
|
|
||||||
// Check all sources against the current state setup and
|
// Check all sources against the current state setup and
|
||||||
// take appropriate actions.
|
// take appropriate actions.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include "sfx/sfxPlayList.h"
|
#include "sfx/sfxPlayList.h"
|
||||||
#include "sfx/sfxState.h"
|
#include "sfx/sfxState.h"
|
||||||
#include "sfx/sfxTypes.h"
|
#include "sfx/sfxTypes.h"
|
||||||
|
#include "sfx/sfxDescription.h"
|
||||||
#include "core/stream/bitStream.h"
|
#include "core/stream/bitStream.h"
|
||||||
#include "math/mRandom.h"
|
#include "math/mRandom.h"
|
||||||
#include "math/mathTypes.h"
|
#include "math/mathTypes.h"
|
||||||
|
|
@ -218,10 +219,23 @@ SFXPlayList::SFXPlayList()
|
||||||
: mRandomMode( RANDOM_NotRandom ),
|
: mRandomMode( RANDOM_NotRandom ),
|
||||||
mLoopMode( LOOP_All ),
|
mLoopMode( LOOP_All ),
|
||||||
mTrace( false ),
|
mTrace( false ),
|
||||||
mNumSlotsToPlay( NUM_SLOTS )
|
mNumSlotsToPlay( NUM_SLOTS ),
|
||||||
|
mActiveSlots(12)
|
||||||
{
|
{
|
||||||
for (U32 i=0;i<NUM_SLOTS;i++)
|
}
|
||||||
INIT_SOUNDASSET_ARRAY(Track, i);
|
|
||||||
|
SFXPlayList::~SFXPlayList()
|
||||||
|
{
|
||||||
|
if (!isTempClone())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// cleanup after a temp-clone
|
||||||
|
|
||||||
|
if (mDescription && mDescription->isTempClone())
|
||||||
|
{
|
||||||
|
delete mDescription;
|
||||||
|
mDescription = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -250,10 +264,10 @@ void SFXPlayList::initPersistFields()
|
||||||
|
|
||||||
addArray( "slots", NUM_SLOTS );
|
addArray( "slots", NUM_SLOTS );
|
||||||
|
|
||||||
INITPERSISTFIELD_SOUNDASSET_ARRAY( Track, NUM_SLOTS, SFXPlayList,
|
addField("track", TypeSFXTrackName, Offset(mSlots.mTrack, SFXPlayList), NUM_SLOTS,
|
||||||
"Track to play in this slot.\n"
|
"Track to play in this slot.\n"
|
||||||
"This must be set for the slot to be considered for playback. Other settings for a slot "
|
"This must be set for the slot to be considered for playback. Other settings for a slot "
|
||||||
"will not take effect except this field is set." );
|
"will not take effect except this field is set.");
|
||||||
addField( "replay", TYPEID< EReplayMode >(), Offset( mSlots.mReplayMode, SFXPlayList ), NUM_SLOTS,
|
addField( "replay", TYPEID< EReplayMode >(), Offset( mSlots.mReplayMode, SFXPlayList ), NUM_SLOTS,
|
||||||
"Behavior when an already playing sound is encountered on this slot from a previous cycle.\n"
|
"Behavior when an already playing sound is encountered on this slot from a previous cycle.\n"
|
||||||
"Each slot can have an arbitrary number of sounds playing on it from previous cycles. This field determines "
|
"Each slot can have an arbitrary number of sounds playing on it from previous cycles. This field determines "
|
||||||
|
|
@ -340,32 +354,64 @@ void SFXPlayList::initPersistFields()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
U32 SFXPlayList::getNumSlots()
|
||||||
|
{
|
||||||
|
U32 trackCount = 0;
|
||||||
|
for (U32 i = 0; i < NUM_SLOTS; i++)
|
||||||
|
{
|
||||||
|
if (mSlots.mTrack[i] == NULL)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
trackCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return trackCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SFXPlayList::isLooping() const
|
||||||
|
{
|
||||||
|
// pretty useless in playlist, looping handled differently.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SFXPlayList::onAdd()
|
||||||
|
{
|
||||||
|
if (!Parent::onAdd())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mActiveSlots = getNumSlots();
|
||||||
|
|
||||||
|
validate();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SFXPlayList::onRemove()
|
||||||
|
{
|
||||||
|
Parent::onRemove();
|
||||||
|
}
|
||||||
|
|
||||||
bool SFXPlayList::preload( bool server, String& errorStr )
|
bool SFXPlayList::preload( bool server, String& errorStr )
|
||||||
{
|
{
|
||||||
if( !Parent::preload( server, errorStr ) )
|
if( !Parent::preload( server, errorStr ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
mActiveSlots = getNumSlots();
|
||||||
|
|
||||||
validate();
|
validate();
|
||||||
|
|
||||||
// Resolve SFXTracks and SFXStates on client.
|
// Resolve SFXTracks and SFXStates on client.
|
||||||
|
|
||||||
if( !server )
|
if( !server )
|
||||||
{
|
{
|
||||||
for( U32 i = 0; i < NUM_SLOTS; ++ i )
|
for( U32 i = 0; i < mActiveSlots; ++ i )
|
||||||
{
|
{
|
||||||
StringTableEntry track = getTrack(i);
|
if (!sfxResolve(&mSlots.mTrack[i], errorStr))
|
||||||
if (track != StringTable->EmptyString())
|
|
||||||
{
|
|
||||||
_setTrack(getTrack(i), i);
|
|
||||||
if (!getTrackProfile(i))
|
|
||||||
{
|
|
||||||
Con::errorf("SFXPlayList::Preload() - unable to find sfxProfile for asset %s", mTrackAssetId[i]);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!sfxResolve(&mSlots.mState[i], errorStr))
|
if (!sfxResolve(&mSlots.mState[i], errorStr))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -382,55 +428,57 @@ void SFXPlayList::packData( BitStream* stream )
|
||||||
stream->writeInt( mLoopMode, NUM_LOOP_MODE_BITS );
|
stream->writeInt( mLoopMode, NUM_LOOP_MODE_BITS );
|
||||||
stream->writeInt( mNumSlotsToPlay, NUM_SLOTS_TO_PLAY_BITS );
|
stream->writeInt( mNumSlotsToPlay, NUM_SLOTS_TO_PLAY_BITS );
|
||||||
|
|
||||||
#define FOR_EACH_SLOT \
|
stream->writeInt(mActiveSlots, 8);
|
||||||
for( U32 i = 0; i < NUM_SLOTS; ++ i )
|
|
||||||
|
for (U32 i = 0; i < mActiveSlots; ++i)
|
||||||
FOR_EACH_SLOT stream->writeInt( mSlots.mReplayMode[ i ], NUM_REPLAY_MODE_BITS );
|
{
|
||||||
FOR_EACH_SLOT stream->writeInt( mSlots.mTransitionIn[ i ], NUM_TRANSITION_MODE_BITS );
|
stream->writeInt(mSlots.mReplayMode[i], NUM_REPLAY_MODE_BITS);
|
||||||
FOR_EACH_SLOT stream->writeInt( mSlots.mTransitionOut[ i ], NUM_TRANSITION_MODE_BITS );
|
stream->writeInt(mSlots.mTransitionIn[i], NUM_TRANSITION_MODE_BITS);
|
||||||
FOR_EACH_SLOT stream->writeInt( mSlots.mStateMode[ i ], NUM_STATE_MODE_BITS );
|
stream->writeInt(mSlots.mTransitionOut[i], NUM_TRANSITION_MODE_BITS);
|
||||||
|
stream->writeInt(mSlots.mStateMode[i], NUM_STATE_MODE_BITS);
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mFadeTimeIn.mValue[ i ] != -1 ))
|
|
||||||
stream->write( mSlots.mFadeTimeIn.mValue[ i ] );
|
if (stream->writeFlag(mSlots.mFadeTimeIn.mValue[i] != -1))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag( mSlots.mFadeTimeIn.mVariance[ i ][ 0 ] > 0))
|
stream->write(mSlots.mFadeTimeIn.mValue[i]);
|
||||||
stream->write(mSlots.mFadeTimeIn.mVariance[ i ][ 0 ] );
|
if (stream->writeFlag(mSlots.mFadeTimeIn.mVariance[i][0] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag( mSlots.mFadeTimeIn.mVariance[ i ][ 1 ] > 0))
|
stream->write(mSlots.mFadeTimeIn.mVariance[i][0]);
|
||||||
stream->write(mSlots.mFadeTimeIn.mVariance[ i ][ 1 ] );
|
if (stream->writeFlag(mSlots.mFadeTimeIn.mVariance[i][1] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mFadeTimeOut.mValue[ i ] != -1 ))
|
stream->write(mSlots.mFadeTimeIn.mVariance[i][1]);
|
||||||
stream->write( mSlots.mFadeTimeOut.mValue[ i ] );
|
if (stream->writeFlag(mSlots.mFadeTimeOut.mValue[i] != -1))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mFadeTimeOut.mVariance[i][0] > 0))
|
stream->write(mSlots.mFadeTimeOut.mValue[i]);
|
||||||
stream->write(mSlots.mFadeTimeOut.mVariance[i][0]);
|
if (stream->writeFlag(mSlots.mFadeTimeOut.mVariance[i][0] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mFadeTimeOut.mVariance[i][1] > 0))
|
stream->write(mSlots.mFadeTimeOut.mVariance[i][0]);
|
||||||
stream->write(mSlots.mFadeTimeOut.mVariance[i][1]);
|
if (stream->writeFlag(mSlots.mFadeTimeOut.mVariance[i][1] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeIn.mValue[ i ] > 0))
|
stream->write(mSlots.mFadeTimeOut.mVariance[i][1]);
|
||||||
stream->write(mSlots.mDelayTimeIn.mValue[ i ] );
|
if (stream->writeFlag(mSlots.mDelayTimeIn.mValue[i] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeIn.mVariance[ i ][ 0 ] > 0))
|
stream->write(mSlots.mDelayTimeIn.mValue[i]);
|
||||||
stream->write(mSlots.mDelayTimeIn.mVariance[ i ][ 0 ] );
|
if (stream->writeFlag(mSlots.mDelayTimeIn.mVariance[i][0] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeIn.mVariance[ i ][ 1 ] > 0))
|
stream->write(mSlots.mDelayTimeIn.mVariance[i][0]);
|
||||||
stream->write(mSlots.mDelayTimeIn.mVariance[ i ][ 1 ] );
|
if (stream->writeFlag(mSlots.mDelayTimeIn.mVariance[i][1] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeOut.mValue[ i ] > 0))
|
stream->write(mSlots.mDelayTimeIn.mVariance[i][1]);
|
||||||
stream->write(mSlots.mDelayTimeOut.mValue[ i ] );
|
if (stream->writeFlag(mSlots.mDelayTimeOut.mValue[i] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeOut.mVariance[ i ][ 0 ] > 0))
|
stream->write(mSlots.mDelayTimeOut.mValue[i]);
|
||||||
stream->write(mSlots.mDelayTimeOut.mVariance[ i ][ 0 ] );
|
if (stream->writeFlag(mSlots.mDelayTimeOut.mVariance[i][0] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeOut.mVariance[ i ][ 1 ] > 0))
|
stream->write(mSlots.mDelayTimeOut.mVariance[i][0]);
|
||||||
stream->write(mSlots.mDelayTimeOut.mVariance[ i ][ 1 ] );
|
if (stream->writeFlag(mSlots.mDelayTimeOut.mVariance[i][1] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mVolumeScale.mValue[ i ] != 1))
|
stream->write(mSlots.mDelayTimeOut.mVariance[i][1]);
|
||||||
stream->write(mSlots.mVolumeScale.mValue[ i ] );
|
if (stream->writeFlag(mSlots.mVolumeScale.mValue[i] != 1))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mVolumeScale.mVariance[ i ][ 0 ] > 0))
|
stream->write(mSlots.mVolumeScale.mValue[i]);
|
||||||
stream->write(mSlots.mVolumeScale.mVariance[ i ][ 0 ] );
|
if (stream->writeFlag(mSlots.mVolumeScale.mVariance[i][0] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mVolumeScale.mVariance[ i ][ 1 ] > 0))
|
stream->write(mSlots.mVolumeScale.mVariance[i][0]);
|
||||||
stream->write(mSlots.mVolumeScale.mVariance[ i ][ 1 ] );
|
if (stream->writeFlag(mSlots.mVolumeScale.mVariance[i][1] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mPitchScale.mValue[ i ] != 1))
|
stream->write(mSlots.mVolumeScale.mVariance[i][1]);
|
||||||
stream->write(mSlots.mPitchScale.mValue[ i ] );
|
if (stream->writeFlag(mSlots.mPitchScale.mValue[i] != 1))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mPitchScale.mVariance[ i ][ 0 ] > 0))
|
stream->write(mSlots.mPitchScale.mValue[i]);
|
||||||
stream->write(mSlots.mPitchScale.mVariance[ i ][ 0 ] );
|
if (stream->writeFlag(mSlots.mPitchScale.mVariance[i][0] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag(mSlots.mPitchScale.mVariance[ i ][ 1 ] > 0))
|
stream->write(mSlots.mPitchScale.mVariance[i][0]);
|
||||||
stream->write(mSlots.mPitchScale.mVariance[ i ][ 1 ] );
|
if (stream->writeFlag(mSlots.mPitchScale.mVariance[i][1] > 0))
|
||||||
FOR_EACH_SLOT if (stream->writeFlag( mSlots.mRepeatCount[ i ] > 0))
|
stream->write(mSlots.mPitchScale.mVariance[i][1]);
|
||||||
stream->write( mSlots.mRepeatCount[ i ] );
|
if (stream->writeFlag(mSlots.mRepeatCount[i] > 0))
|
||||||
|
stream->write(mSlots.mRepeatCount[i]);
|
||||||
FOR_EACH_SLOT sfxWrite( stream, mSlots.mState[ i ] );
|
|
||||||
FOR_EACH_SLOT PACKDATA_SOUNDASSET_ARRAY(Track, i);
|
sfxWrite(stream, mSlots.mState[i]);
|
||||||
|
sfxWrite(stream, mSlots.mTrack[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -442,36 +490,39 @@ void SFXPlayList::unpackData( BitStream* stream )
|
||||||
mRandomMode = ( ERandomMode ) stream->readInt( NUM_RANDOM_MODE_BITS );
|
mRandomMode = ( ERandomMode ) stream->readInt( NUM_RANDOM_MODE_BITS );
|
||||||
mLoopMode = ( ELoopMode ) stream->readInt( NUM_LOOP_MODE_BITS );
|
mLoopMode = ( ELoopMode ) stream->readInt( NUM_LOOP_MODE_BITS );
|
||||||
mNumSlotsToPlay = stream->readInt( NUM_SLOTS_TO_PLAY_BITS );
|
mNumSlotsToPlay = stream->readInt( NUM_SLOTS_TO_PLAY_BITS );
|
||||||
|
|
||||||
FOR_EACH_SLOT mSlots.mReplayMode[ i ] = ( EReplayMode ) stream->readInt( NUM_REPLAY_MODE_BITS );
|
mActiveSlots = stream->readInt(8);
|
||||||
FOR_EACH_SLOT mSlots.mTransitionIn[ i ] = ( ETransitionMode ) stream->readInt( NUM_TRANSITION_MODE_BITS );
|
|
||||||
FOR_EACH_SLOT mSlots.mTransitionOut[ i ] = ( ETransitionMode ) stream->readInt( NUM_TRANSITION_MODE_BITS );
|
for (U32 i = 0; i < mActiveSlots; ++i)
|
||||||
FOR_EACH_SLOT mSlots.mStateMode[ i ] = ( EStateMode ) stream->readInt( NUM_STATE_MODE_BITS );
|
{
|
||||||
|
mSlots.mReplayMode[i] = (EReplayMode)stream->readInt(NUM_REPLAY_MODE_BITS);
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeIn.mValue[ i ] );}
|
mSlots.mTransitionIn[i] = (ETransitionMode)stream->readInt(NUM_TRANSITION_MODE_BITS);
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeIn.mVariance[ i ][ 0 ] );}
|
mSlots.mTransitionOut[i] = (ETransitionMode)stream->readInt(NUM_TRANSITION_MODE_BITS);
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeIn.mVariance[ i ][ 1 ] );}
|
mSlots.mStateMode[i] = (EStateMode)stream->readInt(NUM_STATE_MODE_BITS);
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeOut.mValue[ i ] );}
|
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeOut.mVariance[ i ][ 0 ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mFadeTimeIn.mValue[i]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeOut.mVariance[ i ][ 1 ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mFadeTimeIn.mVariance[i][0]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeIn.mValue[ i ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mFadeTimeIn.mVariance[i][1]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeIn.mVariance[ i ][ 0 ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mFadeTimeOut.mValue[i]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeIn.mVariance[ i ][ 1 ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mFadeTimeOut.mVariance[i][0]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeOut.mValue[ i ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mFadeTimeOut.mVariance[i][1]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeOut.mVariance[ i ][ 0 ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mDelayTimeIn.mValue[i]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeOut.mVariance[ i ][ 1 ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mDelayTimeIn.mVariance[i][0]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mVolumeScale.mValue[ i ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mDelayTimeIn.mVariance[i][1]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mVolumeScale.mVariance[ i ][ 0 ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mDelayTimeOut.mValue[i]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mVolumeScale.mVariance[ i ][ 1 ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mDelayTimeOut.mVariance[i][0]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mPitchScale.mValue[ i ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mDelayTimeOut.mVariance[i][1]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mPitchScale.mVariance[ i ][ 0 ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mVolumeScale.mValue[i]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mPitchScale.mVariance[ i ][ 1 ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mVolumeScale.mVariance[i][0]); }
|
||||||
FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mRepeatCount[ i ] );}
|
if (stream->readFlag()) { stream->read(&mSlots.mVolumeScale.mVariance[i][1]); }
|
||||||
|
if (stream->readFlag()) { stream->read(&mSlots.mPitchScale.mValue[i]); }
|
||||||
FOR_EACH_SLOT sfxRead( stream, &mSlots.mState[ i ] );
|
if (stream->readFlag()) { stream->read(&mSlots.mPitchScale.mVariance[i][0]); }
|
||||||
FOR_EACH_SLOT UNPACKDATA_SOUNDASSET_ARRAY(Track, i);
|
if (stream->readFlag()) { stream->read(&mSlots.mPitchScale.mVariance[i][1]); }
|
||||||
|
if (stream->readFlag()) { stream->read(&mSlots.mRepeatCount[i]); }
|
||||||
#undef FOR_EACH_SLOT
|
|
||||||
|
sfxRead(stream, &mSlots.mState[i]);
|
||||||
|
sfxRead(stream, &mSlots.mTrack[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -486,8 +537,8 @@ void SFXPlayList::inspectPostApply()
|
||||||
|
|
||||||
void SFXPlayList::validate()
|
void SFXPlayList::validate()
|
||||||
{
|
{
|
||||||
if( mNumSlotsToPlay > NUM_SLOTS )
|
if( mNumSlotsToPlay > mActiveSlots )
|
||||||
mNumSlotsToPlay = NUM_SLOTS;
|
mNumSlotsToPlay = mActiveSlots;
|
||||||
|
|
||||||
mSlots.mFadeTimeIn.validate();
|
mSlots.mFadeTimeIn.validate();
|
||||||
mSlots.mFadeTimeOut.validate();
|
mSlots.mFadeTimeOut.validate();
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,8 @@
|
||||||
#include "sfx/sfxTrack.h"
|
#include "sfx/sfxTrack.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SOUND_ASSET_H
|
|
||||||
#include "T3D/assets/SoundAsset.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
class SFXState;
|
class SFXState;
|
||||||
|
class SFXDescription;
|
||||||
|
|
||||||
/// A playback list of SFXTracks.
|
/// A playback list of SFXTracks.
|
||||||
///
|
///
|
||||||
|
|
@ -79,7 +74,7 @@ class SFXPlayList : public SFXTrack
|
||||||
|
|
||||||
typedef SFXTrack Parent;
|
typedef SFXTrack Parent;
|
||||||
|
|
||||||
enum
|
enum SFXPlaylistSettings
|
||||||
{
|
{
|
||||||
/// Number of slots in a playlist.
|
/// Number of slots in a playlist.
|
||||||
///
|
///
|
||||||
|
|
@ -261,6 +256,9 @@ class SFXPlayList : public SFXTrack
|
||||||
/// is playing.
|
/// is playing.
|
||||||
EStateMode mStateMode[ NUM_SLOTS ];
|
EStateMode mStateMode[ NUM_SLOTS ];
|
||||||
|
|
||||||
|
/// Track to play in this slot.
|
||||||
|
SFXTrack* mTrack[NUM_SLOTS];
|
||||||
|
|
||||||
SlotData()
|
SlotData()
|
||||||
{
|
{
|
||||||
dMemset( mReplayMode, 0, sizeof( mReplayMode ) );
|
dMemset( mReplayMode, 0, sizeof( mReplayMode ) );
|
||||||
|
|
@ -268,6 +266,7 @@ class SFXPlayList : public SFXTrack
|
||||||
dMemset( mTransitionOut, 0, sizeof( mTransitionOut ) );
|
dMemset( mTransitionOut, 0, sizeof( mTransitionOut ) );
|
||||||
dMemset( mRepeatCount, 0, sizeof( mRepeatCount ) );
|
dMemset( mRepeatCount, 0, sizeof( mRepeatCount ) );
|
||||||
dMemset( mState, 0, sizeof( mState ) );
|
dMemset( mState, 0, sizeof( mState ) );
|
||||||
|
dMemset( mTrack, 0, sizeof( mTrack ) );
|
||||||
dMemset( mStateMode, 0, sizeof( mStateMode ) );
|
dMemset( mStateMode, 0, sizeof( mStateMode ) );
|
||||||
|
|
||||||
for( U32 i = 0; i < NUM_SLOTS; ++ i )
|
for( U32 i = 0; i < NUM_SLOTS; ++ i )
|
||||||
|
|
@ -282,31 +281,33 @@ class SFXPlayList : public SFXTrack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
DECLARE_SOUNDASSET_ARRAY(SFXPlayList, Track, NUM_SLOTS);
|
|
||||||
DECLARE_ASSET_ARRAY_SETGET(SFXPlayList, Track);
|
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
|
// moved to public for soundasset
|
||||||
|
|
||||||
/// Trace interpreter execution. This field is not networked.
|
/// Trace interpreter execution. This field is not networked.
|
||||||
bool mTrace;
|
bool mTrace;
|
||||||
|
|
||||||
/// Select slots at random.
|
/// Select slots at random.
|
||||||
ERandomMode mRandomMode;
|
ERandomMode mRandomMode;
|
||||||
|
|
||||||
/// Loop over slots in this list.
|
/// Loop over slots in this list.
|
||||||
ELoopMode mLoopMode;
|
ELoopMode mLoopMode;
|
||||||
|
|
||||||
/// Number of slots to play from list. This can be used, for example,
|
/// Number of slots to play from list. This can be used, for example,
|
||||||
/// to create a list of tracks where only a single track is selected and
|
/// to create a list of tracks where only a single track is selected and
|
||||||
/// played for each cycle.
|
/// played for each cycle.
|
||||||
U32 mNumSlotsToPlay;
|
U32 mNumSlotsToPlay;
|
||||||
|
|
||||||
/// Data for each of the playlist slots.
|
/// Data for each of the playlist slots.
|
||||||
SlotData mSlots;
|
SlotData mSlots;
|
||||||
|
|
||||||
public:
|
U32 mActiveSlots;
|
||||||
|
|
||||||
SFXPlayList();
|
SFXPlayList();
|
||||||
|
|
||||||
|
/// The destructor.
|
||||||
|
virtual ~SFXPlayList();
|
||||||
|
|
||||||
/// Make all settings conform to constraints.
|
/// Make all settings conform to constraints.
|
||||||
void validate();
|
void validate();
|
||||||
|
|
@ -324,7 +325,7 @@ class SFXPlayList : public SFXTrack
|
||||||
ELoopMode getLoopMode() const { return mLoopMode; }
|
ELoopMode getLoopMode() const { return mLoopMode; }
|
||||||
|
|
||||||
/// Return the total number of slots in the list.
|
/// Return the total number of slots in the list.
|
||||||
U32 getNumSlots() const { return NUM_SLOTS; }
|
U32 getNumSlots();
|
||||||
|
|
||||||
/// Return the slot data for this list.
|
/// Return the slot data for this list.
|
||||||
const SlotData& getSlots() const { return mSlots; }
|
const SlotData& getSlots() const { return mSlots; }
|
||||||
|
|
@ -332,8 +333,13 @@ class SFXPlayList : public SFXTrack
|
||||||
DECLARE_CONOBJECT( SFXPlayList );
|
DECLARE_CONOBJECT( SFXPlayList );
|
||||||
DECLARE_CATEGORY( "SFX" );
|
DECLARE_CATEGORY( "SFX" );
|
||||||
DECLARE_DESCRIPTION( "A playback list of SFXProfiles or nested SFXPlayLists." );
|
DECLARE_DESCRIPTION( "A playback list of SFXProfiles or nested SFXPlayLists." );
|
||||||
|
|
||||||
|
// SFXTrack.
|
||||||
|
virtual bool isLooping() const;
|
||||||
|
|
||||||
// SimDataBlock.
|
// SimDataBlock.
|
||||||
|
bool onAdd();
|
||||||
|
void onRemove();
|
||||||
virtual bool preload( bool server, String& errorStr );
|
virtual bool preload( bool server, String& errorStr );
|
||||||
virtual void packData( BitStream* stream );
|
virtual void packData( BitStream* stream );
|
||||||
virtual void unpackData( BitStream* stream );
|
virtual void unpackData( BitStream* stream );
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ class SFXSound : public SFXSource,
|
||||||
bool isBlocked() const { return ( mVoice && mVoice->getStatus() == SFXStatusBlocked ); }
|
bool isBlocked() const { return ( mVoice && mVoice->getStatus() == SFXStatusBlocked ); }
|
||||||
|
|
||||||
/// Returns true if this is a continuously streaming source.
|
/// Returns true if this is a continuously streaming source.
|
||||||
bool isStreaming() const { return mDescription->mIsStreaming; }
|
bool isStreaming() const { return mDescription ? mDescription->mIsStreaming : false; }
|
||||||
|
|
||||||
/// Returns true if the source's associated data is ready for playback.
|
/// Returns true if the source's associated data is ready for playback.
|
||||||
bool isReady() const;
|
bool isReady() const;
|
||||||
|
|
|
||||||
|
|
@ -192,18 +192,18 @@ SFXSource::SFXSource()
|
||||||
mSavedStatus( SFXStatusNull ),
|
mSavedStatus( SFXStatusNull ),
|
||||||
mStatusCallback( NULL ),
|
mStatusCallback( NULL ),
|
||||||
mDescription( NULL ),
|
mDescription( NULL ),
|
||||||
mVolume( 1.f ),
|
mVolume( 1.0f ),
|
||||||
mPreFadeVolume( 1.f ),
|
mPreFadeVolume( 1.0f ),
|
||||||
mFadedVolume( 1.f ),
|
mFadedVolume( 1.0f ),
|
||||||
mModulativeVolume( 1.f ),
|
mModulativeVolume( 1.0f ),
|
||||||
mPreAttenuatedVolume( 1.f ),
|
mPreAttenuatedVolume( 1.0f ),
|
||||||
mAttenuatedVolume( 1.f ),
|
mAttenuatedVolume( 1.0f ),
|
||||||
mPriority( 0 ),
|
mPriority( 0 ),
|
||||||
mModulativePriority( 1.f ),
|
mModulativePriority( 1.0f ),
|
||||||
mEffectivePriority( 0 ),
|
mEffectivePriority( 0 ),
|
||||||
mPitch( 1.f ),
|
mPitch( 1.f ),
|
||||||
mModulativePitch( 1.f ),
|
mModulativePitch( 1.0f ),
|
||||||
mEffectivePitch( 1.f ),
|
mEffectivePitch( 1.0f ),
|
||||||
mTransform( true ),
|
mTransform( true ),
|
||||||
mVelocity( 0, 0, 0 ),
|
mVelocity( 0, 0, 0 ),
|
||||||
mMinDistance( 1 ),
|
mMinDistance( 1 ),
|
||||||
|
|
@ -213,14 +213,14 @@ SFXSource::SFXSource()
|
||||||
mConeOutsideVolume( 1 ),
|
mConeOutsideVolume( 1 ),
|
||||||
mDistToListener( 0.f ),
|
mDistToListener( 0.f ),
|
||||||
mTransformScattered( false ),
|
mTransformScattered( false ),
|
||||||
mFadeInTime( 0.f ),
|
mFadeInTime( 0.0f ),
|
||||||
mFadeOutTime( 0.f ),
|
mFadeOutTime( 0.0f ),
|
||||||
mFadeInPoint( -1.f ),
|
mFadeInPoint( -1.0f ),
|
||||||
mFadeOutPoint( -1.f ),
|
mFadeOutPoint( -1.0f ),
|
||||||
mFadeSegmentType( FadeSegmentNone ),
|
mFadeSegmentType( FadeSegmentNone ),
|
||||||
mFadeSegmentEase( NULL ),
|
mFadeSegmentEase( NULL ),
|
||||||
mFadeSegmentStartPoint( 0.f ),
|
mFadeSegmentStartPoint( 0.0f ),
|
||||||
mFadeSegmentEndPoint( 0.f ),
|
mFadeSegmentEndPoint( 0.0f ),
|
||||||
mSavedFadeTime( -1.f ),
|
mSavedFadeTime( -1.f ),
|
||||||
mPlayStartTick( 0 )
|
mPlayStartTick( 0 )
|
||||||
{
|
{
|
||||||
|
|
@ -236,17 +236,17 @@ SFXSource::SFXSource( SFXTrack* track, SFXDescription* description )
|
||||||
mTrack( track ),
|
mTrack( track ),
|
||||||
mDescription( description ),
|
mDescription( description ),
|
||||||
mVolume( 1.f ),
|
mVolume( 1.f ),
|
||||||
mPreFadeVolume( 1.f ),
|
mPreFadeVolume( 1.0f ),
|
||||||
mFadedVolume( 1.f ),
|
mFadedVolume( 1.0f ),
|
||||||
mModulativeVolume( 1.f ),
|
mModulativeVolume( 1.0f ),
|
||||||
mPreAttenuatedVolume( 1.f ),
|
mPreAttenuatedVolume( 1.0f ),
|
||||||
mAttenuatedVolume( 1.f ),
|
mAttenuatedVolume( 1.0f ),
|
||||||
mPriority( 0 ),
|
mPriority( 0 ),
|
||||||
mModulativePriority( 1.f ),
|
mModulativePriority( 1.0f ),
|
||||||
mEffectivePriority( 0 ),
|
mEffectivePriority( 0 ),
|
||||||
mPitch( 1.f ),
|
mPitch( 1.0f ),
|
||||||
mModulativePitch( 1.f ),
|
mModulativePitch( 1.0f ),
|
||||||
mEffectivePitch( 1.f ),
|
mEffectivePitch( 1.0f ),
|
||||||
mTransform( true ),
|
mTransform( true ),
|
||||||
mVelocity( 0, 0, 0 ),
|
mVelocity( 0, 0, 0 ),
|
||||||
mMinDistance( 1 ),
|
mMinDistance( 1 ),
|
||||||
|
|
@ -256,15 +256,15 @@ SFXSource::SFXSource( SFXTrack* track, SFXDescription* description )
|
||||||
mConeOutsideVolume( 1 ),
|
mConeOutsideVolume( 1 ),
|
||||||
mDistToListener( 0.f ),
|
mDistToListener( 0.f ),
|
||||||
mTransformScattered( false ),
|
mTransformScattered( false ),
|
||||||
mFadeInTime( 0.f ),
|
mFadeInTime( 0.0f ),
|
||||||
mFadeOutTime( 0.f ),
|
mFadeOutTime( 0.0f ),
|
||||||
mFadeInPoint( -1.f ),
|
mFadeInPoint( -1.0f ),
|
||||||
mFadeOutPoint( -1.f ),
|
mFadeOutPoint( -1.0f ),
|
||||||
mFadeSegmentType( FadeSegmentNone ),
|
mFadeSegmentType( FadeSegmentNone ),
|
||||||
mFadeSegmentEase( NULL ),
|
mFadeSegmentEase( NULL ),
|
||||||
mFadeSegmentStartPoint( 0.f ),
|
mFadeSegmentStartPoint( 0.0f ),
|
||||||
mFadeSegmentEndPoint( 0.f ),
|
mFadeSegmentEndPoint( 0.0f ),
|
||||||
mSavedFadeTime( -1.f ),
|
mSavedFadeTime( -1.0f ),
|
||||||
mPlayStartTick( 0 )
|
mPlayStartTick( 0 )
|
||||||
{
|
{
|
||||||
VECTOR_SET_ASSOCIATION( mParameters );
|
VECTOR_SET_ASSOCIATION( mParameters );
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 237 B |
|
|
@ -0,0 +1,8 @@
|
||||||
|
<ImageAsset
|
||||||
|
canSave="true"
|
||||||
|
canSaveDynamicFields="true"
|
||||||
|
AssetName="pausebutton_h_image"
|
||||||
|
imageFile="@assetFile=pausebutton_h.png"
|
||||||
|
UseMips="true"
|
||||||
|
isHDRImage="false"
|
||||||
|
imageType="Albedo" />
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 145 B |
|
|
@ -0,0 +1,8 @@
|
||||||
|
<ImageAsset
|
||||||
|
canSave="true"
|
||||||
|
canSaveDynamicFields="true"
|
||||||
|
AssetName="pausebutton_n_image"
|
||||||
|
imageFile="@assetFile=pausebutton_n.png"
|
||||||
|
UseMips="true"
|
||||||
|
isHDRImage="false"
|
||||||
|
imageType="Albedo" />
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 221 B |
|
|
@ -0,0 +1,8 @@
|
||||||
|
<ImageAsset
|
||||||
|
canSave="true"
|
||||||
|
canSaveDynamicFields="true"
|
||||||
|
AssetName="stopbutton_h_image"
|
||||||
|
imageFile="@assetFile=stopbutton_h.png"
|
||||||
|
UseMips="true"
|
||||||
|
isHDRImage="false"
|
||||||
|
imageType="Albedo" />
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 143 B |
|
|
@ -0,0 +1,8 @@
|
||||||
|
<ImageAsset
|
||||||
|
canSave="true"
|
||||||
|
canSaveDynamicFields="true"
|
||||||
|
AssetName="stopbutton_n_image"
|
||||||
|
imageFile="@assetFile=stopbutton_n.png"
|
||||||
|
UseMips="true"
|
||||||
|
isHDRImage="false"
|
||||||
|
imageType="Albedo" />
|
||||||
Loading…
Add table
Add a link
Reference in a new issue