#region Copyright & License Information /* * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, * see COPYING. */ #endregion using System; using System.IO; using System.Linq; using System.Threading; using OpenRA.FileFormats; using OpenRA.FileFormats.Graphics; using OpenRA.GameRules; using OpenRA.Traits; using OpenRA.Widgets; namespace OpenRA.Mods.Cnc.Widgets.Logic { public class CncMusicPlayerLogic { bool installed; MusicInfo currentSong = null; Widget panel; MusicInfo[] music; MusicInfo[] random; ScrollItemWidget itemTemplate; [ObjectCreator.UseCtor] public CncMusicPlayerLogic([ObjectCreator.Param] Widget widget, [ObjectCreator.Param] Action onExit) { panel = widget.GetWidget("MUSIC_PANEL"); var ml = panel.GetWidget("MUSIC_LIST"); itemTemplate = ml.GetWidget("MUSIC_TEMPLATE"); BuildMusicTable(ml); currentSong = Sound.CurrentMusic ?? GetNextSong(); installed = Rules.Music.Where(m => m.Value.Exists).Any(); Func noMusic = () => !installed; panel.GetWidget("BACK_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); }; Action afterInstall = () => { // Mount the new mixfile and rebuild the scores list try { var path = new string[] { Platform.SupportDir, "Content", "cnc" }.Aggregate(Path.Combine); FileSystem.Mount(Path.Combine(path, "scores.mix")); FileSystem.Mount(Path.Combine(path, "transit.mix")); Rules.Music.Do(m => m.Value.Reload()); } catch (Exception) { } installed = Rules.Music.Where(m => m.Value.Exists).Any(); BuildMusicTable(ml); }; var installButton = panel.GetWidget("INSTALL_BUTTON"); installButton.OnClick = () => Widget.OpenWindow("INSTALL_MUSIC_PANEL", new WidgetArgs() {{ "afterInstall", afterInstall }}); installButton.IsVisible = () => music.Length < 2; // Hack around ra shipping (only) hellmarch by default panel.GetWidget("NO_MUSIC_LABEL").IsVisible = noMusic; var playButton = panel.GetWidget("BUTTON_PLAY"); playButton.OnClick = Play; playButton.IsDisabled = noMusic; var pauseButton = panel.GetWidget("BUTTON_PAUSE"); pauseButton.OnClick = Pause; pauseButton.IsDisabled = noMusic; var stopButton = panel.GetWidget("BUTTON_STOP"); stopButton.OnClick = Stop; stopButton.IsDisabled = noMusic; var nextButton = panel.GetWidget("BUTTON_NEXT"); nextButton.OnClick = () => { currentSong = GetNextSong(); Play(); }; nextButton.IsDisabled = noMusic; var prevButton = panel.GetWidget("BUTTON_PREV"); prevButton.OnClick = () => { currentSong = GetPrevSong(); Play(); }; prevButton.IsDisabled = noMusic; var shuffleCheckbox = panel.GetWidget("SHUFFLE"); shuffleCheckbox.IsChecked = () => Game.Settings.Sound.Shuffle; shuffleCheckbox.OnClick = () => Game.Settings.Sound.Shuffle ^= true; var repeatCheckbox = panel.GetWidget("REPEAT"); repeatCheckbox.IsChecked = () => Game.Settings.Sound.Repeat; repeatCheckbox.OnClick = () => Game.Settings.Sound.Repeat ^= true; panel.GetWidget("TIME_LABEL").GetText = () => (currentSong == null) ? "" : "{0:D2}:{1:D2} / {2:D2}:{3:D2}".F((int)Sound.MusicSeekPosition / 60, (int)Sound.MusicSeekPosition % 60, currentSong.Length / 60, currentSong.Length % 60); panel.GetWidget("TITLE_LABEL").GetText = () => (currentSong == null) ? "" : currentSong.Title; var musicSlider = panel.GetWidget("MUSIC_SLIDER"); musicSlider.OnChange += x => Sound.MusicVolume = x; musicSlider.Value = Sound.MusicVolume; } void BuildMusicTable(Widget list) { music = Rules.Music.Where(a => a.Value.Exists).Select(a => a.Value).ToArray(); random = music.Shuffle(Game.CosmeticRandom).ToArray(); list.RemoveChildren(); foreach (var s in music) { var song = s; if (currentSong == null) currentSong = song; var item = ScrollItemWidget.Setup(itemTemplate, () => currentSong == song, () => { currentSong = song; Play(); }); item.GetWidget("TITLE").GetText = () => song.Title; item.GetWidget("LENGTH").GetText = () => SongLengthLabel(song); list.AddChild(item); } } void Play() { if (currentSong == null) return; Sound.PlayMusicThen(currentSong, () => { if (!Game.Settings.Sound.Repeat) currentSong = GetNextSong(); Play(); }); panel.GetWidget("BUTTON_PLAY").Visible = false; panel.GetWidget("BUTTON_PAUSE").Visible = true; } void Pause() { Sound.PauseMusic(); panel.GetWidget("BUTTON_PAUSE").Visible = false; panel.GetWidget("BUTTON_PLAY").Visible = true; } void Stop() { Sound.StopMusic(); panel.GetWidget("BUTTON_PAUSE").Visible = false; panel.GetWidget("BUTTON_PLAY").Visible = true; } string SongLengthLabel(MusicInfo song) { return "{0:D1}:{1:D2}".F(song.Length / 60, song.Length % 60); } MusicInfo GetNextSong() { if (!music.Any()) return null; var songs = Game.Settings.Sound.Shuffle ? random : music; return songs.SkipWhile(m => m != currentSong) .Skip(1).FirstOrDefault() ?? songs.FirstOrDefault(); } MusicInfo GetPrevSong() { if (!music.Any()) return null; var songs = Game.Settings.Sound.Shuffle ? random : music; return songs.Reverse().SkipWhile(m => m != currentSong) .Skip(1).FirstOrDefault() ?? songs.Reverse().FirstOrDefault(); } } public class CncInstallMusicLogic { Widget panel; ProgressBarWidget progressBar; LabelWidget statusLabel; Action afterInstall; ButtonWidget retryButton, backButton; Widget installingContainer, insertDiskContainer; [ObjectCreator.UseCtor] public CncInstallMusicLogic([ObjectCreator.Param] Widget widget, [ObjectCreator.Param] Action afterInstall) { this.afterInstall = afterInstall; panel = widget.GetWidget("INSTALL_MUSIC_PANEL"); progressBar = panel.GetWidget("PROGRESS_BAR"); statusLabel = panel.GetWidget("STATUS_LABEL"); backButton = panel.GetWidget("BACK_BUTTON"); backButton.OnClick = Widget.CloseWindow; retryButton = panel.GetWidget("RETRY_BUTTON"); retryButton.OnClick = CheckForDisk; installingContainer = panel.GetWidget("INSTALLING"); insertDiskContainer = panel.GetWidget("INSERT_DISK"); CheckForDisk(); } void CheckForDisk() { var path = InstallUtils.GetMountedDisk(new [] { "GDI95", "NOD95" }); if (path != null) Install(path); else { insertDiskContainer.IsVisible = () => true; installingContainer.IsVisible = () => false; } } void Install(string source) { backButton.IsDisabled = () => true; retryButton.IsDisabled = () => true; insertDiskContainer.IsVisible = () => false; installingContainer.IsVisible = () => true; var dest = new string[] { Platform.SupportDir, "Content", "cnc" }.Aggregate(Path.Combine); var copyFiles = new string[] { "SCORES.MIX" }; var extractPackage = "INSTALL/SETUP.Z"; var extractFiles = new string[] { "transit.mix" }; var installCounter = 0; var installTotal = copyFiles.Count() + extractFiles.Count(); var onProgress = (Action)(s => Game.RunAfterTick(() => { progressBar.Percentage = installCounter*100/installTotal; installCounter++; statusLabel.GetText = () => s; })); var onError = (Action)(s => Game.RunAfterTick(() => { statusLabel.GetText = () => "Error: "+s; backButton.IsDisabled = () => false; retryButton.IsDisabled = () => false; })); var t = new Thread( _ => { try { if (!InstallUtils.CopyFiles(source, copyFiles, dest, onProgress, onError)) return; if (!InstallUtils.ExtractFromPackage(source, extractPackage, extractFiles, dest, onProgress, onError)) return; Game.RunAfterTick(() => { Widget.CloseWindow(); afterInstall(); }); } catch { onError("Installation failed"); } }) { IsBackground = true }; t.Start(); } } }