using System; using System.IO; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Media; namespace FreedomFighter; /// /// Replacement for TOmegaMusic: a flat list of "songs" where some entries are /// streamed music (mp3 via MediaPlayer) and some are sound effects (wav). /// Indices mirror OmegaMusic1.Songs in GameU.dfm. /// public class MusicManager { public class Entry { readonly MusicManager _mgr; public string Name = ""; public Song? Song; // streamed music public SoundEffect? Effect; // wav sfx public int Volume = 100; // 0..100, Omega convention public Entry(MusicManager mgr) => _mgr = mgr; public void Play() { if (Song != null) { MediaPlayer.Volume = Volume / 100f; MediaPlayer.Play(Song); _mgr._current = this; } else if (Effect != null) { Effect.Play(Volume / 100f, 0, 0); Volume = 100; // one-shot volume, like the original's per-play setting } } public void Stop() { if (Song != null && _mgr._current == this) { MediaPlayer.Stop(); _mgr._current = null; } } /// Playback position in seconds (original used this in the intro). public double Position => Song != null && _mgr._current == this ? MediaPlayer.PlayPosition.TotalSeconds : 0; } Entry? _current; public Entry[] Songs = []; public void Load(string contentDir) { MediaPlayer.IsRepeating = true; // OmegaMusic1.Loop was called every menu frame // Index order mirrors OmegaMusic1.Songs in GameU.dfm. // [1] 'Level test.mp3' is lost — Track06.mp3 substitutes. // [3] gameover was a MIDI (Nazi_Rap.mid); MonoGame has no MIDI playback, so it is silent. (string name, string? file)[] entries = [ ("level1", @"music\white light.mp3"), ("level2", @"music\Track06.mp3"), ("level3", @"music\G2 Final.mp3"), ("gameover", null), ("title", @"music\Main Menu 2.mp3"), ("fire1", @"sfx\fire1.wav"), ("reload", @"sfx\reload.wav"), ("thump", @"sfx\thump1.wav"), ("beep", @"sfx\beep.wav"), ("credits", @"music\G8 Final.mp3"), ("hit", @"sfx\hit4.wav"), ("explosion", @"sfx\explode2.wav"), ("level4", @"music\Thunderization.mp3"), ("missile", @"sfx\missile.wav"), ("intro", @"music\Intro.mp3"), ]; Songs = new Entry[entries.Length]; for (int i = 0; i < entries.Length; i++) { var e = new Entry(this) { Name = entries[i].name }; var file = entries[i].file; if (file != null) { string path = Path.Combine(contentDir, file); if (File.Exists(path)) { try { if (path.EndsWith(".wav", StringComparison.OrdinalIgnoreCase)) { using var fs = File.OpenRead(path); e.Effect = SoundEffect.FromStream(fs); } else { e.Song = Song.FromUri(entries[i].name, new Uri(path, UriKind.Absolute)); } } catch (Exception ex) { Console.WriteLine($"Audio load failed for {file}: {ex.Message}"); } } } Songs[i] = e; } } }