diff --git a/OpenDiablo2.Common/Interfaces/Data/IMPQProvider.cs b/OpenDiablo2.Common/Interfaces/Data/IMPQProvider.cs index 0fda4891..17970d60 100644 --- a/OpenDiablo2.Common/Interfaces/Data/IMPQProvider.cs +++ b/OpenDiablo2.Common/Interfaces/Data/IMPQProvider.cs @@ -1,17 +1,29 @@ -using System; +/* OpenDiablo 2 - An open source re-implementation of Diablo 2 in C# + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using OpenDiablo2.Common.Models; using System.Collections.Generic; using System.IO; -using System.Threading.Tasks; -using OpenDiablo2.Common.Models; namespace OpenDiablo2.Common.Interfaces { - public interface IMPQProvider + public interface IMPQProvider : IEnumerable { - IEnumerable GetMPQs(); - IEnumerable GetTextFile(string fileName); + IEnumerable GetTextFile(string fileName); Stream GetStream(string fileName); byte[] GetBytes(string fileName); - void GetBytesAsync(string fileName, Action callback); } } diff --git a/OpenDiablo2.Core/GameEngine.cs b/OpenDiablo2.Core/GameEngine.cs index 07569686..45c9aa83 100644 --- a/OpenDiablo2.Core/GameEngine.cs +++ b/OpenDiablo2.Core/GameEngine.cs @@ -41,14 +41,12 @@ namespace OpenDiablo2.Core this.getScene = getScene; this.getResourceManager = getResourceManager; this.getGameState = getGameState; - - MPQs = mpqProvider.GetMPQs().ToArray(); } private void LoadPalettes() { log.Info("Loading palettes"); - var paletteFiles = MPQs.SelectMany(x => x.Files).Where(x => x.StartsWith("data\\global\\palette\\") && x.EndsWith(".dat")); + var paletteFiles = mpqProvider.SelectMany(x => x.Files).Where(x => x.StartsWith("data\\global\\palette\\") && x.EndsWith(".dat")); foreach (var paletteFile in paletteFiles) { var paletteNameParts = paletteFile.Split('\\'); diff --git a/OpenDiablo2.Core/MPQProvider.cs b/OpenDiablo2.Core/MPQProvider.cs index 3fe9ada1..77dfba03 100644 --- a/OpenDiablo2.Core/MPQProvider.cs +++ b/OpenDiablo2.Core/MPQProvider.cs @@ -1,23 +1,37 @@ -using OpenDiablo2.Common.Interfaces; +/* OpenDiablo 2 - An open source re-implementation of Diablo 2 in C# + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using OpenDiablo2.Common.Interfaces; using OpenDiablo2.Common.Models; -using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace OpenDiablo2.Core { public sealed class MPQProvider : IMPQProvider { - private readonly MPQ[] mpqs; + private readonly IList mpqs; private readonly Dictionary mpqLookup = new Dictionary(); public MPQProvider(GlobalConfiguration globalConfiguration) { // TODO: Make this less dumb. We need to an external file to configure mpq load order. - + this.mpqs = Directory .EnumerateFiles(globalConfiguration.BaseDataPath, "*.mpq") .Where(x => !Path.GetFileName(x).StartsWith("patch")) @@ -59,15 +73,15 @@ namespace OpenDiablo2.Core return result; } - public void GetBytesAsync(string fileName, Action callback) + public IEnumerator GetEnumerator() { - var stream = GetStream(fileName); - var result = new byte[stream.Length]; - stream.Read(result, 0, (int)stream.Length); - callback(result); + return mpqs.GetEnumerator(); } - public IEnumerable GetMPQs() => mpqs; + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } public Stream GetStream(string fileName) { @@ -77,10 +91,7 @@ namespace OpenDiablo2.Core return mpqs[mpqLookup[fileName.ToLower()]].OpenFile(fileName); } - public IEnumerable GetTextFile(string fileName) => new StreamReader(mpqs[mpqLookup[fileName.ToLower()]].OpenFile(fileName)).ReadToEnd().Split('\n'); - - } } diff --git a/OpenDiablo2.Scenes/SelectHeroClass.cs b/OpenDiablo2.Scenes/SelectHeroClass.cs index d59be1f6..301dae69 100644 --- a/OpenDiablo2.Scenes/SelectHeroClass.cs +++ b/OpenDiablo2.Scenes/SelectHeroClass.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; +using System.Threading.Tasks; using OpenDiablo2.Common; using OpenDiablo2.Common.Attributes; using OpenDiablo2.Common.Enums; @@ -51,9 +52,7 @@ namespace OpenDiablo2.Scenes private readonly ITextBox characterNameTextBox; private readonly Dictionary heroRenderInfo = new Dictionary(); - private byte[] sfxAmazonSelect, sfxAmazonDeselect, sfxAssassinSelect, sfxAssassinDeselect, sfxBarbarianSelect, sfxBarbarianDeselect, - sfxDruidSelect, sfxDruidDeselect, sfxNecromancerSelect, sfxNecromancerDeselect, sfxPaladinSelect, sfxPaladinDeselect, - sfxSorceressSelect, sfxSorceressDeselect; + private Dictionary sfxDictionary; public SelectHeroClass( IRenderWindow renderWindow, @@ -75,7 +74,7 @@ namespace OpenDiablo2.Scenes this.keyboardInfoProvider = keyboardInfoProvider; this.soundProvider = soundProvider; this.gameState = gameState; - + sfxDictionary = new Dictionary(); backgroundSprite = renderWindow.LoadSprite(ResourcePaths.CharacterSelectBackground, Palettes.Fechar); campfireSprite = renderWindow.LoadSprite(ResourcePaths.CharacterSelectCampfire, Palettes.Fechar, new Point(380, 335)); @@ -224,21 +223,23 @@ namespace OpenDiablo2.Scenes characterNameTextBox.Text = ""; characterNameTextBox.Location = new Point(320, 493); - mpqProvider.GetBytesAsync(ResourcePaths.SFXAmazonSelect, x => sfxAmazonSelect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXAmazonDeselect, x => sfxAmazonDeselect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXAssassinSelect, x => sfxAssassinSelect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXAssassinDeselect, x => sfxAssassinDeselect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXBarbarianSelect, x => sfxBarbarianSelect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXBarbarianDeselect, x => sfxBarbarianDeselect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXDruidSelect, x => sfxDruidSelect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXDruidDeselect, x => sfxDruidDeselect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXNecromancerSelect, x => sfxNecromancerSelect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXNecromancerDeselect, x => sfxNecromancerDeselect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXPaladinSelect, x => sfxPaladinSelect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXPaladinDeselect, x => sfxPaladinDeselect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXSorceressSelect, x => sfxSorceressSelect = x); - mpqProvider.GetBytesAsync(ResourcePaths.SFXSorceressDeselect, x => sfxSorceressDeselect = x); - + Parallel.ForEach(new[] + { + ResourcePaths.SFXAmazonSelect, + ResourcePaths.SFXAmazonDeselect, + ResourcePaths.SFXAssassinSelect, + ResourcePaths.SFXAssassinDeselect, + ResourcePaths.SFXBarbarianSelect, + ResourcePaths.SFXBarbarianDeselect, + ResourcePaths.SFXDruidSelect, + ResourcePaths.SFXDruidDeselect, + ResourcePaths.SFXNecromancerSelect, + ResourcePaths.SFXNecromancerDeselect, + ResourcePaths.SFXPaladinSelect, + ResourcePaths.SFXPaladinDeselect, + ResourcePaths.SFXSorceressSelect, + ResourcePaths.SFXSorceressDeselect + }, (path => sfxDictionary.Add(path, mpqProvider.GetBytes(path)))); } private void OnOkclicked() @@ -475,25 +476,25 @@ namespace OpenDiablo2.Scenes switch (hero) { case eHero.Barbarian: - soundProvider.PlaySfx(sfxBarbarianSelect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXBarbarianSelect]); break; case eHero.Necromancer: - soundProvider.PlaySfx(sfxNecromancerSelect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXNecromancerSelect]); break; case eHero.Paladin: - soundProvider.PlaySfx(sfxPaladinSelect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXPaladinSelect]); break; case eHero.Assassin: - soundProvider.PlaySfx(sfxAssassinSelect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXAssassinSelect]); break; case eHero.Sorceress: - soundProvider.PlaySfx(sfxSorceressSelect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXSorceressSelect]); break; case eHero.Amazon: - soundProvider.PlaySfx(sfxAmazonSelect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXAmazonSelect]); break; case eHero.Druid: - soundProvider.PlaySfx(sfxDruidSelect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXDruidSelect]); break; default: break; @@ -505,25 +506,25 @@ namespace OpenDiablo2.Scenes switch (hero) { case eHero.Barbarian: - soundProvider.PlaySfx(sfxBarbarianDeselect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXBarbarianDeselect]); break; case eHero.Necromancer: - soundProvider.PlaySfx(sfxNecromancerDeselect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXNecromancerDeselect]); break; case eHero.Paladin: - soundProvider.PlaySfx(sfxPaladinDeselect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXPaladinDeselect]); break; case eHero.Assassin: - soundProvider.PlaySfx(sfxAssassinDeselect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXAssassinDeselect]); break; case eHero.Sorceress: - soundProvider.PlaySfx(sfxSorceressDeselect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXSorceressDeselect]); break; case eHero.Amazon: - soundProvider.PlaySfx(sfxAmazonDeselect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXAmazonDeselect]); break; case eHero.Druid: - soundProvider.PlaySfx(sfxDruidDeselect); + soundProvider.PlaySfx(sfxDictionary[ResourcePaths.SFXDruidDeselect]); break; default: break;