2016-09-07 18:50:38 +02:00
Public Class MusicManager
Private Shared SongFiles As New Dictionary ( Of String , CSong )
Private Shared currentSong As String = " "
Public Shared SongList As New List ( Of String )
Public Shared Sub Setup ( )
MasterVolume = 1 . 0F
MediaPlayer . Volume = MasterVolume
Volume = 1 . 0F
NextSong = " "
FadeInSpeed = 0 . 0F
FadeOutSpeed = 0 . 0F
FadeOut = False
FadeIn = False
2016-10-17 05:41:19 +02:00
MediaPlayer . IsRepeating = False
2016-09-07 18:50:38 +02:00
End Sub
Class CSong
Private _song As Song
Private _origin As String
Public Sub New ( ByVal Song As Song , ByVal Origin As String )
Me . _song = Song
Me . _origin = Origin
End Sub
Public Property Song ( ) As Song
Get
Return Me . _song
End Get
Set ( value As Song )
Me . _song = 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 AddSong ( ByVal Name As String , ByVal forceReplace As Boolean ) As Boolean
Try
2017-07-25 09:45:18 +02:00
Dim cContent As ContentManager = ContentPackManager . GetContentManager ( " Songs\ " & Name , " .xnb,.mp3,.ogg " )
2016-09-07 18:50:38 +02:00
Dim loadSong As Boolean = False
Dim removeSong As Boolean = False
If SongFiles . ContainsKey ( Name . ToLower ( ) ) = False Then
loadSong = True
ElseIf forceReplace = True And SongFiles ( Name . ToLower ( ) ) . IsStandardSong = True Then
removeSong = True
loadSong = True
End If
If loadSong = True Then
Dim song As Song = Nothing
If System . IO . File . Exists ( GameController . GamePath & " \ " & cContent . RootDirectory & " \Songs\ " & Name & " .xnb " ) = False Then
If System . IO . File . Exists ( GameController . GamePath & " \ " & cContent . RootDirectory & " \Songs\ " & Name & " .mp3 " ) = True Then
Dim ctor = GetType ( Song ) . GetConstructor ( System . Reflection . BindingFlags . NonPublic Or System . Reflection . BindingFlags . Instance , Nothing , { GetType ( String ) , GetType ( String ) , GetType ( Integer ) } , Nothing )
Dim filePath As String = GameController . GamePath & " \ " & cContent . RootDirectory & " \Songs\ " & Name & " .mp3 "
song = CType ( ctor . Invoke ( { Name , filePath , 0 } ) , Song )
2017-07-25 09:45:18 +02:00
ElseIf System . IO . File . Exists ( GameController . GamePath & " \ " & cContent . RootDirectory & " \Songs\ " & Name & " .ogg " ) = True Then
2018-02-22 03:40:20 +01:00
Dim filePath As String = cContent . RootDirectory & " \Songs\ " & Name & " .ogg "
Dim source = New Uri ( filePath , UriKind . Relative )
2018-02-21 16:34:06 +01:00
song = Song . FromUri ( Name , source )
2016-09-07 18:50:38 +02:00
Else
Logger . Log ( Logger . LogTypes . Warning , " MusicManager.vb: Song at "" " & GameController . GamePath & " \ " & cContent . RootDirectory & " \Songs\ " & Name & " "" was not found! " )
Return False
End If
Else
song = cContent . Load ( Of Song ) ( " Songs\ " & Name )
End If
If Not song Is Nothing Then
If removeSong = True Then
SongFiles . Remove ( Name . ToLower ( ) )
End If
SongFiles . Add ( Name . ToLower ( ) , New CSong ( song , cContent . RootDirectory ) )
End If
End If
Catch ex As Exception
Logger . Log ( Logger . LogTypes . Warning , " MusicManager.vb: File at "" Songs\ " & Name & " "" is not a valid song file! " )
Return False
End Try
Return True
End Function
Public Shared Function GetSong ( ByVal Name As String , ByVal LogErrors As Boolean ) As CSong
'Exceptions due to old definitions:
Select Case Name . ToLower ( )
Case " welcome "
Name = " RouteMusic1 "
Case " battle "
Name = " johto_wild "
Case " battleintro " , " johto_battle_intro "
Name = " battle_intro "
Case " darkcave "
Name = " dark_cave "
Case " showmearound "
Name = " show_me_around "
Case " sprouttower "
Name = " sprout_tower "
Case " johto_rival_intro "
Name = " johto_rivalintro "
Case " johto_rival_appear "
Name = " johto_rival_encounter "
Case " ilex_forest " , " union_cave " , " mt_mortar " , " whirlpool_islands " , " tohjo_falls "
Name = " IlexForest "
End Select
If SongFiles . ContainsKey ( Name . ToLower ( ) ) = True Then
Return SongFiles ( Name . ToLower ( ) )
Else
If TryAddGameModeMusic ( Name ) = True Then
Return SongFiles ( Name . ToLower ( ) )
End If
If Name . ToLower ( ) <> " nomusic " Then
Logger . Log ( Logger . LogTypes . Warning , " MusicManager.vb: Cannot find music file "" " & Name & " "" . Return nothing. " )
End If
Return Nothing
End If
End Function
Private Shared Function TryAddGameModeMusic ( ByVal Name As String ) As Boolean
Dim musicfileXNB As String = GameController . GamePath & GameModeManager . ActiveGameMode . ContentPath & " Songs\ " & Name & " .xnb "
Dim musicfileMP3 As String = GameController . GamePath & GameModeManager . ActiveGameMode . ContentPath & " Songs\ " & Name & " .mp3 "
2017-07-25 09:45:18 +02:00
Dim musicfileOGG As String = GameController . GamePath & GameModeManager . ActiveGameMode . ContentPath & " Songs\ " & Name & " .ogg "
2018-02-21 16:34:06 +01:00
If System . IO . File . Exists ( musicfileXNB ) OrElse System . IO . File . Exists ( musicfileMP3 ) OrElse System . IO . File . Exists ( musicfileOGG ) Then
2016-09-07 18:50:38 +02:00
Return AddSong ( Name , False )
End If
Return False
End Function
Public Shared Sub LoadMusic ( ByVal forceReplace As Boolean )
MediaPlayer . IsRepeating = True
For Each musicFile As String In System . IO . Directory . GetFiles ( GameController . GamePath & " \Content\Songs\ " , " *.* " , IO . SearchOption . AllDirectories )
If musicFile . EndsWith ( " .xnb " ) = True Then
Dim isIntro As Boolean = False
If musicFile . Contains ( " \Songs\intro\ " ) = True Then
isIntro = True
End If
If isIntro = False Then
musicFile = System . IO . Path . GetFileNameWithoutExtension ( musicFile )
Else
musicFile = " intro\ " & System . IO . Path . GetFileNameWithoutExtension ( musicFile )
End If
AddSong ( musicFile , 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 & " \Songs\ "
If System . IO . Directory . Exists ( path ) = True Then
For Each musicFile As String In System . IO . Directory . GetFiles ( path , " *.* " , IO . SearchOption . AllDirectories )
If musicFile . EndsWith ( " .xnb " ) = True Then
Dim isIntro As Boolean = False
If musicFile . Contains ( " \Songs\intro\ " ) = True Then
isIntro = True
End If
If isIntro = False Then
musicFile = System . IO . Path . GetFileNameWithoutExtension ( musicFile )
Else
musicFile = " intro\ " & System . IO . Path . GetFileNameWithoutExtension ( musicFile )
End If
AddSong ( musicFile , forceReplace )
End If
Next
End If
Next
End If
End Sub
Private Shared SongExistFlag As Boolean = True
Public Shared Sub PlayMusic ( ByVal Song As String )
PlayMusic ( Song , 0 . 0F , 0 . 0F )
End Sub
Public Shared Sub PlayMusic ( ByVal Song As String , ByVal SearchForIntro As Boolean )
PlayMusic ( Song , SearchForIntro , 0 . 02F , 0 . 02F )
End Sub
Public Shared Sub PlayNoMusic ( )
MediaPlayer . Stop ( )
currentSong = " nomusic "
End Sub
2016-12-14 16:41:40 +01:00
Public Shared Sub IgnoreLastSong ( )
currentSong = " nomusic "
SongList . Add ( " nomusic " )
IntroStarted = False
End Sub
2016-09-07 18:50:38 +02:00
Public Shared Sub PlayMusic ( ByVal Song As String , ByVal SearchForIntro As Boolean , ByVal NewFadeInSpeed As Single , ByVal NewFadeOutSpeed As Single )
Dim lastSong As String = " nomusic "
If IntroStarted = True Then
lastSong = IntroContinue
Else
If SongList . Count > 0 Then
lastSong = SongList ( SongList . Count - 1 )
End If
End If
2016-10-17 05:41:19 +02:00
MediaPlayer . IsRepeating = True
2016-09-07 18:50:38 +02:00
If SearchForIntro = True And lastSong . ToLower ( ) <> Song . ToLower ( ) Then
If SongFiles . Keys . Contains ( " intro\ " & Song . ToLower ( ) ) = True Then
If SongFiles ( " intro\ " & Song . ToLower ( ) ) . Origin = SongFiles ( Song . ToLower ( ) ) . Origin Then
2018-01-07 18:01:32 +01:00
IntroEndTime = Date . Now . AddSeconds ( - 1 ) + SongFiles ( " intro\ " & Song . ToLower ( ) ) . Song . Duration
2016-09-07 18:50:38 +02:00
PlayMusic ( " intro\ " & Song . ToLower ( ) , NewFadeInSpeed , NewFadeOutSpeed )
2016-10-17 05:41:19 +02:00
MediaPlayer . IsRepeating = False
2016-09-07 18:50:38 +02:00
IntroContinue = Song
IntroStarted = True
If NewFadeInSpeed > 0 . 0F And NewFadeOutSpeed > 0 . 0F Then
FadeIntoIntro = True
End If
Else
FadeIntoIntro = False
PlayMusic ( Song , NewFadeInSpeed , NewFadeOutSpeed )
End If
Else
FadeIntoIntro = False
PlayMusic ( Song , NewFadeInSpeed , NewFadeOutSpeed )
End If
Else
If Not ( SearchForIntro = True And IntroStarted = True And IntroContinue . ToLower ( ) = Song . ToLower ( ) ) Then
FadeIntoIntro = False
PlayMusic ( Song , NewFadeInSpeed , NewFadeOutSpeed )
End If
End If
End Sub
Public Shared Sub PlayMusic ( ByVal Song As String , ByVal NewFadeInSpeed As Single , ByVal NewFadeOutSpeed As Single )
If FadeOut = True Then
If currentSong . ToLower ( ) = Song . ToLower ( ) And NextSong . ToLower ( ) <> Song . ToLower ( ) Then
NextSong = Song . ToLower ( )
Exit Sub
End If
End If
If currentSong = " " Or Song . ToLower ( ) <> currentSong . ToLower ( ) Then
If NewFadeInSpeed > 0 . 0F And NewFadeOutSpeed > 0 . 0F Then
If currentSong = " " Then
FadeInSpeed = NewFadeInSpeed
FadeIn = True
Volume = 0 . 0F
PlayTrack ( Song )
Else
NextSong = Song
FadeInSpeed = NewFadeInSpeed
FadeOutSpeed = NewFadeOutSpeed
FadeOut = True
FadeIn = False
End If
Else
Volume = 1 . 0F
FadeIn = False
FadeOut = False
PlayTrack ( Song )
End If
End If
End Sub
Private Shared Sub PlayTrack ( ByVal song As String )
Dim s As CSong = Nothing
s = GetSong ( song , True )
MediaPlayer . Stop ( )
Logger . Debug ( " Play [ " & song & " ] " )
IntroStarted = False
If Not s Is Nothing Then
2017-03-22 18:15:19 +01:00
MediaPlayer . Play ( s . Song )
2016-09-07 18:50:38 +02:00
If MediaPlayer . IsMuted = True Then
MediaPlayer . Pause ( )
End If
SongList . Add ( song )
SongExistFlag = True
Else
SongList . Add ( " " )
SongExistFlag = False
End If
currentSong = song
End Sub
Public Shared Sub Mute ( ByVal mute As Boolean )
If MediaPlayer . IsMuted <> mute Then
MediaPlayer . IsMuted = mute
If MediaPlayer . IsMuted = True Then
MediaPlayer . Pause ( )
Core . GameMessage . ShowMessage ( Localization . GetString ( " game_message_music_off " ) , 12 , FontManager . MainFont , Color . White )
Else
If SongExistFlag = True Then
MediaPlayer . Resume ( )
End If
Core . GameMessage . ShowMessage ( Localization . GetString ( " game_message_music_on " ) , 12 , FontManager . MainFont , Color . White )
End If
End If
End Sub
Public Shared Sub ReloadMusic ( )
SongFiles . Clear ( )
LoadMusic ( False )
End Sub
'Intro:
Shared StartTime As Date
Shared PausedForSound As Boolean = False
Shared IntroEndTime As Date
Shared IntroStarted As Boolean = False
Shared IntroContinue As String = " "
'Fading:
Shared NextSong As String
Shared FadeInSpeed As Single
Shared FadeOutSpeed As Single
Shared FadeOut As Boolean = False
Shared FadeIn As Boolean = False
Shared FadeIntoIntro As Boolean = False
Shared Volume As Single = 1 . 0F
Public Shared MasterVolume As Single = 1 . 0F 'Actual volume people can change
Public Shared Sub Update ( )
If PausedForSound = True Then
If Date . Now >= StartTime Then
PausedForSound = False
If MediaPlayer . IsMuted = False And SongExistFlag = True Then
MediaPlayer . Resume ( )
End If
End If
Else
UpdateFade ( )
If IntroStarted = True Then
If Date . Now >= IntroEndTime Then
2016-10-17 05:41:19 +02:00
PlayTrack ( IntroContinue ) 'Plays the loop that follows the intro
MediaPlayer . IsRepeating = True
2016-09-07 18:50:38 +02:00
End If
End If
End If
End Sub
Shared LastVolume As Single = - 1 . 0F
Private Shared Sub UpdateFade ( )
If FadeIn = True Then
Volume += FadeInSpeed
If Volume >= 1 . 0F Then
Volume = 1 . 0F
FadeIn = False
End If
End If
If FadeOut = True Then
Volume -= FadeOutSpeed
If Volume <= 0 . 0F Then
Volume = 0 . 0F
FadeOut = False
FadeIn = True
PlayTrack ( NextSong )
If FadeIntoIntro = True Then
IntroStarted = True
2018-01-07 18:01:32 +01:00
IntroEndTime = Date . Now . AddSeconds ( - 1 ) + SongFiles ( NextSong ) . Song . Duration
2016-09-07 18:50:38 +02:00
FadeIntoIntro = False
End If
currentSong = NextSong
NextSong = " "
End If
End If
If Core . GameInstance . IsActive = True And LastVolume <> ( Volume * MasterVolume ) Then
ForceVolumeUpdate ( )
End If
End Sub
Public Shared Sub PauseForSound ( ByVal s As SoundEffect )
StartTime = Date . Now + s . Duration
PausedForSound = True
MediaPlayer . Pause ( )
End Sub
Public Shared Sub StopMusic ( )
MediaPlayer . Stop ( )
IntroStarted = False
End Sub
Public Shared Sub Pause ( )
MediaPlayer . Pause ( )
IntroStarted = False
End Sub
Public Shared Sub ResumeMusic ( )
MediaPlayer . Resume ( )
End Sub
Public Shared ReadOnly Property GetCurrentSong ( ) As String
Get
Return SongList ( SongList . Count - 1 )
End Get
End Property
Public Shared Function SongExists ( ByVal songName As String ) As Boolean
Dim s As CSong = GetSong ( songName , False )
2018-01-07 18:01:32 +01:00
Return s IsNot Nothing
2016-09-07 18:50:38 +02:00
End Function
Public Shared Sub ForceVolumeUpdate ( )
MediaPlayer . Volume = Volume * MasterVolume
LastVolume = Volume * MasterVolume
End Sub
End Class