1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-09-06 19:44:15 -04:00
OpenDiablo2/OpenDiablo2.Core/GameEngine.cs

137 lines
4.6 KiB
C#
Raw Normal View History

using System;
2018-11-22 00:18:42 -05:00
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading;
using OpenDiablo2.Common;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Models;
2018-11-22 00:18:42 -05:00
namespace OpenDiablo2.Core
{
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;
private readonly Func<IRenderWindow> getRenderWindow;
private readonly Func<eSceneType, IScene> getScene;
private readonly Func<IResourceManager> getResourceManager;
private readonly Func<IGameState> getGameState;
2018-11-22 00:18:42 -05:00
private IScene currentScene;
private IScene nextScene = null;
2018-12-09 14:55:01 -05:00
2018-12-08 09:32:09 -05:00
private readonly Dictionary<string, SoundEntry> soundTable = new Dictionary<string, SoundEntry>();
2018-11-22 00:18:42 -05:00
public Dictionary<string, Palette> PaletteTable { get; private set; } = new Dictionary<string, Palette>();
public GameEngine(
IMPQProvider mpqProvider,
Func<IRenderWindow> getRenderWindow,
Func<eSceneType, IScene> getScene,
Func<IResourceManager> getResourceManager,
Func<IGameState> getGameState
)
2018-11-22 00:18:42 -05:00
{
this.mpqProvider = mpqProvider;
this.getRenderWindow = getRenderWindow;
2018-11-22 00:18:42 -05:00
this.getScene = getScene;
this.getResourceManager = getResourceManager;
this.getGameState = getGameState;
2018-11-22 00:18:42 -05:00
}
private void LoadPalettes()
{
log.Info("Loading palettes");
var paletteFiles = mpqProvider.SelectMany(x => x.Files).Where(x => x.StartsWith("data\\global\\palette\\") && x.EndsWith(".dat"));
2018-11-22 00:18:42 -05:00
foreach (var paletteFile in paletteFiles)
{
var paletteNameParts = paletteFile.Split('\\');
var paletteName = paletteNameParts[paletteNameParts.Count() - 2];
PaletteTable[paletteName] = getResourceManager().GetPalette(paletteFile);
2018-11-22 00:18:42 -05:00
}
}
private void LoadSoundData()
{
log.Info("Loading sound configuration data");
2018-11-24 17:54:15 -05:00
var soundDescFile = mpqProvider.GetTextFile("data\\global\\excel\\Sounds.txt");
foreach (var row in soundDescFile.Skip(1).Where(x => !String.IsNullOrWhiteSpace(x)))
2018-11-22 00:18:42 -05:00
{
2018-11-24 17:54:15 -05:00
var soundEntry = row.ToSoundEntry();
soundTable[soundEntry.Handle] = soundEntry;
2018-11-22 00:18:42 -05:00
}
2018-11-24 17:54:15 -05:00
2018-11-22 00:18:42 -05:00
}
public void Run()
{
var renderWindow = getRenderWindow();
2018-11-22 00:18:42 -05:00
LoadPalettes();
LoadSoundData();
2018-12-08 13:31:50 -05:00
var mouseSprite = renderWindow.LoadSprite(ResourcePaths.CursorDefault, Palettes.Units);
var cursor = renderWindow.LoadCursor(mouseSprite, 0, new Point(0, 3));
renderWindow.MouseCursor = cursor;
currentScene = getScene(eSceneType.MainMenu);
var lastTicks = renderWindow.GetTicks();
while (getRenderWindow().IsRunning)
2018-11-22 00:18:42 -05:00
{
var curTicks = renderWindow.GetTicks();
var ms = curTicks - lastTicks;
if (ms < 0)
continue;
if (ms < 40)
{
Thread.Sleep(40 - (int)ms); // Diablo 2 runs at 25FPS.
2018-12-09 14:55:01 -05:00
} else
{
log.Info($"Full frame time used - {ms} milliseconds to frame");
}
2018-11-22 00:18:42 -05:00
// Prevent falco-punch updates
if (ms > 1000)
{
lastTicks = renderWindow.GetTicks();
2018-11-22 00:18:42 -05:00
continue;
}
lastTicks = curTicks;
2018-12-01 00:00:17 -05:00
lock (getGameState().ThreadLocker)
{
2018-12-01 00:00:17 -05:00
getGameState().Update(ms);
getRenderWindow().Update();
currentScene.Update(ms);
2018-12-01 00:00:17 -05:00
if (nextScene!= null)
{
currentScene = nextScene;
nextScene = null;
continue;
}
2018-12-01 00:00:17 -05:00
renderWindow.Clear();
currentScene.Render();
renderWindow.Sync();
}
2018-11-22 00:18:42 -05:00
}
}
public void Dispose()
{
currentScene?.Dispose();
2018-11-22 00:18:42 -05:00
}
public void ChangeScene(eSceneType sceneType)
=> nextScene = getScene(sceneType);
2018-11-22 00:18:42 -05:00
}
}