1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-27 09:35:29 +00:00

Added resource manager. Working on weird memory and performance things.

This commit is contained in:
Tim Sarbin 2018-11-22 22:53:05 -05:00
parent fcc3293aad
commit 245eabe4c2
21 changed files with 252 additions and 67 deletions

View File

@ -0,0 +1,8 @@
namespace OpenDiablo2.Common.Enums
{
public enum eButtonType
{
Wide,
Cancel
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenDiablo2.Common.Models;
namespace OpenDiablo2.Common.Interfaces
{
public interface IResourceManager
{
ImageSet GetImageSet(string resourcePath);
MPQFont GetMPQFont(string resourcePath);
Palette GetPalette(string paletteName);
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenDiablo2.Common.Enums;
namespace OpenDiablo2.Common.Models
{
public class ButtonLayout
{
public int XSegments { get; internal set; }
public string ResourceName { get; internal set; }
public string PaletteName { get; internal set; }
public static Dictionary<eButtonType, ButtonLayout> Values = new Dictionary<eButtonType, ButtonLayout>
{
{eButtonType.Wide, new ButtonLayout { XSegments = 2, ResourceName = ResourcePaths.WideButtonBlank, PaletteName = Palettes.Units } },
{eButtonType.Cancel, new ButtonLayout {XSegments = 1,ResourceName = ResourcePaths.CancelButton,PaletteName = Palettes.Units } }
};
}
}

View File

@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace OpenDiablo2.Common.Models namespace OpenDiablo2.Common.Models
{ {
public class ImageFrame public class ImageFrame : IDisposable
{ {
public UInt32 Flip; public UInt32 Flip;
public UInt32 Width; public UInt32 Width;
@ -21,6 +21,11 @@ namespace OpenDiablo2.Common.Models
public UInt32 Length; public UInt32 Length;
public Int16[,] ImageData; public Int16[,] ImageData;
public void Dispose()
{
ImageData = new Int16[0, 0];
}
public Color GetColor(int x, int y, Palette palette) public Color GetColor(int x, int y, Palette palette)
{ {
var index = ImageData[x, y]; var index = ImageData[x, y];
@ -33,7 +38,7 @@ namespace OpenDiablo2.Common.Models
} }
} }
public sealed class ImageSet public sealed class ImageSet : IDisposable
{ {
static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
@ -112,7 +117,6 @@ namespace OpenDiablo2.Common.Models
continue; continue;
} }
for (int p = 0; p < b; p++) for (int p = 0; p < b; p++)
{ {
result.Frames[i].ImageData[x++, y] = br.ReadByte(); result.Frames[i].ImageData[x++, y] = br.ReadByte();
@ -122,5 +126,9 @@ namespace OpenDiablo2.Common.Models
} }
return result; return result;
} }
public void Dispose()
{
}
} }
} }

View File

@ -85,16 +85,18 @@ namespace OpenDiablo2.Common.Models
private List<string> GetFilePaths() private List<string> GetFilePaths()
{ {
var stream = OpenFile("(listfile)"); using (var stream = OpenFile("(listfile)"))
if (stream == null)
{ {
return new List<string>(); if (stream == null)
{
return new List<string>();
}
var sr = new StreamReader(stream);
var text = sr.ReadToEnd();
return text.Split('\n').Where(x => !String.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).ToList();
} }
var sr = new StreamReader(stream);
var text = sr.ReadToEnd();
return text.Split('\n').Where(x => !String.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).ToList();
} }
static MPQ() static MPQ()

View File

