diff --git a/OpenRA.Game/Sound/Sound.cs b/OpenRA.Game/Sound/Sound.cs index 91665e7ed5..23f506061b 100644 --- a/OpenRA.Game/Sound/Sound.cs +++ b/OpenRA.Game/Sound/Sound.cs @@ -165,6 +165,14 @@ namespace OpenRA return Play(type, player, names.Random(world.LocalRandom), false, pos, volumeModifier); } + public ISound Play(ISoundFormat soundFormat) => Play(soundFormat, MusicVolume); + + public ISound Play(ISoundFormat soundFormat, float volume) + { + return soundEngine.Play2DStream(soundFormat.GetPCMInputStream(), soundFormat.Channels, soundFormat.SampleBits, soundFormat.SampleRate, + false, true, WPos.Zero, volume); + } + public void PlayVideo(byte[] raw, int channels, int sampleBits, int sampleRate) { StopVideo(); diff --git a/OpenRA.Mods.Common/AssetBrowser.cs b/OpenRA.Mods.Common/AssetBrowser.cs index 47debd7282..1b29765548 100644 --- a/OpenRA.Mods.Common/AssetBrowser.cs +++ b/OpenRA.Mods.Common/AssetBrowser.cs @@ -17,6 +17,7 @@ namespace OpenRA { public readonly string[] SpriteExtensions = Array.Empty(); public readonly string[] ModelExtensions = Array.Empty(); + public readonly string[] AudioExtensions = Array.Empty(); public readonly string[] VideoExtensions = Array.Empty(); } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/AssetBrowserLogic.cs index 164f4f1cbf..54456ad210 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/AssetBrowserLogic.cs @@ -27,6 +27,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly string[] allowedExtensions; readonly string[] allowedSpriteExtensions; readonly string[] allowedModelExtensions; + readonly string[] allowedAudioExtensions; readonly string[] allowedVideoExtensions; readonly IEnumerable acceptablePackages; readonly string[] palettes; @@ -48,6 +49,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic IReadOnlyPackage currentPackage; Sprite[] currentSprites; IModel currentVoxel; + ISound currentSound; VideoPlayerWidget player = null; bool isVideoLoaded = false; bool isLoadError = false; @@ -77,7 +79,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic { ticker.OnTick = () => { - if (animateFrames) + if (animateFrames && currentSprites != null) SelectNextFrame(); }; } @@ -310,9 +312,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic var assetBrowserModData = modData.Manifest.Get(); allowedSpriteExtensions = assetBrowserModData.SpriteExtensions; allowedModelExtensions = assetBrowserModData.ModelExtensions; + allowedAudioExtensions = assetBrowserModData.AudioExtensions; allowedVideoExtensions = assetBrowserModData.VideoExtensions; allowedExtensions = allowedSpriteExtensions .Union(allowedModelExtensions) + .Union(allowedAudioExtensions) .Union(allowedVideoExtensions) .ToArray(); @@ -402,6 +406,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic bool LoadAsset(IReadOnlyPackage package, string filename) { + if (currentSound != null) + Game.Sound.StopSound(currentSound); + + currentSprites = null; + currentFrame = 0; + currentVoxel = null; + currentSound = null; + if (isVideoLoaded) { player.Stop(); @@ -456,6 +468,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic // Just in case we're switching away from a type of asset that forced the music to pause. UnMuteSounds(); } + else if (allowedAudioExtensions.Contains(fileExtension)) + { + // Mute music so it doesn't interfere with current asset. + MuteSounds(); + + using (var soundStream = Game.ModData.DefaultFileSystem.Open(prefix + filename)) + foreach (var modDataSoundLoader in Game.ModData.SoundLoaders) + if (modDataSoundLoader.TryParseSound(soundStream, out var soundFormat)) + currentSound = Game.Sound.Play(soundFormat, Game.Sound.SoundVolume); + } else if (allowedVideoExtensions.Contains(fileExtension)) { var video = VideoLoader.GetVideo(Game.ModData.DefaultFileSystem.Open(filename), Game.ModData.VideoLoaders); diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index cbcb9839e1..cd6ef315af 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -240,6 +240,7 @@ ModelSequenceFormat: PlaceholderModelSequence AssetBrowser: SpriteExtensions: .shp, .tem, .des, .sno, .jun + AudioExtensions: .aud, .wav VideoExtensions: .vqa, .wsa GameSpeeds: diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 5a3923451b..c35180904e 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -215,6 +215,7 @@ ModelSequenceFormat: PlaceholderModelSequence AssetBrowser: SpriteExtensions: .shp, .r8 + AudioExtensions: .aud, .wav VideoExtensions: .vqa GameSpeeds: diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index d2ed4e56e8..e303c775ef 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -245,6 +245,7 @@ ModelSequenceFormat: PlaceholderModelSequence AssetBrowser: SpriteExtensions: .shp, .tmp, .tem, .des, .sno, .int + AudioExtensions: .aud, .wav VideoExtensions: .vqa, .wsa GameSpeeds: diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index 66b95d25ca..d7ee36c2cf 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -274,6 +274,7 @@ ModelSequenceFormat: VoxelModelSequence AssetBrowser: SpriteExtensions: .shp, .tem, .sno ModelExtensions: .vxl + AudioExtensions: .aud, .wav VideoExtensions: .vqa GameSpeeds: