mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-09-29 14:45:58 -04: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
|
namespace OpenDiablo2.Common.Models
|
||||||
{
|
{
|
||||||
|
|
||||||
public sealed class ImageFrame : IDisposable
|
public sealed class ImageFrame
|
||||||
{
|
{
|
||||||
public UInt32 Flip { get; internal set; }
|
public UInt32 Flip { get; internal set; }
|
||||||
public UInt32 Width { get; internal set; }
|
public UInt32 Width { get; internal set; }
|
||||||
@ -18,7 +18,8 @@ namespace OpenDiablo2.Common.Models
|
|||||||
public UInt32 Length { get; internal set; }
|
public UInt32 Length { get; internal set; }
|
||||||
public Int16[] ImageData { get; internal set; }
|
public Int16[] ImageData { get; internal set; }
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
|
~ImageFrame()
|
||||||
{
|
{
|
||||||
ImageData = null;
|
ImageData = null;
|
||||||
}
|
}
|
||||||
@ -31,7 +32,7 @@ namespace OpenDiablo2.Common.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ImageSet : IDisposable
|
public sealed class ImageSet
|
||||||
{
|
{
|
||||||
private UInt32[] framePointers;
|
private UInt32[] framePointers;
|
||||||
public ImageFrame[] Frames { get; private set; }
|
public ImageFrame[] Frames { get; private set; }
|
||||||
@ -117,8 +118,10 @@ namespace OpenDiablo2.Common.Models
|
|||||||
return result;
|
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<COFLayer> Layers { get; private set; }
|
||||||
public IEnumerable<eAnimationFrame> AnimationFrames { 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)
|
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 br = new BinaryReader(stream);
|
||||||
|
|
||||||
var numLayers = br.ReadByte();
|
result.NumberOfLayers = br.ReadByte();
|
||||||
var framesPerDir = br.ReadByte();
|
result.FramesPerDirection = br.ReadByte();
|
||||||
br.ReadByte(); // Number of directions
|
result.NumberOfDirections = br.ReadByte(); // Number of directions
|
||||||
|
|
||||||
br.ReadBytes(25); // Skip 25 unknown bytes...
|
br.ReadBytes(25); // Skip 25 unknown bytes...
|
||||||
|
|
||||||
var layers = new List<COFLayer>();
|
var layers = new List<COFLayer>();
|
||||||
for (var layerIdx = 0; layerIdx < numLayers; layerIdx++)
|
for (var layerIdx = 0; layerIdx < result.NumberOfLayers; layerIdx++)
|
||||||
{
|
{
|
||||||
var layer = new COFLayer
|
var layer = new COFLayer
|
||||||
{
|
{
|
||||||
@ -93,7 +97,8 @@ namespace OpenDiablo2.Common.Models
|
|||||||
layer.WeaponCode = weaponCode;
|
layer.WeaponCode = weaponCode;
|
||||||
}
|
}
|
||||||
result.Layers = layers;
|
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();
|
var cofName = $"{hero.ToToken()}{mobMode.ToToken()}{weaponClass.ToToken()}".ToUpper();
|
||||||
result.Animations = animations[cofName];
|
result.Animations = animations[cofName];
|
||||||
|
@ -112,6 +112,7 @@ namespace OpenDiablo2.Core
|
|||||||
|
|
||||||
if (nextScene!= null)
|
if (nextScene!= null)
|
||||||
{
|
{
|
||||||
|
currentScene.Dispose();
|
||||||
currentScene = nextScene;
|
currentScene = nextScene;
|
||||||
nextScene = null;
|
nextScene = null;
|
||||||
continue;
|
continue;
|
||||||
@ -131,6 +132,13 @@ namespace OpenDiablo2.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeScene(eSceneType sceneType)
|
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)
|
private IMapInfo GetMap(ref int cellX, ref int cellY)
|
||||||
{
|
{
|
||||||
var x = cellX;
|
var p = new Point(cellX, cellY);
|
||||||
var y = cellY;
|
var map = mapInfo.LastOrDefault(z => z.TileLocation.Contains(p));
|
||||||
var map = mapInfo.LastOrDefault(z => (x >= z.TileLocation.X) && (y >= z.TileLocation.Y)
|
|
||||||
&& (x < z.TileLocation.Right) && (y < z.TileLocation.Bottom));
|
|
||||||
if (map == null)
|
if (map == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@ -43,7 +43,8 @@ namespace OpenDiablo2.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ImageSet GetImageSet(string resourcePath)
|
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)
|
public MPQFont GetMPQFont(string resourcePath)
|
||||||
=> cache.AddOrGetExisting($"Font::{resourcePath}", () => MPQFont.LoadFromStream(mpqProvider.GetStream($"{resourcePath}.DC6"), mpqProvider.GetStream($"{resourcePath}.tbl")));
|
=> cache.AddOrGetExisting($"Font::{resourcePath}", () => MPQFont.LoadFromStream(mpqProvider.GetStream($"{resourcePath}.DC6"), mpqProvider.GetStream($"{resourcePath}.tbl")));
|
||||||
@ -68,11 +69,12 @@ namespace OpenDiablo2.Core
|
|||||||
{
|
{
|
||||||
var path = $"{ResourcePaths.PlayerAnimationBase}\\{hero.ToToken()}\\COF\\{hero.ToToken()}{mobMode.ToToken()}{weaponClass.ToToken()}.cof";
|
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);
|
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)
|
public MPQDCC GetPlayerDCC(MPQCOF.COFLayer cofLayer, eArmorType armorType, Palette palette)
|
||||||
{
|
{
|
||||||
// TODO: We need to cache this...
|
return cache.AddOrGetExisting($"PlayerDCC::{cofLayer.GetDCCPath(armorType)}", () =>
|
||||||
|
{
|
||||||
byte[] binaryData;
|
byte[] binaryData;
|
||||||
|
|
||||||
var streamPath = cofLayer.GetDCCPath(armorType);
|
var streamPath = cofLayer.GetDCCPath(armorType);
|
||||||
@ -89,25 +91,7 @@ namespace OpenDiablo2.Core
|
|||||||
}
|
}
|
||||||
var result = new MPQDCC(binaryData, palette);
|
var result = new MPQDCC(binaryData, palette);
|
||||||
return result;
|
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.");
|
log.Info("Configuring OpenDiablo2.Core service implementations.");
|
||||||
|
|
||||||
builder.RegisterType<SDL2RenderWindow>().AsImplementedInterfaces().SingleInstance();
|
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 IntPtr[] SpriteTexture { get; set; }
|
||||||
public int FramesToAnimate { get; set; }
|
public int FramesToAnimate { get; set; }
|
||||||
public int AnimationSpeed { 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);
|
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>();
|
private readonly List<DirectionCacheItem> directionCache = new List<DirectionCacheItem>();
|
||||||
DirectionCacheItem currentDirectionCache;
|
DirectionCacheItem currentDirectionCache;
|
||||||
private float seconds;
|
private float seconds;
|
||||||
|
private int renderFrameIndex = 0;
|
||||||
|
|
||||||
private readonly IResourceManager resourceManager;
|
private readonly IResourceManager resourceManager;
|
||||||
private readonly IPaletteProvider paletteProvider;
|
private readonly IPaletteProvider paletteProvider;
|
||||||
@ -79,13 +79,13 @@ namespace OpenDiablo2.SDL2_
|
|||||||
|
|
||||||
var destRect = new SDL.SDL_Rect
|
var destRect = new SDL.SDL_Rect
|
||||||
{
|
{
|
||||||
x = pixelOffsetX + currentDirectionCache.SpriteRect[currentDirectionCache.RenderFrameIndex].x,
|
x = pixelOffsetX + currentDirectionCache.SpriteRect[renderFrameIndex].x,
|
||||||
y = pixelOffsetY + currentDirectionCache.SpriteRect[currentDirectionCache.RenderFrameIndex].y,
|
y = pixelOffsetY + currentDirectionCache.SpriteRect[renderFrameIndex].y,
|
||||||
w = currentDirectionCache.SpriteRect[currentDirectionCache.RenderFrameIndex].w,
|
w = currentDirectionCache.SpriteRect[renderFrameIndex].w,
|
||||||
h = currentDirectionCache.SpriteRect[currentDirectionCache.RenderFrameIndex].h
|
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)
|
public void Update(long ms)
|
||||||
@ -98,9 +98,9 @@ namespace OpenDiablo2.SDL2_
|
|||||||
while (seconds >= animationSeg)
|
while (seconds >= animationSeg)
|
||||||
{
|
{
|
||||||
seconds -= animationSeg;
|
seconds -= animationSeg;
|
||||||
currentDirectionCache.RenderFrameIndex++;
|
renderFrameIndex++;
|
||||||
if (currentDirectionCache.RenderFrameIndex >= currentDirectionCache.FramesToAnimate)
|
while (renderFrameIndex >= currentDirectionCache.FramesToAnimate)
|
||||||
currentDirectionCache.RenderFrameIndex = 0;
|
renderFrameIndex -= currentDirectionCache.FramesToAnimate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +111,7 @@ namespace OpenDiablo2.SDL2_
|
|||||||
|
|
||||||
public void ResetAnimationData()
|
public void ResetAnimationData()
|
||||||
{
|
{
|
||||||
|
var lastMobMode = MobMode;
|
||||||
switch (LocationDetails.MovementType)
|
switch (LocationDetails.MovementType)
|
||||||
{
|
{
|
||||||
case eMovementType.Stopped:
|
case eMovementType.Stopped:
|
||||||
@ -126,23 +127,22 @@ namespace OpenDiablo2.SDL2_
|
|||||||
MobMode = eMobMode.PlayerNeutral;
|
MobMode = eMobMode.PlayerNeutral;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (lastMobMode != MobMode)
|
||||||
|
renderFrameIndex = 0;
|
||||||
|
|
||||||
currentDirectionCache = directionCache.FirstOrDefault(x => x.MobMode == MobMode && x.Direction == directionConversion[LocationDetails.MovementDirection]);
|
currentDirectionCache = directionCache.FirstOrDefault(x => x.MobMode == MobMode && x.Direction == directionConversion[LocationDetails.MovementDirection]);
|
||||||
if (currentDirectionCache != null)
|
if (currentDirectionCache != null)
|
||||||
{
|
|
||||||
currentDirectionCache.RenderFrameIndex = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
animationData = resourceManager.GetPlayerAnimation(Hero, WeaponClass, MobMode, ShieldCode, WeaponCode);
|
animationData = resourceManager.GetPlayerAnimation(Hero, WeaponClass, MobMode, ShieldCode, WeaponCode);
|
||||||
if (animationData == null)
|
if (animationData == null)
|
||||||
throw new OpenDiablo2Exception("Could not locate animation for the character!");
|
throw new OpenDiablo2Exception("Could not locate animation for the character!");
|
||||||
|
|
||||||
var palette = paletteProvider.PaletteTable["Units"];
|
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
|
var directionCache = new DirectionCacheItem
|
||||||
{
|
{
|
||||||
@ -155,7 +155,6 @@ namespace OpenDiablo2.SDL2_
|
|||||||
var dirAnimation = animationData.Animations[0];
|
var dirAnimation = animationData.Animations[0];
|
||||||
directionCache.FramesToAnimate = dirAnimation.FramesPerDirection;
|
directionCache.FramesToAnimate = dirAnimation.FramesPerDirection;
|
||||||
directionCache.AnimationSpeed = dirAnimation.AnimationSpeed;
|
directionCache.AnimationSpeed = dirAnimation.AnimationSpeed;
|
||||||
directionCache.RenderFrameIndex = 0;
|
|
||||||
|
|
||||||
var minX = Int32.MaxValue;
|
var minX = Int32.MaxValue;
|
||||||
var minY = Int32.MaxValue;
|
var minY = Int32.MaxValue;
|
||||||
@ -163,7 +162,6 @@ namespace OpenDiablo2.SDL2_
|
|||||||
var maxY = Int32.MinValue;
|
var maxY = Int32.MinValue;
|
||||||
|
|
||||||
var layersIgnored = 0;
|
var layersIgnored = 0;
|
||||||
var layersToRender = new List<MPQDCC>();
|
|
||||||
foreach (var layer in layerData)
|
foreach (var layer in layerData)
|
||||||
{
|
{
|
||||||
if (layer == null)
|
if (layer == null)
|
||||||
@ -172,7 +170,6 @@ namespace OpenDiablo2.SDL2_
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
layersToRender.Add(layer);
|
|
||||||
minX = Math.Min(minX, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Left);
|
minX = Math.Min(minX, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Left);
|
||||||
minY = Math.Min(minY, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Top);
|
minY = Math.Min(minY, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Top);
|
||||||
maxX = Math.Max(maxX, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Right);
|
maxX = Math.Max(maxX, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Right);
|
||||||
@ -195,8 +192,21 @@ namespace OpenDiablo2.SDL2_
|
|||||||
SDL.SDL_LockTexture(texture, IntPtr.Zero, out IntPtr pixels, out int pitch);
|
SDL.SDL_LockTexture(texture, IntPtr.Zero, out IntPtr pixels, out int pitch);
|
||||||
UInt32* data = (UInt32*)pixels;
|
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)
|
if (layer == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -231,8 +241,9 @@ namespace OpenDiablo2.SDL2_
|
|||||||
directionCache.SpriteRect[frameIndex] = new SDL.SDL_Rect { x = minX, y = minY, w = frameW, h = frameH };
|
directionCache.SpriteRect[frameIndex] = new SDL.SDL_Rect { x = minX, y = minY, w = frameW, h = frameH };
|
||||||
|
|
||||||
this.directionCache.Add(directionCache);
|
this.directionCache.Add(directionCache);
|
||||||
currentDirectionCache = directionCache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentDirectionCache = directionCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,14 +22,14 @@ using SDL2;
|
|||||||
|
|
||||||
namespace OpenDiablo2.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 static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private IntPtr music = IntPtr.Zero;
|
private IntPtr music = IntPtr.Zero;
|
||||||
private int musicChannel;
|
private int musicChannel;
|
||||||
private byte[] musicBytes; // Cannot be local or GC will destory it with great anger
|
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)
|
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()}");
|
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 sealed class SDL2Sprite : ISprite
|
||||||
{
|
{
|
||||||
internal readonly ImageSet source;
|
internal ImageSet source;
|
||||||
private readonly IntPtr renderer;
|
private readonly IntPtr renderer;
|
||||||
private readonly bool cacheFrames;
|
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);
|
SDL.SDL_SetTextureBlendMode(texture[i], blend ? SDL.SDL_BlendMode.SDL_BLENDMODE_ADD : SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||||
}
|
}
|
||||||
else
|
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);
|
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;
|
var framestoClear = cacheFrames ? TotalFrames : 1;
|
||||||
for (int i = 0; i < framestoClear; i++)
|
for (int i = 0; i < framestoClear; i++)
|
||||||
frameLoaded[i] = false;
|
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()
|
public void Dispose()
|
||||||
@ -213,16 +230,11 @@ namespace OpenDiablo2.SDL2_
|
|||||||
if (disposed)
|
if (disposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var framestoClear = cacheFrames ? TotalFrames : 1;
|
DestroyTextures();
|
||||||
for (var i = 0; i < framestoClear; i++)
|
source = null;
|
||||||
{
|
|
||||||
SDL.SDL_DestroyTexture(texture[i]);
|
|
||||||
texture[i] = IntPtr.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
texture = Array.Empty<IntPtr>();
|
|
||||||
disposed = true;
|
disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,18 +77,6 @@ namespace OpenDiablo2.Scenes
|
|||||||
urlLabel = renderWindow.CreateLabel(labelFont, new Point(50, 569), "https://github.com/essial/OpenDiablo2/");
|
urlLabel = renderWindow.CreateLabel(labelFont, new Point(50, 569), "https://github.com/essial/OpenDiablo2/");
|
||||||
urlLabel.TextColor = Color.Magenta;
|
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.LoadSong(mpqProvider.GetStream(ResourcePaths.BGMTitle));
|
||||||
soundProvider.PlaySong();
|
soundProvider.PlaySong();
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,25 @@ namespace OpenDiablo2.Scenes
|
|||||||
Retreating
|
Retreating
|
||||||
}
|
}
|
||||||
|
|
||||||
class HeroRenderInfo
|
class HeroRenderInfo : IDisposable
|
||||||
{
|
{
|
||||||
public ISprite IdleSprite, IdleSelectedSprite, ForwardWalkSprite, ForwardWalkSpriteOverlay, SelectedSprite, SelectedSpriteOverlay, BackWalkSprite, BackWalkSpriteOverlay;
|
public ISprite IdleSprite, IdleSelectedSprite, ForwardWalkSprite, ForwardWalkSpriteOverlay, SelectedSprite, SelectedSpriteOverlay, BackWalkSprite, BackWalkSpriteOverlay;
|
||||||
public eHeroStance Stance;
|
public eHeroStance Stance;
|
||||||
public long ForwardWalkTimeMs, BackWalkTimeMs;
|
public long ForwardWalkTimeMs, BackWalkTimeMs;
|
||||||
public long SpecialFrameTime;
|
public long SpecialFrameTime;
|
||||||
public Rectangle SelectionBounds = new Rectangle();
|
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)]
|
[Scene(eSceneType.SelectHeroClass)]
|
||||||
@ -267,7 +279,7 @@ namespace OpenDiablo2.Scenes
|
|||||||
StopSfx();
|
StopSfx();
|
||||||
|
|
||||||
var heros = Enum.GetValues(typeof(eHero)).Cast<eHero>();
|
var heros = Enum.GetValues(typeof(eHero)).Cast<eHero>();
|
||||||
foreach(var hero in heros)
|
foreach (var hero in heros)
|
||||||
{
|
{
|
||||||
heroRenderInfo[hero].SpecialFrameTime = 0;
|
heroRenderInfo[hero].SpecialFrameTime = 0;
|
||||||
heroRenderInfo[hero].Stance = eHeroStance.Idle;
|
heroRenderInfo[hero].Stance = eHeroStance.Idle;
|
||||||
@ -460,7 +472,7 @@ namespace OpenDiablo2.Scenes
|
|||||||
renderInfo.SpecialFrameTime = 0;
|
renderInfo.SpecialFrameTime = 0;
|
||||||
|
|
||||||
|
|
||||||
foreach(var ri in heroRenderInfo)
|
foreach (var ri in heroRenderInfo)
|
||||||
{
|
{
|
||||||
if (ri.Value.Stance != eHeroStance.Selected)
|
if (ri.Value.Stance != eHeroStance.Selected)
|
||||||
continue;
|
continue;
|
||||||
@ -611,6 +623,12 @@ namespace OpenDiablo2.Scenes
|
|||||||
headingFont.Dispose();
|
headingFont.Dispose();
|
||||||
headingLabel.Dispose();
|
headingLabel.Dispose();
|
||||||
sfxDictionary.Clear();
|
sfxDictionary.Clear();
|
||||||
|
|
||||||
|
foreach (var hri in heroRenderInfo)
|
||||||
|
hri.Value.Dispose();
|
||||||
|
|
||||||
|
heroRenderInfo.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,16 @@
|
|||||||
<startup>
|
<startup>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
|
||||||
</startup>
|
</startup>
|
||||||
|
<system.runtime.caching>
|
||||||
|
<memoryCache>
|
||||||
|
<namedCaches>
|
||||||
|
<add name="OpenDiablo2.Cache"
|
||||||
|
cacheMemoryLimitMegabytes="0"
|
||||||
|
physicalMemoryLimitPercentage="0"
|
||||||
|
pollingInterval="00:00:05" />
|
||||||
|
</namedCaches>
|
||||||
|
</memoryCache>
|
||||||
|
</system.runtime.caching>
|
||||||
<runtime>
|
<runtime>
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
|
Loading…
Reference in New Issue
Block a user