@ -70,6 +70,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Attributes\SceneAttribute.cs" /> <Compile Include="Attributes\SceneAttribute.cs" />
<Compile Include="Enums\eButtonType.cs" />
<Compile Include="Enums\eMPQFormatVersion.cs" /> <Compile Include="Enums\eMPQFormatVersion.cs" />
<Compile Include="Interfaces\IFont.cs" /> <Compile Include="Interfaces\IFont.cs" />
<Compile Include="Interfaces\IGameEngine.cs" /> <Compile Include="Interfaces\IGameEngine.cs" />
@ -79,12 +80,14 @@
<Compile Include="Interfaces\IPaletteProvider.cs" /> <Compile Include="Interfaces\IPaletteProvider.cs" />
<Compile Include="Interfaces\IRenderTarget.cs" /> <Compile Include="Interfaces\IRenderTarget.cs" />
<Compile Include="Interfaces\IRenderWindow.cs" /> <Compile Include="Interfaces\IRenderWindow.cs" />
<Compile Include="Interfaces\IResourceManager.cs" />
<Compile Include="Interfaces\IScene.cs" /> <Compile Include="Interfaces\IScene.cs" />
<Compile Include="Interfaces\ISceneManager.cs" /> <Compile Include="Interfaces\ISceneManager.cs" />
<Compile Include="Interfaces\ISprite.cs" /> <Compile Include="Interfaces\ISprite.cs" />
<Compile Include="Interfaces\IMouseInfoProvider.cs" /> <Compile Include="Interfaces\IMouseInfoProvider.cs" />
<Compile Include="Interfaces\ITextLabel.cs" /> <Compile Include="Interfaces\ITextLabel.cs" />
<Compile Include="Models\BitStream.cs" /> <Compile Include="Models\BitStream.cs" />
<Compile Include="Models\ButtonLayout.cs" />
<Compile Include="Models\MPQFont.cs" /> <Compile Include="Models\MPQFont.cs" />
<Compile Include="Models\GlobalConfiguration.cs" /> <Compile Include="Models\GlobalConfiguration.cs" />
<Compile Include="Models\ImageSet.cs" /> <Compile Include="Models\ImageSet.cs" />

View File

@ -40,6 +40,7 @@ namespace OpenDiablo2.Common
// --- UI --- // --- UI ---
public static string WideButtonBlank = "data\\global\\ui\\FrontEnd\\WideButtonBlank.dc6"; public static string WideButtonBlank = "data\\global\\ui\\FrontEnd\\WideButtonBlank.dc6";
public static string CancelButton = "data\\global\\ui\\FrontEnd\\CancelButtonBlank.dc6";
} }
} }

View File

@ -19,8 +19,9 @@ namespace OpenDiablo2.Core
builder.RegisterType<GameEngine>().AsImplementedInterfaces().SingleInstance(); builder.RegisterType<GameEngine>().AsImplementedInterfaces().SingleInstance();
builder.RegisterType<MPQProvider>().As<IMPQProvider>().SingleInstance(); builder.RegisterType<MPQProvider>().As<IMPQProvider>().SingleInstance();
builder.RegisterType<ResourceManager>().As<IResourceManager>().SingleInstance();
builder.RegisterType<WideButton>().AsSelf().InstancePerDependency(); builder.RegisterType<Button>().AsSelf().InstancePerDependency();
} }
} }
} }

View File

