From f9291fd65c0e2d74bcc4c18a7edb8601b0fd022e Mon Sep 17 00:00:00 2001 From: nilllzz Date: Thu, 22 Feb 2018 03:40:20 +0100 Subject: [PATCH] fix sounds and music --- P3D/Core/Core.vb | 1 - P3D/Core/GameOptions.vb | 2 +- P3D/Core/MainGameFunctions.vb | 2 +- P3D/Player/Player.vb | 1 - P3D/Resources/ContentPackManager.vb | 2 +- P3D/Resources/Sound/MusicManager.vb | 4 +- P3D/Resources/Sound/SoundManager.vb | 275 ++++++++-------------------- P3D/Screens/NewOptionScreen.vb | 6 +- 8 files changed, 84 insertions(+), 209 deletions(-) diff --git a/P3D/Core/Core.vb b/P3D/Core/Core.vb index 6c844c23c..f878da328 100644 --- a/P3D/Core/Core.vb +++ b/P3D/Core/Core.vb @@ -97,7 +97,6 @@ TextureManager.InitializeTextures() MusicManager.Setup() MusicManager.LoadMusic(False) - SoundManager.LoadSounds(False) Logger.Debug("Loaded content.") Logger.Debug("Validated files. Result: " & Security.FileValidation.IsValid(True).ToString()) diff --git a/P3D/Core/GameOptions.vb b/P3D/Core/GameOptions.vb index a35c9cf20..7ad14ad4d 100644 --- a/P3D/Core/GameOptions.vb +++ b/P3D/Core/GameOptions.vb @@ -44,7 +44,7 @@ Case "sound" SoundManager.Volume = CSng(CDbl(value) / 100) Case "muted" - SoundManager.Mute(CBool(value)) + SoundManager.Muted = CBool(value) MediaPlayer.IsMuted = CBool(value) Case "renderdistance" Me.RenderDistance = CInt(value) diff --git a/P3D/Core/MainGameFunctions.vb b/P3D/Core/MainGameFunctions.vb index e3acf49a8..d8e31f630 100644 --- a/P3D/Core/MainGameFunctions.vb +++ b/P3D/Core/MainGameFunctions.vb @@ -25,7 +25,7 @@ ToggleFullScreen() ElseIf KeyBoardHandler.KeyPressed(KeyBindings.MuteMusicKey) AndAlso Core.CurrentScreen.CanMuteMusic Then MusicManager.Mute(Not MediaPlayer.IsMuted) - SoundManager.Mute(MediaPlayer.IsMuted) + SoundManager.Muted = MediaPlayer.IsMuted Core.GameOptions.SaveOptions() Core.CurrentScreen.ToggledMute() End If diff --git a/P3D/Player/Player.vb b/P3D/Player/Player.vb index b88cb0c9c..bcdff9a2b 100644 --- a/P3D/Player/Player.vb +++ b/P3D/Player/Player.vb @@ -520,7 +520,6 @@ If GameModeManager.ActiveGameMode.IsDefaultGamemode = False Then MusicManager.LoadMusic(True) - SoundManager.LoadSounds(True) End If SmashRock.Load() Badge.Load() diff --git a/P3D/Resources/ContentPackManager.vb b/P3D/Resources/ContentPackManager.vb index cabbc262a..f45cd83db 100644 --- a/P3D/Resources/ContentPackManager.vb +++ b/P3D/Resources/ContentPackManager.vb @@ -105,7 +105,7 @@ TextureResolutions.Clear() FilesExist.Clear() MusicManager.ReloadMusic() - SoundManager.ReloadSounds() + SoundManager.Clear() ModelManager.Clear() TextureManager.TextureList.Clear() Water.ClearAnimationResources() diff --git a/P3D/Resources/Sound/MusicManager.vb b/P3D/Resources/Sound/MusicManager.vb index 5cb6158d3..e50edd3ab 100644 --- a/P3D/Resources/Sound/MusicManager.vb +++ b/P3D/Resources/Sound/MusicManager.vb @@ -77,8 +77,8 @@ Dim filePath As String = GameController.GamePath & "\" & cContent.RootDirectory & "\Songs\" & Name & ".mp3" song = CType(ctor.Invoke({Name, filePath, 0}), Song) ElseIf System.IO.File.Exists(GameController.GamePath & "\" & cContent.RootDirectory & "\Songs\" & Name & ".ogg") = True Then - Dim filePath As String = GameController.GamePath & "\" & cContent.RootDirectory & "\Songs\" & Name & ".ogg" - Dim source = New Uri(filePath) + Dim filePath As String = cContent.RootDirectory & "\Songs\" & Name & ".ogg" + Dim source = New Uri(filePath, UriKind.Relative) song = Song.FromUri(Name, source) Else Logger.Log(Logger.LogTypes.Warning, "MusicManager.vb: Song at """ & GameController.GamePath & "\" & cContent.RootDirectory & "\Songs\" & Name & """ was not found!") diff --git a/P3D/Resources/Sound/SoundManager.vb b/P3D/Resources/Sound/SoundManager.vb index 7302b2e33..0c599e6ba 100644 --- a/P3D/Resources/Sound/SoundManager.vb +++ b/P3D/Resources/Sound/SoundManager.vb @@ -1,209 +1,86 @@ Public Class SoundManager - Shared Muted As Boolean = False + Const POKEMON_CRY_VOLUME_MULTIPLIER As Single = 0.6F + + Shared _sounds As Dictionary(Of String, SoundEffect) = New Dictionary(Of String, SoundEffect) - Private Shared SoundFiles As New Dictionary(Of String, CSound) Public Shared Volume As Single = 1.0F - - Class CSound - - Private _sound As SoundEffect - Private _origin As String - - Public Sub New(ByVal Sound As SoundEffect, ByVal Origin As String) - Me._sound = Sound - Me._origin = Origin - End Sub - - Public Property Sound() As SoundEffect - Get - Return Me._sound - End Get - Set(value As SoundEffect) - Me._sound = value - End Set - End Property - - Public Property Origin() As String - Get - Return Me._origin - End Get - Set(value As String) - Me._origin = value - End Set - End Property - - Public ReadOnly Property IsStandardSong() As Boolean - Get - Return (Me.Origin = "Content") - End Get - End Property - - End Class - - Private Shared Function AddSound(ByVal Name As String, ByVal forceReplace As Boolean) As Boolean - Try - Dim cContent As ContentManager = ContentPackManager.GetContentManager("Sounds\" & Name, ".xnb,.wav") - - Dim loadSound As Boolean = False - Dim removeSound As Boolean = False - - If SoundFiles.ContainsKey(Name.ToLower()) = False Then - loadSound = True - ElseIf forceReplace = True And SoundFiles(Name.ToLower()).IsStandardSong = True Then - removeSound = True - loadSound = True - End If - - If loadSound = True Then - Dim sound As SoundEffect = Nothing - - If System.IO.File.Exists(GameController.GamePath & "\" & cContent.RootDirectory & "\Sounds\" & Name & ".xnb") = False Then - If System.IO.File.Exists(GameController.GamePath & "\" & cContent.RootDirectory & "\Sounds\" & Name & ".wav") = True Then - Using stream As System.IO.Stream = System.IO.File.Open(GameController.GamePath & "\" & cContent.RootDirectory & "\Sounds\" & Name & ".wav", IO.FileMode.OpenOrCreate) - sound = SoundEffect.FromStream(stream) - End Using - Else - Logger.Log(Logger.LogTypes.Warning, "SoundManager.vb: Sound at """ & GameController.GamePath & "\" & cContent.RootDirectory & "\Songs\" & Name & """ was not found!") - Return False - End If - Else - sound = cContent.Load(Of SoundEffect)("Sounds\" & Name) - End If - - If Not sound Is Nothing Then - If removeSound = True Then - SoundFiles.Remove(Name.ToLower()) - End If - SoundFiles.Add(Name.ToLower(), New CSound(sound, cContent.RootDirectory)) - End If - End If - Catch ex As Exception - Logger.Log(Logger.LogTypes.Warning, "SoundManager.vb: File at ""Sounds\" & Name & """ is not a valid sound file. They have to be a PCM wave file, mono or stereo, 8 or 16 bit and have to have a sample rate between 8k and 48k Hz.") - Return False - End Try - Return True - End Function - - Private Shared Function GetSoundEffect(ByVal Name As String) As SoundEffect - Select Case Name.ToLower() - Case "healing" - Name = "pokemon_heal" - End Select - - If SoundFiles.ContainsKey(Name.ToLower()) = True Then - Return SoundFiles(Name.ToLower()).Sound - Else - If TryAddGameModeSound(Name) = True Then - Return SoundFiles(Name.ToLower()).Sound - Else - Logger.Log(Logger.LogTypes.Warning, "SoundManager.vb: Cannot find sound file """ & Name & """. Return nothing.") - Return Nothing - End If - End If - End Function - - Private Shared Function TryAddGameModeSound(ByVal Name As String) As Boolean - Dim soundfile As String = GameController.GamePath & GameModeManager.ActiveGameMode.ContentPath & "Sounds\" & Name & ".xnb" - If System.IO.File.Exists(soundfile) = True Then - Return AddSound(Name, False) - End If - Return False - End Function - - Public Shared Sub LoadSounds(ByVal forceReplace As Boolean) - For Each soundfile As String In System.IO.Directory.GetFiles(GameController.GamePath & "\Content\Sounds\") - If soundfile.EndsWith(".xnb") = True Then - soundfile = System.IO.Path.GetFileNameWithoutExtension(soundfile) - AddSound(soundfile, forceReplace) - End If - Next - If Core.GameOptions.ContentPackNames.Count > 0 Then - For Each c As String In Core.GameOptions.ContentPackNames - Dim path As String = GameController.GamePath & "\ContentPacks\" & c & "\Sounds\" - - If System.IO.Directory.Exists(path) = True Then - For Each soundfile As String In System.IO.Directory.GetFiles(path, "*.*", IO.SearchOption.AllDirectories) - If soundfile.EndsWith(".xnb") = True Then - soundfile = System.IO.Path.GetFileNameWithoutExtension(soundfile) - AddSound(soundfile, forceReplace) - End If - Next - End If - Next - End If - End Sub - - Public Shared Sub PlaySound(ByVal Sound As String, ByVal Pitch As Single, ByVal Pan As Single, ByVal Volume As Single, ByVal stopMusic As Boolean) - If Muted = False Then - Dim s As SoundEffect = Nothing - - s = GetSoundEffect(Sound) - - If Not s Is Nothing Then - Logger.Debug("SoundEffect [" & Sound & "]") - - If CanPlaySound() = True Then - s.Play(Volume, Pitch, Pan) - - If stopMusic = True Then - MusicManager.PauseForSound(s) - End If - Else - Logger.Log(Logger.LogTypes.Warning, "SoundManager.vb: Failed to play sound: No audio devices found.") - End If - End If - End If - End Sub - - Public Shared Sub PlayPokemonCry(ByVal Number As Integer) - PlayPokemonCry(Number, 0.0F, 0F, Volume) - End Sub - - Public Shared Sub PlayPokemonCry(ByVal Number As Integer, ByVal Pitch As Single, ByVal Pan As Single) - PlayPokemonCry(Number, Pitch, Pan, Volume) - End Sub - - Public Shared Sub PlayPokemonCry(ByVal Number As Integer, ByVal Pitch As Single, ByVal Pan As Single, ByVal Volume As Single) - If Muted = False Then - Dim soundfile As String = "Cries\" & Number & ".xnb" - If GameModeManager.ContentFileExists("Sounds\" & soundfile) = True Then - AddSound("Cries\" & Number, False) - - Dim s As SoundEffect = GetSoundEffect("Cries\" & Number.ToString()) - - If CanPlaySound() = True Then - If Not s Is Nothing Then - s.Play(Volume * 0.6F, Pitch, Pan) - End If - Else - Logger.Log(Logger.LogTypes.Warning, "SoundManager.vb: Failed to play sound: No audio devices found.") - End If - End If - End If - End Sub - - Public Shared Sub Mute(ByVal mute As Boolean) - Muted = mute - End Sub - - Public Shared Sub PlaySound(ByVal Sound As String) - PlaySound(Sound, 0.0F, 0.0F, Volume, False) - End Sub - - Public Shared Sub PlaySound(ByVal Sound As String, ByVal stopMusic As Boolean) - PlaySound(Sound, 0.0F, 0.0F, Volume, stopMusic) - End Sub - - Public Shared Sub ReloadSounds() - SoundFiles.Clear() - LoadSounds(False) - End Sub + Public Shared Muted As Boolean = False Private Declare Function GetAudioOutputDevices Lib "winmm.dll" Alias "waveOutGetNumDevs" () As Integer - - Private Shared Function CanPlaySound() As Boolean + Private Shared Function HasOutputDeviceAvailable() As Boolean Return GetAudioOutputDevices() > 0 End Function + Public Shared Sub Clear() + _sounds.Clear() + End Sub + + Public Shared Sub PlaySound(soundFile As String) + PlaySound(soundFile, 0.0F, 0.0F, Volume, False) + End Sub + + Public Shared Sub PlaySound(soundFile As String, stopMusic As Boolean) + PlaySound(soundFile, 0.0F, 0.0F, Volume, stopMusic) + End Sub + + Public Shared Sub PlaySound(soundFile As String, pitch As Single, pan As Single, volume As Single, stopMusic As Boolean) + + If Not Muted Then + + Dim key = soundFile.ToLowerInvariant() + Dim sound As SoundEffect = Nothing + If Not _sounds.TryGetValue(key, sound) Then + + ' load sound + Dim filePath = Path.Combine(GameController.GamePath, "Content\Sounds", soundFile & ".wav") + If File.Exists(filePath) Then + Using stream As New FileStream(filePath, FileMode.OpenOrCreate) + Try + sound = SoundEffect.FromStream(stream) + _sounds.Add(key, sound) + Catch ex As Exception + Logger.Log(Logger.LogTypes.ErrorMessage, "Failed to load sound at """ & soundFile & """: " & ex.Message) + End Try + End Using + End If + + End If + + If sound IsNot Nothing Then + + If HasOutputDeviceAvailable() Then + + Logger.Debug("SoundEffect [" & soundFile & "]") + + sound.Play(volume, pitch, pan) + + If stopMusic = True Then + MusicManager.PauseForSound(sound) + End If + + Else + + Logger.Log(Logger.LogTypes.ErrorMessage, "Failed to play sound: no audio device available.") + + End If + + End If + + End If + + End Sub + + Public Shared Sub PlayPokemonCry(pokemonId As Integer) + PlaySound("Cries/" + pokemonId.ToString(), 0F, 0F, Volume * POKEMON_CRY_VOLUME_MULTIPLIER, False) + End Sub + + Public Shared Sub PlayPokemonCry(pokemonId As Integer, pitch As Single, pan As Single) + PlaySound("Cries/" + pokemonId.ToString(), pitch, pan, Volume * POKEMON_CRY_VOLUME_MULTIPLIER, False) + End Sub + + Public Shared Sub PlayPokemonCry(pokemonId As Integer, pitch As Single, pan As Single, volume As Single) + PlaySound("Cries/" + pokemonId.ToString(), pitch, pan, volume * POKEMON_CRY_VOLUME_MULTIPLIER, False) + End Sub + End Class \ No newline at end of file diff --git a/P3D/Screens/NewOptionScreen.vb b/P3D/Screens/NewOptionScreen.vb index df4b0ea13..b5d72ea8d 100644 --- a/P3D/Screens/NewOptionScreen.vb +++ b/P3D/Screens/NewOptionScreen.vb @@ -461,7 +461,7 @@ MusicManager.MasterVolume = CSng(Me.Music / 100) SoundManager.Volume = CSng(Me.Sound / 100) MusicManager.Mute(CBool(Me.Muted)) - SoundManager.Mute(CBool(Me.Muted)) + SoundManager.Muted = CBool(Me.Muted) Core.GameOptions.RenderDistance = Me.RenderDistance Core.GameOptions.GraphicStyle = Me.GraphicStyle Screen.Level.World.Initialize(Screen.Level.EnvironmentType, Screen.Level.WeatherType) @@ -645,7 +645,7 @@ Private Sub ApplyMusicChange() MusicManager.Mute(CBool(Me.Muted)) - SoundManager.Mute(CBool(Me.Muted)) + SoundManager.Muted = CBool(Me.Muted) MusicManager.MasterVolume = CSng(Me.Music / 100) SoundManager.Volume = CSng(Me.Sound / 100) End Sub @@ -868,7 +868,7 @@ Dim c As Color = New Color(255, 255, 255, CInt(255 * s._interfaceFade * s._pageFade)) - Core.SpriteBatch.Draw(s._texture, New Rectangle(CInt(pos.X), CInt(pos.Y), size, size), New Rectangle(16, 16, 16, 16), c) + Core.SpriteBatch.Draw(s._texture, New Rectangle(CInt(pos.X), CInt(pos.Y), Size, Size), New Rectangle(16, 16, 16, 16), c) Core.SpriteBatch.Draw(s._texture, New Rectangle(CInt(pos.X) + Size, CInt(pos.Y), Size * ButtonWidth, Size), New Rectangle(32, 16, 16, 16), c) Core.SpriteBatch.Draw(s._texture, New Rectangle(CInt(pos.X) + Size * (ButtonWidth + 1), CInt(pos.Y), Size, Size), New Rectangle(16, 16, 16, 16), c, 0.0F, Vector2.Zero, SpriteEffects.FlipHorizontally, 0.0F)