2018-11-22 16:40:13 -05:00
|
|
|
|
using OpenDiablo2.Common;
|
|
|
|
|
using OpenDiablo2.Common.Interfaces;
|
2018-11-22 00:18:42 -05:00
|
|
|
|
using OpenDiablo2.Common.Models;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace OpenDiablo2.Core
|
|
|
|
|
{
|
2018-11-22 20:23:00 -05:00
|
|
|
|
public sealed class GameEngine : IGameEngine, IPaletteProvider, ISceneManager
|
2018-11-22 00:18:42 -05:00
|
|
|
|
{
|
|
|
|
|
static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
|
|
|
|
|
|
private readonly IMPQProvider mpqProvider;
|
2018-11-22 14:30:37 -05:00
|
|
|
|
private readonly Func<IRenderWindow> getRenderWindow;
|
2018-11-22 16:40:13 -05:00
|
|
|
|
private readonly Func<IMouseInfoProvider> getMouseInfoProvider;
|
2018-11-22 00:18:42 -05:00
|
|
|
|
private readonly Func<string, IScene> getScene;
|
|
|
|
|
private IScene currentScene;
|
2018-11-22 20:23:00 -05:00
|
|
|
|
private IScene nextScene = null;
|
2018-11-22 16:40:13 -05:00
|
|
|
|
private ISprite mouseSprite;
|
2018-11-22 00:18:42 -05:00
|
|
|
|
|
|
|
|
|
private readonly MPQ[] MPQs;
|
|
|
|
|
|
|
|
|
|
private Dictionary<string, SoundEntry> soundTable = new Dictionary<string, SoundEntry>();
|
|
|
|
|
public Dictionary<string, Palette> PaletteTable { get; private set; } = new Dictionary<string, Palette>();
|
|
|
|
|
private Stopwatch sw = new Stopwatch();
|
|
|
|
|
|
|
|
|
|
|
2018-11-22 16:40:13 -05:00
|
|
|
|
public GameEngine(
|
|
|
|
|
IMPQProvider mpqProvider,
|
|
|
|
|
Func<IRenderWindow> getRenderWindow,
|
|
|
|
|
Func<IMouseInfoProvider> getMouseInfoProvider,
|
|
|
|
|
Func<string, IScene> getScene
|
|
|
|
|
)
|
2018-11-22 00:18:42 -05:00
|
|
|
|
{
|
|
|
|
|
this.mpqProvider = mpqProvider;
|
2018-11-22 14:30:37 -05:00
|
|
|
|
this.getRenderWindow = getRenderWindow;
|
2018-11-22 16:40:13 -05:00
|
|
|
|
this.getMouseInfoProvider = getMouseInfoProvider;
|
2018-11-22 00:18:42 -05:00
|
|
|
|
this.getScene = getScene;
|
|
|
|
|
|
|
|
|
|
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"));
|
|
|
|
|
foreach (var paletteFile in paletteFiles)
|
|
|
|
|
{
|
|
|
|
|
var paletteNameParts = paletteFile.Split('\\');
|
|
|
|
|
var paletteName = paletteNameParts[paletteNameParts.Count() - 2];
|
2018-11-22 16:22:39 -05:00
|
|
|
|
PaletteTable[paletteName] = Palette.LoadFromStream(mpqProvider.GetStream(paletteFile), paletteName);
|
2018-11-22 00:18:42 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LoadSoundData()
|
|
|
|
|
{
|
|
|
|
|
log.Info("Loading sound configuration data");
|
|
|
|
|
foreach (var soundDescFile in mpqProvider.GetTextFile("data\\global\\excel\\Sounds.txt"))
|
|
|
|
|
{
|
|
|
|
|
foreach (var row in soundDescFile.Skip(1).Where(x => !String.IsNullOrWhiteSpace(x)))
|
|
|
|
|
{
|
|
|
|
|
var soundEntry = row.ToSoundEntry();
|
|
|
|
|
soundTable[soundEntry.Handle] = soundEntry;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Run()
|
|
|
|
|
{
|
2018-11-22 16:40:13 -05:00
|
|
|
|
var renderWindow = getRenderWindow();
|
|
|
|
|
var mouseInfoProvider = getMouseInfoProvider();
|
|
|
|
|
|
2018-11-22 00:18:42 -05:00
|
|
|
|
LoadPalettes();
|
|
|
|
|
LoadSoundData();
|
|
|
|
|
|
2018-11-22 16:40:13 -05:00
|
|
|
|
mouseSprite = renderWindow.LoadSprite(ResourcePaths.CursorDefault, Palettes.Units);
|
|
|
|
|
|
2018-11-22 00:18:42 -05:00
|
|
|
|
currentScene = getScene("Main Menu");
|
|
|
|
|
sw.Start();
|
2018-11-22 14:30:37 -05:00
|
|
|
|
while (getRenderWindow().IsRunning)
|
2018-11-22 00:18:42 -05:00
|
|
|
|
{
|
|
|
|
|
while (sw.ElapsedMilliseconds < 16)
|
|
|
|
|
Thread.Sleep(1); // Oh yes we did
|
|
|
|
|
|
|
|
|
|
var ms = sw.ElapsedMilliseconds;
|
|
|
|
|
|
|
|
|
|
// Prevent falco-punch updates
|
|
|
|
|
if (ms > 1000)
|
|
|
|
|
{
|
|
|
|
|
sw.Restart();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
sw.Restart();
|
2018-11-22 14:30:37 -05:00
|
|
|
|
getRenderWindow().Update();
|
2018-11-22 00:18:42 -05:00
|
|
|
|
currentScene.Update(ms);
|
2018-11-22 20:23:00 -05:00
|
|
|
|
if (nextScene!= null)
|
|
|
|
|
{
|
|
|
|
|
currentScene.Dispose();
|
|
|
|
|
currentScene = nextScene;
|
|
|
|
|
nextScene = null;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2018-11-22 16:40:13 -05:00
|
|
|
|
|
|
|
|
|
renderWindow.Clear();
|
2018-11-22 00:18:42 -05:00
|
|
|
|
currentScene.Render();
|
2018-11-22 16:40:13 -05:00
|
|
|
|
|
|
|
|
|
// Draw the mouse
|
|
|
|
|
renderWindow.Draw(mouseSprite, new Point(mouseInfoProvider.MouseX, mouseInfoProvider.MouseY + 3));
|
|
|
|
|
|
|
|
|
|
renderWindow.Sync();
|
2018-11-22 00:18:42 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2018-11-22 20:23:00 -05:00
|
|
|
|
currentScene?.Dispose();
|
2018-11-22 00:18:42 -05:00
|
|
|
|
}
|
2018-11-22 20:23:00 -05:00
|
|
|
|
|
|
|
|
|
public void ChangeScene(string sceneName)
|
|
|
|
|
=> nextScene = getScene(sceneName);
|
2018-11-22 00:18:42 -05:00
|
|
|
|
}
|
|
|
|
|
}
|