@ -20,6 +20,8 @@ namespace OpenDiablo2.Core
private readonly Func<IRenderWindow> getRenderWindow; private readonly Func<IRenderWindow> getRenderWindow;
private readonly Func<IMouseInfoProvider> getMouseInfoProvider; private readonly Func<IMouseInfoProvider> getMouseInfoProvider;
private readonly Func<string, IScene> getScene; private readonly Func<string, IScene> getScene;
private readonly Func<IResourceManager> getResourceManager;
private IScene currentScene; private IScene currentScene;
private IScene nextScene = null; private IScene nextScene = null;
private ISprite mouseSprite; private ISprite mouseSprite;
@ -35,13 +37,15 @@ namespace OpenDiablo2.Core
IMPQProvider mpqProvider, IMPQProvider mpqProvider,
Func<IRenderWindow> getRenderWindow, Func<IRenderWindow> getRenderWindow,
Func<IMouseInfoProvider> getMouseInfoProvider, Func<IMouseInfoProvider> getMouseInfoProvider,
Func<string, IScene> getScene Func<string, IScene> getScene,
Func<IResourceManager> getResourceManager
) )
{ {
this.mpqProvider = mpqProvider; this.mpqProvider = mpqProvider;
this.getRenderWindow = getRenderWindow; this.getRenderWindow = getRenderWindow;
this.getMouseInfoProvider = getMouseInfoProvider; this.getMouseInfoProvider = getMouseInfoProvider;
this.getScene = getScene; this.getScene = getScene;
this.getResourceManager = getResourceManager;
MPQs = mpqProvider.GetMPQs().ToArray(); MPQs = mpqProvider.GetMPQs().ToArray();
} }
@ -54,7 +58,7 @@ namespace OpenDiablo2.Core
{ {
var paletteNameParts = paletteFile.Split('\\'); var paletteNameParts = paletteFile.Split('\\');
var paletteName = paletteNameParts[paletteNameParts.Count() - 2]; var paletteName = paletteNameParts[paletteNameParts.Count() - 2];
PaletteTable[paletteName] = Palette.LoadFromStream(mpqProvider.GetStream(paletteFile), paletteName); PaletteTable[paletteName] = getResourceManager().GetPalette(paletteFile);
} }
} }
@ -81,6 +85,8 @@ namespace OpenDiablo2.Core
mouseSprite = renderWindow.LoadSprite(ResourcePaths.CursorDefault, Palettes.Units); mouseSprite = renderWindow.LoadSprite(ResourcePaths.CursorDefault, Palettes.Units);
currentScene = getScene("Main Menu"); currentScene = getScene("Main Menu");
sw.Start(); sw.Start();
while (getRenderWindow().IsRunning) while (getRenderWindow().IsRunning)
@ -101,7 +107,6 @@ namespace OpenDiablo2.Core
currentScene.Update(ms); currentScene.Update(ms);
if (nextScene!= null) if (nextScene!= null)
{ {
currentScene.Dispose();
currentScene = nextScene; currentScene = nextScene;
nextScene = null; nextScene = null;
continue; continue;

View File

@ -76,7 +76,8 @@
<Compile Include="GameEngine.cs" /> <Compile Include="GameEngine.cs" />
<Compile Include="MPQProvider.cs" /> <Compile Include="MPQProvider.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI\WideButton.cs" /> <Compile Include="ResourceManager.cs" />
<Compile Include="UI\Button.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\OpenDiablo2.Common\OpenDiablo2.Common.csproj"> <ProjectReference Include="..\OpenDiablo2.Common\OpenDiablo2.Common.csproj">

View File

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Models;
namespace OpenDiablo2.Core
{
public sealed class ResourceManager : IResourceManager
{
private readonly IMPQProvider mpqProvider;
private Dictionary<string, ImageSet> ImageSets = new Dictionary<string, ImageSet>();
private Dictionary<string, MPQFont> MPQFonts = new Dictionary<string, MPQFont>();
private Dictionary<string, Palette> Palettes = new Dictionary<string, Palette>();
public ResourceManager(IMPQProvider mpqProvider)
{
this.mpqProvider = mpqProvider;
}
public ImageSet GetImageSet(string resourcePath)
{
if (!ImageSets.ContainsKey(resourcePath))
ImageSets[resourcePath] = ImageSet.LoadFromStream(mpqProvider.GetStream(resourcePath));
return ImageSets[resourcePath];
}
public MPQFont GetMPQFont(string resourcePath)
{
if (!MPQFonts.ContainsKey(resourcePath))
MPQFonts[resourcePath] = MPQFont.LoadFromStream(mpqProvider.GetStream($"{resourcePath}.DC6"), mpqProvider.GetStream($"{resourcePath}.tbl"));
return MPQFonts[resourcePath];
}
public Palette GetPalette(string paletteFile)
{
if (!Palettes.ContainsKey(paletteFile))
{
var paletteNameParts = paletteFile.Split('\\');
var paletteName = paletteNameParts[paletteNameParts.Count() - 2];
Palettes[paletteFile] = Palette.LoadFromStream(mpqProvider.GetStream(paletteFile), paletteName);
}
return Palettes[paletteFile];
}
}
}

View File

@ -1,5 +1,6 @@
using OpenDiablo2.Common; using OpenDiablo2.Common;
using OpenDiablo2.Common.Interfaces; using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
@ -9,10 +10,13 @@ using System.Threading.Tasks;
namespace OpenDiablo2.Core.UI namespace OpenDiablo2.Core.UI
{ {
public sealed class WideButton
public sealed class Button : IDisposable
{ {
private readonly IMouseInfoProvider mouseInfoProvider; private readonly IMouseInfoProvider mouseInfoProvider;
private readonly IRenderWindow renderWindow; private readonly IRenderWindow renderWindow;
private readonly ButtonLayout buttonLayout;
public delegate void OnActivateDelegate(); public delegate void OnActivateDelegate();
public OnActivateDelegate OnActivate { get; set; } public OnActivateDelegate OnActivate { get; set; }
@ -28,7 +32,7 @@ namespace OpenDiablo2.Core.UI
} }
} }
private readonly int buttonWidth, buttonHeight; private int buttonWidth, buttonHeight;
private ISprite sprite; private ISprite sprite;
private IFont font; private IFont font;
private ILabel label; private ILabel label;
@ -36,7 +40,7 @@ namespace OpenDiablo2.Core.UI
private bool active = false; // When true, button is actively being focus pressed private bool active = false; // When true, button is actively being focus pressed
private bool activeLock = false; // When true, something else is being pressed so ignore everything private bool activeLock = false; // When true, something else is being pressed so ignore everything
private Point labelOffset = new Point(); private Point labelOffset = new Point();
private string text; private string text;
public string Text public string Text
{ {
@ -48,22 +52,32 @@ namespace OpenDiablo2.Core.UI
} }
} }
public WideButton(IRenderWindow renderWindow, IMouseInfoProvider mouseInfoProvider)
public Button(
ButtonLayout buttonLayout,
IRenderWindow renderWindow,
IMouseInfoProvider mouseInfoProvider
)
{ {
this.buttonLayout = buttonLayout;
this.renderWindow = renderWindow; this.renderWindow = renderWindow;
this.mouseInfoProvider = mouseInfoProvider; this.mouseInfoProvider = mouseInfoProvider;
sprite = renderWindow.LoadSprite(ResourcePaths.WideButtonBlank, Palettes.Units);
font = renderWindow.LoadFont(ResourcePaths.FontExocet10, Palettes.Units); font = renderWindow.LoadFont(ResourcePaths.FontExocet10, Palettes.Units);
label = renderWindow.CreateLabel(font); label = renderWindow.CreateLabel(font);
// TODO: Less stupid way of doing this would be nice
sprite.Frame = 0;
buttonWidth = sprite.LocalFrameSize.Width;
buttonHeight = sprite.LocalFrameSize.Height;
sprite.Frame = 1;
buttonWidth += sprite.LocalFrameSize.Width;
sprite = renderWindow.LoadSprite(buttonLayout.ResourceName, buttonLayout.PaletteName);
// TODO: Less stupid way of doing this would be nice
buttonWidth = 0;
buttonHeight = 0;
for (int i = 0; i < buttonLayout.XSegments; i++)
{
sprite.Frame = i;
buttonWidth += sprite.LocalFrameSize.Width;
buttonHeight = Math.Max(buttonHeight, sprite.LocalFrameSize.Height);
}
} }
public void Update() public void Update()
@ -101,7 +115,7 @@ namespace OpenDiablo2.Core.UI
public void Render() public void Render()
{ {
renderWindow.Draw(sprite, 2, 1, pressed ? 1 : 0); renderWindow.Draw(sprite, buttonLayout.XSegments, 1, pressed ? 1 : 0);
var offset = pressed ? -3 : 0; var offset = pressed ? -3 : 0;
label.Location = new Point(location.X + offset + labelOffset.X, location.Y - offset + labelOffset.Y); label.Location = new Point(location.X + offset + labelOffset.X, location.Y - offset + labelOffset.Y);
@ -116,5 +130,12 @@ namespace OpenDiablo2.Core.UI
var offsetX = (buttonWidth / 2) - (label.TextArea.Width / 2); var offsetX = (buttonWidth / 2) - (label.TextArea.Width / 2);
labelOffset = new Point(offsetX, -5); labelOffset = new Point(offsetX, -5);
} }
}
public void Dispose()
{
sprite.Dispose();
font.Dispose();
label.Dispose();
}
}
} }

