mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-03 07:07:25 -05:00
Fixed animation glitches. Started work in animation priority. Fixed memory issues
This commit is contained in:
parent
c277cb2d89
commit
6646efd0c3
@ -6,7 +6,7 @@ using System.Runtime.CompilerServices;
|
||||
namespace OpenDiablo2.Common.Models
|
||||
{
|
||||
|
||||
public sealed class ImageFrame : IDisposable
|
||||
public sealed class ImageFrame
|
||||
{
|
||||
public UInt32 Flip { get; internal set; }
|
||||
public UInt32 Width { get; internal set; }
|
||||
@ -18,7 +18,8 @@ namespace OpenDiablo2.Common.Models
|
||||
public UInt32 Length { get; internal set; }
|
||||
public Int16[] ImageData { get; internal set; }
|
||||
|
||||
public void Dispose()
|
||||
|
||||
~ImageFrame()
|
||||
{
|
||||
ImageData = null;
|
||||
}
|
||||
@ -31,7 +32,7 @@ namespace OpenDiablo2.Common.Models
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ImageSet : IDisposable
|
||||
public sealed class ImageSet
|
||||
{
|
||||
private UInt32[] framePointers;
|
||||
public ImageFrame[] Frames { get; private set; }
|
||||
@ -117,8 +118,10 @@ namespace OpenDiablo2.Common.Models
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
~ImageSet()
|
||||
{
|
||||
framePointers = null;
|
||||
Frames = Array.Empty<ImageFrame>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,10 @@ namespace OpenDiablo2.Common.Models
|
||||
|
||||
public IEnumerable<COFLayer> Layers { get; private set; }
|
||||
public IEnumerable<eAnimationFrame> AnimationFrames { get; private set; }
|
||||
public byte[] Priority { get; private set; }
|
||||
public int NumberOfDirections { get; internal set; }
|
||||
public int FramesPerDirection { get; internal set; }
|
||||
public int NumberOfLayers { get; internal set; }
|
||||
|
||||
public static MPQCOF Load(Stream stream, Dictionary<string, List<AnimationData>> animations, eHero hero, eWeaponClass weaponClass, eMobMode mobMode, string ShieldCode, string weaponCode)
|
||||
{
|
||||
@ -69,14 +73,14 @@ namespace OpenDiablo2.Common.Models
|
||||
|
||||
var br = new BinaryReader(stream);
|
||||
|
||||
var numLayers = br.ReadByte();
|
||||
var framesPerDir = br.ReadByte();
|
||||
br.ReadByte(); // Number of directions
|
||||
result.NumberOfLayers = br.ReadByte();
|
||||
result.FramesPerDirection = br.ReadByte();
|
||||
result.NumberOfDirections = br.ReadByte(); // Number of directions
|
||||
|
||||
br.ReadBytes(25); // Skip 25 unknown bytes...
|
||||
|
||||
var layers = new List<COFLayer>();
|
||||
for (var layerIdx = 0; layerIdx < numLayers; layerIdx++)
|
||||
for (var layerIdx = 0; layerIdx < result.NumberOfLayers; layerIdx++)
|
||||
{
|
||||
var layer = new COFLayer
|
||||
{
|
||||
@ -93,7 +97,8 @@ namespace OpenDiablo2.Common.Models
|
||||
layer.WeaponCode = weaponCode;
|
||||
}
|
||||
result.Layers = layers;
|
||||
result.AnimationFrames = br.ReadBytes(framesPerDir).Select(x => (eAnimationFrame)x);
|
||||
result.AnimationFrames = br.ReadBytes(result.FramesPerDirection).Select(x => (eAnimationFrame)x);
|
||||
result.Priority = br.ReadBytes(result.FramesPerDirection * result.NumberOfLayers * result.NumberOfDirections);
|
||||
|
||||
var cofName = $"{hero.ToToken()}{mobMode.ToToken()}{weaponClass.ToToken()}".ToUpper();
|
||||
result.Animations = animations[cofName];
|
||||
|
@ -112,6 +112,7 @@ namespace OpenDiablo2.Core
|
||||
|
||||
if (nextScene!= null)
|
||||
{
|
||||
currentScene.Dispose();
|
||||
currentScene = nextScene;
|
||||
nextScene = null;
|
||||
continue;
|
||||
@ -131,6 +132,13 @@ namespace OpenDiablo2.Core
|
||||
}
|
||||
|
||||
public void ChangeScene(eSceneType sceneType)
|
||||
=> nextScene = getScene(sceneType);
|
||||
{
|
||||
var loadingSprite = getRenderWindow().LoadSprite(ResourcePaths.LoadingScreen, Palettes.Loading, new Point(300, 400));
|
||||
|
||||
getRenderWindow().Clear();
|
||||
getRenderWindow().Draw(loadingSprite);
|
||||
getRenderWindow().Sync();
|
||||
nextScene = getScene(sceneType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,10 +269,8 @@ namespace OpenDiablo2.Core.GameState_
|
||||
|
||||
private IMapInfo GetMap(ref int cellX, ref int cellY)
|
||||
{
|
||||
var x = cellX;
|
||||
var y = cellY;
|
||||
var map = mapInfo.LastOrDefault(z => (x >= z.TileLocation.X) && (y >= z.TileLocation.Y)
|
||||
&& (x < z.TileLocation.Right) && (y < z.TileLocation.Bottom));
|
||||
var p = new Point(cellX, cellY);
|
||||
var map = mapInfo.LastOrDefault(z => z.TileLocation.Contains(p));
|
||||
if (map == null)
|
||||
{
|
||||
return null;
|
||||
|
@ -43,7 +43,8 @@ namespace OpenDiablo2.Core
|
||||
}
|
||||
|
||||
public ImageSet GetImageSet(string resourcePath)
|
||||
=> cache.AddOrGetExisting($"ImageSet::{resourcePath}", () => ImageSet.LoadFromStream(mpqProvider.GetStream(resourcePath)));
|
||||
// => cache.AddOrGetExisting($"ImageSet::{resourcePath}", () => ImageSet.LoadFromStream(mpqProvider.GetStream(resourcePath)));
|
||||
=> ImageSet.LoadFromStream(mpqProvider.GetStream(resourcePath));
|
||||
|
||||
public MPQFont GetMPQFont(string resourcePath)
|
||||
=> cache.AddOrGetExisting($"Font::{resourcePath}", () => MPQFont.LoadFromStream(mpqProvider.GetStream($"{resourcePath}.DC6"), mpqProvider.GetStream($"{resourcePath}.tbl")));
|
||||
@ -68,46 +69,29 @@ namespace OpenDiablo2.Core
|
||||
{
|
||||
var path = $"{ResourcePaths.PlayerAnimationBase}\\{hero.ToToken()}\\COF\\{hero.ToToken()}{mobMode.ToToken()}{weaponClass.ToToken()}.cof";
|
||||
return MPQCOF.Load(mpqProvider.GetStream(path), Animations, hero, weaponClass, mobMode, shieldCode, weaponCode);
|
||||
});
|
||||
}, new System.Runtime.Caching.CacheItemPolicy { Priority = System.Runtime.Caching.CacheItemPriority.NotRemovable });
|
||||
|
||||
public MPQDCC GetPlayerDCC(MPQCOF.COFLayer cofLayer, eArmorType armorType, Palette palette)
|
||||
{
|
||||
// TODO: We need to cache this...
|
||||
byte[] binaryData;
|
||||
return cache.AddOrGetExisting($"PlayerDCC::{cofLayer.GetDCCPath(armorType)}", () =>
|
||||
{
|
||||
byte[] binaryData;
|
||||
|
||||
var streamPath = cofLayer.GetDCCPath(armorType);
|
||||
using (var stream = mpqProvider.GetStream(streamPath))
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
log.Error($"Could not load Player DCC: {streamPath}");
|
||||
return null;
|
||||
}
|
||||
var streamPath = cofLayer.GetDCCPath(armorType);
|
||||
using (var stream = mpqProvider.GetStream(streamPath))
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
log.Error($"Could not load Player DCC: {streamPath}");
|
||||
return null;
|
||||
}
|
||||
|
||||
binaryData = new byte[stream.Length];
|
||||
stream.Read(binaryData, 0, (int)stream.Length);
|
||||
}
|
||||
var result = new MPQDCC(binaryData, palette);
|
||||
return result;
|
||||
binaryData = new byte[stream.Length];
|
||||
stream.Read(binaryData, 0, (int)stream.Length);
|
||||
}
|
||||
var result = new MPQDCC(binaryData, palette);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
=> cache.AddOrGetExisting($"DCC::{cofLayer}::{armorType}::{palette.Name}", () =>
|
||||
{
|
||||
byte[] binaryData;
|
||||
|
||||
using (var stream = mpqProvider.GetStream(cofLayer.GetDCCPath(armorType)))
|
||||
{
|
||||
if (stream == null)
|
||||
return null;
|
||||
|
||||
binaryData = new byte[stream.Length];
|
||||
stream.Read(binaryData, 0, (int)stream.Length);
|
||||
}
|
||||
var result = new MPQDCC(binaryData, palette);
|
||||
return result;
|
||||
});
|
||||
/*
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace OpenDiablo2.SDL2_
|
||||
log.Info("Configuring OpenDiablo2.Core service implementations.");
|
||||
|
||||
builder.RegisterType<SDL2RenderWindow>().AsImplementedInterfaces().SingleInstance();
|
||||
builder.RegisterType<SDL2MusicProvider>().AsImplementedInterfaces().SingleInstance();
|
||||
builder.RegisterType<SDL2SoundProvider>().AsImplementedInterfaces().SingleInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ namespace OpenDiablo2.SDL2_
|
||||
public IntPtr[] SpriteTexture { get; set; }
|
||||
public int FramesToAnimate { get; set; }
|
||||
public int AnimationSpeed { get; set; }
|
||||
public int RenderFrameIndex { get; set; }
|
||||
}
|
||||
|
||||
static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
@ -57,6 +56,7 @@ namespace OpenDiablo2.SDL2_
|
||||
private readonly List<DirectionCacheItem> directionCache = new List<DirectionCacheItem>();
|
||||
DirectionCacheItem currentDirectionCache;
|
||||
private float seconds;
|
||||
private int renderFrameIndex = 0;
|
||||
|
||||
private readonly IResourceManager resourceManager;
|
||||
private readonly IPaletteProvider paletteProvider;
|
||||
@ -79,13 +79,13 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
var destRect = new SDL.SDL_Rect
|
||||
{
|
||||
x = pixelOffsetX + currentDirectionCache.SpriteRect[currentDirectionCache.RenderFrameIndex].x,
|
||||
y = pixelOffsetY + currentDirectionCache.SpriteRect[currentDirectionCache.RenderFrameIndex].y,
|
||||
w = currentDirectionCache.SpriteRect[currentDirectionCache.RenderFrameIndex].w,
|
||||
h = currentDirectionCache.SpriteRect[currentDirectionCache.RenderFrameIndex].h
|
||||
x = pixelOffsetX + currentDirectionCache.SpriteRect[renderFrameIndex].x,
|
||||
y = pixelOffsetY + currentDirectionCache.SpriteRect[renderFrameIndex].y,
|
||||
w = currentDirectionCache.SpriteRect[renderFrameIndex].w,
|
||||
h = currentDirectionCache.SpriteRect[renderFrameIndex].h
|
||||
};
|
||||
|
||||
SDL.SDL_RenderCopy(renderer, currentDirectionCache.SpriteTexture[currentDirectionCache.RenderFrameIndex], IntPtr.Zero, ref destRect);
|
||||
SDL.SDL_RenderCopy(renderer, currentDirectionCache.SpriteTexture[renderFrameIndex], IntPtr.Zero, ref destRect);
|
||||
}
|
||||
|
||||
public void Update(long ms)
|
||||
@ -98,9 +98,9 @@ namespace OpenDiablo2.SDL2_
|
||||
while (seconds >= animationSeg)
|
||||
{
|
||||
seconds -= animationSeg;
|
||||
currentDirectionCache.RenderFrameIndex++;
|
||||
if (currentDirectionCache.RenderFrameIndex >= currentDirectionCache.FramesToAnimate)
|
||||
currentDirectionCache.RenderFrameIndex = 0;
|
||||
renderFrameIndex++;
|
||||
while (renderFrameIndex >= currentDirectionCache.FramesToAnimate)
|
||||
renderFrameIndex -= currentDirectionCache.FramesToAnimate;
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,6 +111,7 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
public void ResetAnimationData()
|
||||
{
|
||||
var lastMobMode = MobMode;
|
||||
switch (LocationDetails.MovementType)
|
||||
{
|
||||
case eMovementType.Stopped:
|
||||
@ -126,23 +127,22 @@ namespace OpenDiablo2.SDL2_
|
||||
MobMode = eMobMode.PlayerNeutral;
|
||||
break;
|
||||
}
|
||||
if (lastMobMode != MobMode)
|
||||
renderFrameIndex = 0;
|
||||
|
||||
currentDirectionCache = directionCache.FirstOrDefault(x => x.MobMode == MobMode && x.Direction == directionConversion[LocationDetails.MovementDirection]);
|
||||
if (currentDirectionCache != null)
|
||||
{
|
||||
currentDirectionCache.RenderFrameIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
animationData = resourceManager.GetPlayerAnimation(Hero, WeaponClass, MobMode, ShieldCode, WeaponCode);
|
||||
if (animationData == null)
|
||||
throw new OpenDiablo2Exception("Could not locate animation for the character!");
|
||||
|
||||
var palette = paletteProvider.PaletteTable["Units"];
|
||||
CacheFrames(animationData.Layers.Select(layer => resourceManager.GetPlayerDCC(layer, ArmorType, palette)));
|
||||
CacheFrames(animationData.Layers.Select(layer => resourceManager.GetPlayerDCC(layer, ArmorType, palette)).ToArray());
|
||||
}
|
||||
|
||||
private unsafe void CacheFrames(IEnumerable<MPQDCC> layerData)
|
||||
private unsafe void CacheFrames(MPQDCC[] layerData)
|
||||
{
|
||||
var directionCache = new DirectionCacheItem
|
||||
{
|
||||
@ -155,7 +155,6 @@ namespace OpenDiablo2.SDL2_
|
||||
var dirAnimation = animationData.Animations[0];
|
||||
directionCache.FramesToAnimate = dirAnimation.FramesPerDirection;
|
||||
directionCache.AnimationSpeed = dirAnimation.AnimationSpeed;
|
||||
directionCache.RenderFrameIndex = 0;
|
||||
|
||||
var minX = Int32.MaxValue;
|
||||
var minY = Int32.MaxValue;
|
||||
@ -163,7 +162,6 @@ namespace OpenDiablo2.SDL2_
|
||||
var maxY = Int32.MinValue;
|
||||
|
||||
var layersIgnored = 0;
|
||||
var layersToRender = new List<MPQDCC>();
|
||||
foreach (var layer in layerData)
|
||||
{
|
||||
if (layer == null)
|
||||
@ -172,7 +170,6 @@ namespace OpenDiablo2.SDL2_
|
||||
continue;
|
||||
}
|
||||
|
||||
layersToRender.Add(layer);
|
||||
minX = Math.Min(minX, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Left);
|
||||
minY = Math.Min(minY, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Top);
|
||||
maxX = Math.Max(maxX, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Right);
|
||||
@ -187,7 +184,7 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
directionCache.SpriteTexture = new IntPtr[directionCache.FramesToAnimate];
|
||||
directionCache.SpriteRect = new SDL.SDL_Rect[directionCache.FramesToAnimate];
|
||||
|
||||
|
||||
for (var frameIndex = 0; frameIndex < directionCache.FramesToAnimate; frameIndex++)
|
||||
{
|
||||
var texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, frameW, frameH);
|
||||
@ -195,8 +192,21 @@ namespace OpenDiablo2.SDL2_
|
||||
SDL.SDL_LockTexture(texture, IntPtr.Zero, out IntPtr pixels, out int pitch);
|
||||
UInt32* data = (UInt32*)pixels;
|
||||
|
||||
foreach (var layer in layersToRender)
|
||||
var priorities = new int[animationData.NumberOfLayers];
|
||||
Array.Copy(
|
||||
animationData.Priority,
|
||||
(directionConversion[LocationDetails.MovementDirection] * animationData.FramesPerDirection * animationData.NumberOfLayers)
|
||||
+ (frameIndex * animationData.NumberOfLayers),
|
||||
priorities,
|
||||
0,
|
||||
animationData.NumberOfLayers
|
||||
);
|
||||
|
||||
for (var i = 0; i < layerData.Length; i++)
|
||||
{
|
||||
//var layer = layerData[priorities[i]];
|
||||
var layer = layerData[i];
|
||||
|
||||
if (layer == null)
|
||||
continue;
|
||||
|
||||
@ -221,18 +231,19 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
SDL.SDL_UnlockTexture(texture);
|
||||
SDL.SDL_SetTextureBlendMode(texture, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
|
||||
|
||||
directionCache.SpriteTexture[frameIndex] = texture;
|
||||
directionCache.SpriteRect[frameIndex] = new SDL.SDL_Rect { x = minX, y = minY, w = frameW, h = frameH };
|
||||
|
||||
this.directionCache.Add(directionCache);
|
||||
currentDirectionCache = directionCache;
|
||||
}
|
||||
|
||||
currentDirectionCache = directionCache;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,14 +22,14 @@ using SDL2;
|
||||
|
||||
namespace OpenDiablo2.SDL2_
|
||||
{
|
||||
public sealed class SDL2MusicProvider : ISoundProvider
|
||||
public sealed class SDL2SoundProvider : ISoundProvider
|
||||
{
|
||||
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private IntPtr music = IntPtr.Zero;
|
||||
private int musicChannel;
|
||||
private byte[] musicBytes; // Cannot be local or GC will destory it with great anger
|
||||
|
||||
public SDL2MusicProvider()
|
||||
public SDL2SoundProvider()
|
||||
{
|
||||
if (SDL_mixer.Mix_OpenAudio(22050, SDL_mixer.MIX_DEFAULT_FORMAT, 2, 1024) < 0)
|
||||
log.Error($"SDL_mixer could not initialize! SDL_mixer Error: {SDL.SDL_GetError()}");
|
||||
|
@ -26,7 +26,7 @@ namespace OpenDiablo2.SDL2_
|
||||
{
|
||||
internal sealed class SDL2Sprite : ISprite
|
||||
{
|
||||
internal readonly ImageSet source;
|
||||
internal ImageSet source;
|
||||
private readonly IntPtr renderer;
|
||||
private readonly bool cacheFrames;
|
||||
|
||||
@ -96,7 +96,7 @@ namespace OpenDiablo2.SDL2_
|
||||
SDL.SDL_SetTextureBlendMode(texture[i], blend ? SDL.SDL_BlendMode.SDL_BLENDMODE_ADD : SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
else
|
||||
if (texture[TextureIndex] != IntPtr.Zero)
|
||||
if (texture != null && texture[TextureIndex] != IntPtr.Zero)
|
||||
SDL.SDL_SetTextureBlendMode(texture[TextureIndex], blend ? SDL.SDL_BlendMode.SDL_BLENDMODE_ADD : SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
|
||||
}
|
||||
@ -206,6 +206,23 @@ namespace OpenDiablo2.SDL2_
|
||||
var framestoClear = cacheFrames ? TotalFrames : 1;
|
||||
for (int i = 0; i < framestoClear; i++)
|
||||
frameLoaded[i] = false;
|
||||
|
||||
DestroyTextures();
|
||||
}
|
||||
|
||||
private void DestroyTextures()
|
||||
{
|
||||
var framestoClear = cacheFrames ? TotalFrames : 1;
|
||||
for (var i = 0; i < framestoClear; i++)
|
||||
{
|
||||
if (!frameLoaded[i])
|
||||
continue;
|
||||
SDL.SDL_DestroyTexture(texture[i]);
|
||||
texture[i] = IntPtr.Zero;
|
||||
frameLoaded[i] = false;
|
||||
}
|
||||
|
||||
texture = new IntPtr[TotalFrames];
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@ -213,16 +230,11 @@ namespace OpenDiablo2.SDL2_
|
||||
if (disposed)
|
||||
return;
|
||||
|
||||
var framestoClear = cacheFrames ? TotalFrames : 1;
|
||||
for (var i = 0; i < framestoClear; i++)
|
||||
{
|
||||
SDL.SDL_DestroyTexture(texture[i]);
|
||||
texture[i] = IntPtr.Zero;
|
||||
}
|
||||
|
||||
texture = Array.Empty<IntPtr>();
|
||||
DestroyTextures();
|
||||
source = null;
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -77,18 +77,6 @@ namespace OpenDiablo2.Scenes
|
||||
urlLabel = renderWindow.CreateLabel(labelFont, new Point(50, 569), "https://github.com/essial/OpenDiablo2/");
|
||||
urlLabel.TextColor = Color.Magenta;
|
||||
|
||||
var loadingSprite = renderWindow.LoadSprite(ResourcePaths.LoadingScreen, Palettes.Loading, new Point(300, 400));
|
||||
|
||||
// Pre-load all the scenes for now until we fix the sdl load problem
|
||||
var scenesToLoad = new eSceneType[] { eSceneType.SelectHeroClass };
|
||||
for (int i = 0; i < scenesToLoad.Count(); i++)
|
||||
{
|
||||
renderWindow.Clear();
|
||||
renderWindow.Draw(loadingSprite, (int)(loadingSprite.TotalFrames * (i / (float)scenesToLoad.Count())));
|
||||
renderWindow.Sync();
|
||||
getScene(scenesToLoad[i]);
|
||||
}
|
||||
|
||||
soundProvider.LoadSong(mpqProvider.GetStream(ResourcePaths.BGMTitle));
|
||||
soundProvider.PlaySong();
|
||||
}
|
||||
|
@ -20,13 +20,25 @@ namespace OpenDiablo2.Scenes
|
||||
Retreating
|
||||
}
|
||||
|
||||
class HeroRenderInfo
|
||||
class HeroRenderInfo : IDisposable
|
||||
{
|
||||
public ISprite IdleSprite, IdleSelectedSprite, ForwardWalkSprite, ForwardWalkSpriteOverlay, SelectedSprite, SelectedSpriteOverlay, BackWalkSprite, BackWalkSpriteOverlay;
|
||||
public eHeroStance Stance;
|
||||
public long ForwardWalkTimeMs, BackWalkTimeMs;
|
||||
public long SpecialFrameTime;
|
||||
public Rectangle SelectionBounds = new Rectangle();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
IdleSprite?.Dispose();
|
||||
IdleSelectedSprite?.Dispose();
|
||||
ForwardWalkSprite?.Dispose();
|
||||
ForwardWalkSpriteOverlay?.Dispose();
|
||||
SelectedSprite?.Dispose();
|
||||
SelectedSpriteOverlay?.Dispose();
|
||||
BackWalkSprite?.Dispose();
|
||||
BackWalkSpriteOverlay?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[Scene(eSceneType.SelectHeroClass)]
|
||||
@ -267,7 +279,7 @@ namespace OpenDiablo2.Scenes
|
||||
StopSfx();
|
||||
|
||||
var heros = Enum.GetValues(typeof(eHero)).Cast<eHero>();
|
||||
foreach(var hero in heros)
|
||||
foreach (var hero in heros)
|
||||
{
|
||||
heroRenderInfo[hero].SpecialFrameTime = 0;
|
||||
heroRenderInfo[hero].Stance = eHeroStance.Idle;
|
||||
@ -460,7 +472,7 @@ namespace OpenDiablo2.Scenes
|
||||
renderInfo.SpecialFrameTime = 0;
|
||||
|
||||
|
||||
foreach(var ri in heroRenderInfo)
|
||||
foreach (var ri in heroRenderInfo)
|
||||
{
|
||||
if (ri.Value.Stance != eHeroStance.Selected)
|
||||
continue;
|
||||
@ -611,6 +623,12 @@ namespace OpenDiablo2.Scenes
|
||||
headingFont.Dispose();
|
||||
headingLabel.Dispose();
|
||||
sfxDictionary.Clear();
|
||||
|
||||
foreach (var hri in heroRenderInfo)
|
||||
hri.Value.Dispose();
|
||||
|
||||
heroRenderInfo.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
|
||||
</startup>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
|
||||
</startup>
|
||||
<system.runtime.caching>
|
||||
<memoryCache>
|
||||
<namedCaches>
|
||||
<add name="OpenDiablo2.Cache"
|
||||
cacheMemoryLimitMegabytes="0"
|
||||
physicalMemoryLimitPercentage="0"
|
||||
pollingInterval="00:00:05" />
|
||||
</namedCaches>
|
||||
</memoryCache>
|
||||
</system.runtime.caching>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
|
Loading…
Reference in New Issue
Block a user