Add project files.
This commit is contained in:
114
FreedomFighter/MusicManager.cs
Normal file
114
FreedomFighter/MusicManager.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework.Audio;
|
||||
using Microsoft.Xna.Framework.Media;
|
||||
|
||||
namespace FreedomFighter;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Playback position in seconds (original used this in the intro).</summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user