View File

@ -12,6 +12,8 @@ namespace OpenDiablo2.SDL2_
{ {
internal sealed class SDL2Label : ILabel internal sealed class SDL2Label : ILabel
{ {
static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private readonly SDL2Font font; private readonly SDL2Font font;
private readonly IntPtr renderer; private readonly IntPtr renderer;
internal IntPtr texture; internal IntPtr texture;

View File

@ -27,14 +27,17 @@ namespace OpenDiablo2.SDL2_
private readonly IMPQProvider mpqProvider; private readonly IMPQProvider mpqProvider;
private readonly IPaletteProvider paletteProvider; private readonly IPaletteProvider paletteProvider;
private readonly IResourceManager resourceManager;
public SDL2RenderWindow( public SDL2RenderWindow(
IMPQProvider mpqProvider, IMPQProvider mpqProvider,
IPaletteProvider paletteProvider IPaletteProvider paletteProvider,
IResourceManager resourceManager
) )
{ {
this.mpqProvider = mpqProvider; this.mpqProvider = mpqProvider;
this.paletteProvider = paletteProvider; this.paletteProvider = paletteProvider;
this.resourceManager = resourceManager;
SDL.SDL_Init(SDL.SDL_INIT_EVERYTHING); SDL.SDL_Init(SDL.SDL_INIT_EVERYTHING);
if (SDL.SDL_SetHint(SDL.SDL_HINT_RENDER_SCALE_QUALITY, "0") == SDL.SDL_bool.SDL_FALSE) if (SDL.SDL_SetHint(SDL.SDL_HINT_RENDER_SCALE_QUALITY, "0") == SDL.SDL_bool.SDL_FALSE)
@ -178,7 +181,7 @@ namespace OpenDiablo2.SDL2_
public ISprite LoadSprite(string resourcePath, string palette) => LoadSprite(resourcePath, palette, Point.Empty); public ISprite LoadSprite(string resourcePath, string palette) => LoadSprite(resourcePath, palette, Point.Empty);
public ISprite LoadSprite(string resourcePath, string palette, Point location) public ISprite LoadSprite(string resourcePath, string palette, Point location)
{ {
var result = new SDL2Sprite(ImageSet.LoadFromStream(mpqProvider.GetStream(resourcePath)), renderer) var result = new SDL2Sprite(resourceManager.GetImageSet(resourcePath), renderer)
{ {
CurrentPalette = paletteProvider.PaletteTable[palette], CurrentPalette = paletteProvider.PaletteTable[palette],
Location = location Location = location
@ -188,7 +191,7 @@ namespace OpenDiablo2.SDL2_
public IFont LoadFont(string resourcePath, string palette) public IFont LoadFont(string resourcePath, string palette)
{ {
var result = new SDL2Font(MPQFont.LoadFromStream(mpqProvider.GetStream($"{resourcePath}.DC6"), mpqProvider.GetStream($"{resourcePath}.tbl")), renderer) var result = new SDL2Font(resourceManager.GetMPQFont(resourcePath), renderer)
{ {
CurrentPalette = paletteProvider.PaletteTable[palette] CurrentPalette = paletteProvider.PaletteTable[palette]
}; };

View File

@ -134,7 +134,6 @@ namespace OpenDiablo2.SDL2_
{ {
SDL.SDL_DestroyTexture(texture); SDL.SDL_DestroyTexture(texture);
} }
textures = new IntPtr[0];
} }
} }
} }

View File

@ -1,11 +1,7 @@
using Autofac; using System.Linq;
using Autofac;
using OpenDiablo2.Common.Attributes; using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Interfaces; using OpenDiablo2.Common.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OpenDiablo2.Scenes namespace OpenDiablo2.Scenes
{ {
@ -24,7 +20,7 @@ namespace OpenDiablo2.Scenes
builder builder
.RegisterType(type) .RegisterType(type)
.Keyed<IScene>(att.SceneName) .Keyed<IScene>(att.SceneName)
.InstancePerDependency(); .SingleInstance();
} }
} }
} }

View File

@ -1,5 +1,6 @@
using OpenDiablo2.Common; using OpenDiablo2.Common;
using OpenDiablo2.Common.Attributes; using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces; using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Models; using OpenDiablo2.Common.Models;
using OpenDiablo2.Core.UI; using OpenDiablo2.Core.UI;
@ -29,7 +30,7 @@ namespace OpenDiablo2.Scenes
private ISprite backgroundSprite, diabloLogoLeft, diabloLogoRight, diabloLogoLeftBlack, diabloLogoRightBlack; private ISprite backgroundSprite, diabloLogoLeft, diabloLogoRight, diabloLogoLeftBlack, diabloLogoRightBlack;
private IFont labelFont; private IFont labelFont;
private ILabel versionLabel, urlLabel; private ILabel versionLabel, urlLabel;
private WideButton btnSinglePlayer, btnExit, btnWebsite; private Button btnSinglePlayer, btnExit, btnWebsite;
public MainMenu( public MainMenu(
IRenderWindow renderWindow, IRenderWindow renderWindow,
@ -38,7 +39,7 @@ namespace OpenDiablo2.Scenes
IMouseInfoProvider mouseInfoProvider, IMouseInfoProvider mouseInfoProvider,
IMusicProvider musicProvider, IMusicProvider musicProvider,
ISceneManager sceneManager, ISceneManager sceneManager,
Func<WideButton> createWideButton Func<eButtonType, Button> createButton
) )
{ {
this.renderWindow = renderWindow; this.renderWindow = renderWindow;
@ -55,17 +56,17 @@ namespace OpenDiablo2.Scenes
diabloLogoLeftBlack = renderWindow.LoadSprite(ResourcePaths.Diablo2LogoBlackLeft, Palettes.Units, new Point(400, 120)); diabloLogoLeftBlack = renderWindow.LoadSprite(ResourcePaths.Diablo2LogoBlackLeft, Palettes.Units, new Point(400, 120));
diabloLogoRightBlack = renderWindow.LoadSprite(ResourcePaths.Diablo2LogoBlackRight, Palettes.Units, new Point(400, 120)); diabloLogoRightBlack = renderWindow.LoadSprite(ResourcePaths.Diablo2LogoBlackRight, Palettes.Units, new Point(400, 120));
btnSinglePlayer = createWideButton(); btnSinglePlayer = createButton(eButtonType.Wide);
btnSinglePlayer.Text = "Single Player".ToUpper(); btnSinglePlayer.Text = "Single Player".ToUpper();
btnSinglePlayer.Location = new Point(264, 290); btnSinglePlayer.Location = new Point(264, 290);
btnSinglePlayer.OnActivate = OnSinglePlayerClicked; btnSinglePlayer.OnActivate = OnSinglePlayerClicked;
btnWebsite = createWideButton(); btnWebsite = createButton(eButtonType.Wide);
btnWebsite.Text = "Visible Github".ToUpper(); btnWebsite.Text = "Visit Github".ToUpper();
btnWebsite.Location = new Point(264, 460); btnWebsite.Location = new Point(264, 460);
btnWebsite.OnActivate = OnVisitWebsiteClicked; btnWebsite.OnActivate = OnVisitWebsiteClicked;
btnExit = createWideButton(); btnExit = createButton(eButtonType.Wide);
btnExit.Text = "Exit Diablo II".ToUpper(); btnExit.Text = "Exit Diablo II".ToUpper();
btnExit.Location = new Point(264, 500); btnExit.Location = new Point(264, 500);
btnExit.OnActivate = OnExitClicked; btnExit.OnActivate = OnExitClicked;
@ -142,7 +143,17 @@ namespace OpenDiablo2.Scenes
public void Dispose() public void Dispose()
{ {
backgroundSprite.Dispose();
diabloLogoLeft.Dispose();
diabloLogoRight.Dispose();
diabloLogoLeftBlack.Dispose();
diabloLogoRightBlack.Dispose();
labelFont.Dispose();
versionLabel.Dispose();
urlLabel.Dispose();
btnSinglePlayer.Dispose();
btnExit.Dispose();
btnWebsite.Dispose();
} }
private void OnSinglePlayerClicked() private void OnSinglePlayerClicked()

View File

@ -5,7 +5,9 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using OpenDiablo2.Common; using OpenDiablo2.Common;
using OpenDiablo2.Common.Attributes; using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces; using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Core.UI;
namespace OpenDiablo2.Scenes namespace OpenDiablo2.Scenes
{ {
@ -25,6 +27,7 @@ namespace OpenDiablo2.Scenes
private ISprite backgroundSprite, campfireSprite; private ISprite backgroundSprite, campfireSprite;
private IFont headingFont; private IFont headingFont;
private ILabel headingLabel; private ILabel headingLabel;
private Button exitButton;
public SelectHeroClass( public SelectHeroClass(
IRenderWindow renderWindow, IRenderWindow renderWindow,
@ -32,7 +35,8 @@ namespace OpenDiablo2.Scenes
IMPQProvider mpqProvider, IMPQProvider mpqProvider,
IMouseInfoProvider mouseInfoProvider, IMouseInfoProvider mouseInfoProvider,
IMusicProvider musicProvider, IMusicProvider musicProvider,
ISceneManager sceneManager ISceneManager sceneManager,
Func<eButtonType, Button> createButton
) )
{ {
this.renderWindow = renderWindow; this.renderWindow = renderWindow;
@ -49,14 +53,23 @@ namespace OpenDiablo2.Scenes
headingLabel.Text = "Select Hero Class"; headingLabel.Text = "Select Hero Class";
headingLabel.Location = new System.Drawing.Point(400 - (headingLabel.TextArea.Width / 2), 20); headingLabel.Location = new System.Drawing.Point(400 - (headingLabel.TextArea.Width / 2), 20);
exitButton = createButton(eButtonType.Cancel);
exitButton.Text = "EXIT";
exitButton.Location = new System.Drawing.Point(30, 550);
exitButton.OnActivate = OnExitClicked;
}
private void OnExitClicked()
{
sceneManager.ChangeScene("Main Menu");
} }
public void Render() public void Render()
{ {
renderWindow.Draw(backgroundSprite, 4, 3, 0); renderWindow.Draw(backgroundSprite, 4, 3, 0);
renderWindow.Draw(campfireSprite, (int)(campfireSprite.TotalFrames * secondTimer)); renderWindow.Draw(campfireSprite, (int)(campfireSprite.TotalFrames * secondTimer));
//renderWindow.Draw(headingLabel); renderWindow.Draw(headingLabel);
exitButton.Render();
} }
public void Update(long ms) public void Update(long ms)
@ -66,11 +79,15 @@ namespace OpenDiablo2.Scenes
while (secondTimer >= 1f) while (secondTimer >= 1f)
secondTimer -= 1f; secondTimer -= 1f;
exitButton.Update();
} }
public void Dispose() public void Dispose()
{ {
backgroundSprite.Dispose();
campfireSprite.Dispose();
headingFont.Dispose();
headingLabel.Dispose();
} }
} }
} }

View File

@ -46,4 +46,10 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {782826E1-7E8E-4878-88FB-1B564D82C621} SolutionGuid = {782826E1-7E8E-4878-88FB-1B564D82C621}
EndGlobalSection EndGlobalSection
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
EndGlobal EndGlobal

View File

@ -5,7 +5,7 @@
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2B0CF1AC-06DD-4322-AE8B-FF8A8C70A3CD}</ProjectGuid> <ProjectGuid>{2B0CF1AC-06DD-4322-AE8B-FF8A8C70A3CD}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>WinExe</OutputType>
<RootNamespace>OpenDiablo2</RootNamespace> <RootNamespace>OpenDiablo2</RootNamespace>
<AssemblyName>OpenDiablo2</AssemblyName> <AssemblyName>OpenDiablo2</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
@ -52,6 +52,9 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit> <Prefer32Bit>true</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Autofac, Version=4.8.1.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL"> <Reference Include="Autofac, Version=4.8.1.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.4.8.1\lib\net45\Autofac.dll</HintPath> <HintPath>..\packages\Autofac.4.8.1\lib\net45\Autofac.dll</HintPath>

View File

@ -10,23 +10,32 @@ using OpenDiablo2.Common.Models;
using System.Reflection; using System.Reflection;
using OpenDiablo2.Common.Interfaces; using OpenDiablo2.Common.Interfaces;
using System.Diagnostics; using System.Diagnostics;
using OpenDiablo2.Core.UI;
using OpenDiablo2.Common.Enums;
namespace OpenDiablo2 namespace OpenDiablo2
{ {
static class Program static class Program
{ {
static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static GlobalConfiguration globalConfiguration;
static void Main(string[] args) static void Main(string[] args)
{ {
log.Info("OpenDiablo 2: The Free and Open Source Diablo 2 clone!"); log.Info("OpenDiablo 2: The Free and Open Source Diablo 2 clone!");
Parser.Default.ParseArguments<CommandLineOptions>(args).WithParsed<CommandLineOptions>(o =>
{
globalConfiguration = new GlobalConfiguration
{
BaseDataPath = Path.GetFullPath(o.DataPath ?? Directory.GetCurrentDirectory())
};
});
#if !DEBUG #if !DEBUG
try try
{ {
#endif #endif
BuildContainer() BuildContainer()
.ResolveCommandLineOptions(args)
.Resolve<IGameEngine>() .Resolve<IGameEngine>()
.Run(); .Run();
#if !DEBUG #if !DEBUG
@ -44,21 +53,12 @@ namespace OpenDiablo2
.Build(); .Build();
static IContainer ResolveCommandLineOptions(this IContainer container, IEnumerable<string> args)
{
var globalConfiguration = container.Resolve<GlobalConfiguration>();
Parser.Default.ParseArguments<CommandLineOptions>(args).WithParsed<CommandLineOptions>(o =>
{
globalConfiguration.BaseDataPath = Path.GetFullPath(o.DataPath ?? Directory.GetCurrentDirectory());
});
return container;
}
static ContainerBuilder RegisterLocalTypes(this ContainerBuilder containerBuilder) static ContainerBuilder RegisterLocalTypes(this ContainerBuilder containerBuilder)
{ {
containerBuilder.RegisterType<GlobalConfiguration>().AsSelf().SingleInstance(); containerBuilder.Register<GlobalConfiguration>(x =>
{
return globalConfiguration;
}).AsSelf().SingleInstance();
containerBuilder.Register<Func<string, IScene>>(c => containerBuilder.Register<Func<string, IScene>>(c =>
{ {
@ -66,12 +66,18 @@ namespace OpenDiablo2
return (sceneName) => componentContext.ResolveKeyed<IScene>(sceneName); return (sceneName) => componentContext.ResolveKeyed<IScene>(sceneName);
}); });
containerBuilder.Register<Func<eButtonType, Button>>(c =>
{
var componentContext = c.Resolve<IComponentContext>();
return (buttonType) => componentContext.Resolve<Button>(new NamedParameter("buttonLayout", ButtonLayout.Values[buttonType]));
});
return containerBuilder; return containerBuilder;
} }
static ContainerBuilder LoadAssemblyModules(this ContainerBuilder containerBuilder) static ContainerBuilder LoadAssemblyModules(this ContainerBuilder containerBuilder)
{ {
var filesToLoad = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.dll"); var filesToLoad = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.dll").Where(x => Path.GetFileName(x).StartsWith("OpenDiablo2."));
foreach (var file in filesToLoad) foreach (var file in filesToLoad)
{ {
try try