mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-20 23:47:16 -05:00
Tons of performance gained.
This commit is contained in:
parent
8f1d43863d
commit
e348d7b1e1
@ -26,15 +26,15 @@ namespace OpenDiablo2.Common.Models
|
||||
ImageData = new Int16[0];
|
||||
}
|
||||
|
||||
public Color GetColor(int x, int y, Palette palette)
|
||||
public UInt32 GetColor(int x, int y, Palette palette)
|
||||
{
|
||||
var index = ImageData[x + (y * Width)];
|
||||
if (index == -1)
|
||||
return Color.Transparent;
|
||||
return 0;
|
||||
|
||||
var color = palette.Colors[(int)index];
|
||||
var color = palette.Colors[index];
|
||||
|
||||
return Color.FromArgb(255, color.R, color.G, color.B);
|
||||
return ((UInt32)255 << 24) + ((UInt32)color.R << 16) + ((UInt32)color.G << 8) + (UInt32)color.B;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace OpenDiablo2.Core
|
||||
{
|
||||
private readonly GlobalConfiguration globalConfiguration;
|
||||
private readonly MPQ[] mpqs;
|
||||
private Dictionary<string, int> mpqLookup = new Dictionary<string, int>();
|
||||
|
||||
public MPQProvider(GlobalConfiguration globalConfiguration)
|
||||
{
|
||||
@ -22,12 +23,22 @@ namespace OpenDiablo2.Core
|
||||
.Where(x => !Path.GetFileName(x).StartsWith("patch"))
|
||||
.Select(file => new MPQ(file))
|
||||
.ToArray();
|
||||
|
||||
for(var i = 0; i < mpqs.Count(); i++)
|
||||
{
|
||||
foreach(var file in mpqs[i].Files)
|
||||
{
|
||||
mpqLookup[file.ToLower()] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<MPQ> GetMPQs() => mpqs;
|
||||
|
||||
public Stream GetStream(string fileName)
|
||||
=> mpqs.First(x => x.Files.Any(z =>z.ToLower() == fileName.ToLower())).OpenFile(fileName);
|
||||
{
|
||||
return mpqs[mpqLookup[fileName.ToLower()]].OpenFile(fileName);
|
||||
}
|
||||
|
||||
public IEnumerable<IEnumerable<string>> GetTextFile(string fileName)
|
||||
{
|
||||
|
@ -111,8 +111,9 @@ namespace OpenDiablo2.SDL2_
|
||||
h = font.sprite.FrameSize.Height
|
||||
};
|
||||
|
||||
SDL.SDL_SetTextureColorMod(font.sprite.textures[character], TextColor.R, TextColor.G, TextColor.B);
|
||||
SDL.SDL_RenderCopy(renderer, font.sprite.textures[character], IntPtr.Zero, ref rect);
|
||||
font.sprite.Frame = character;
|
||||
SDL.SDL_SetTextureColorMod(font.sprite.texture, TextColor.R, TextColor.G, TextColor.B);
|
||||
SDL.SDL_RenderCopy(renderer, font.sprite.texture, IntPtr.Zero, ref rect);
|
||||
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,8 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
SDL.SDL_SetRenderTarget(renderer, IntPtr.Zero);
|
||||
SDL.SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL.SDL_RenderClear(renderer);
|
||||
|
||||
}
|
||||
@ -148,7 +150,7 @@ namespace OpenDiablo2.SDL2_
|
||||
w = spr.FrameSize.Width,
|
||||
h = spr.FrameSize.Height
|
||||
};
|
||||
SDL.SDL_RenderCopy(renderer, spr.textures[spr.Frame], IntPtr.Zero, ref destRect);
|
||||
SDL.SDL_RenderCopy(renderer, spr.texture, IntPtr.Zero, ref destRect);
|
||||
|
||||
}
|
||||
|
||||
@ -162,9 +164,7 @@ namespace OpenDiablo2.SDL2_
|
||||
for (var x = 0; x < xSegments; x++)
|
||||
{
|
||||
var textureIndex = x + (y * xSegments) + (offset * xSegments * ySegments);
|
||||
textureIndex = Math.Min(spr.textures.Count() - 1, Math.Max(0, textureIndex));
|
||||
if (textureIndex >= spr.textures.Count())
|
||||
continue;
|
||||
spr.Frame = Math.Min(spr.TotalFrames - 1, Math.Max(0, textureIndex));
|
||||
|
||||
var destRect = new SDL.SDL_Rect
|
||||
{
|
||||
@ -173,7 +173,7 @@ namespace OpenDiablo2.SDL2_
|
||||
w = spr.FrameSize.Width,
|
||||
h = spr.FrameSize.Height
|
||||
};
|
||||
SDL.SDL_RenderCopy(renderer, spr.textures[textureIndex], IntPtr.Zero, ref destRect);
|
||||
SDL.SDL_RenderCopy(renderer, spr.texture, IntPtr.Zero, ref destRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SDL2;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using SDL2;
|
||||
|
||||
namespace OpenDiablo2.SDL2_
|
||||
{
|
||||
@ -16,16 +12,24 @@ namespace OpenDiablo2.SDL2_
|
||||
{
|
||||
static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
internal readonly ImageSet source;
|
||||
private readonly IntPtr renderer;
|
||||
internal IntPtr texture = IntPtr.Zero;
|
||||
|
||||
public Point Location { get; set; } = new Point();
|
||||
public Size FrameSize { get; set; } = new Size();
|
||||
|
||||
private int frame;
|
||||
private int frame = -1;
|
||||
public int Frame
|
||||
{
|
||||
get => frame;
|
||||
set
|
||||
{
|
||||
if (frame == value && texture != IntPtr.Zero)
|
||||
return;
|
||||
|
||||
frame = Math.Max(0, Math.Min(value, TotalFrames));
|
||||
LoadFrame(frame);
|
||||
}
|
||||
}
|
||||
public int TotalFrames { get; internal set; }
|
||||
@ -37,9 +41,7 @@ namespace OpenDiablo2.SDL2_
|
||||
set
|
||||
{
|
||||
blend = value;
|
||||
|
||||
foreach (var texture in textures)
|
||||
SDL.SDL_SetTextureBlendMode(texture, blend ? SDL.SDL_BlendMode.SDL_BLENDMODE_ADD : SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
SDL.SDL_SetTextureBlendMode(texture, blend ? SDL.SDL_BlendMode.SDL_BLENDMODE_ADD : SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,9 +55,7 @@ namespace OpenDiablo2.SDL2_
|
||||
UpdateTextureData();
|
||||
}
|
||||
}
|
||||
internal readonly ImageSet source;
|
||||
private readonly IntPtr renderer;
|
||||
internal IntPtr[] textures = new IntPtr[0];
|
||||
|
||||
|
||||
public SDL2Sprite(ImageSet source, IntPtr renderer)
|
||||
{
|
||||
@ -63,14 +63,8 @@ namespace OpenDiablo2.SDL2_
|
||||
this.renderer = renderer;
|
||||
|
||||
|
||||
this.TotalFrames = source.Frames.Count();
|
||||
this.FrameSize = new Size(Pow2((int)source.Frames.Max(x => x.Width)), Pow2((int)source.Frames.Max(x => x.Height)));
|
||||
this.textures = new IntPtr[TotalFrames];
|
||||
for(var i = 0; i < this.textures.Count(); i++)
|
||||
{
|
||||
this.textures[i] = IntPtr.Zero;
|
||||
}
|
||||
|
||||
TotalFrames = source.Frames.Count();
|
||||
FrameSize = new Size(Pow2((int)source.Frames.Max(x => x.Width)), Pow2((int)source.Frames.Max(x => x.Height)));
|
||||
}
|
||||
|
||||
internal Point GetRenderPoint()
|
||||
@ -84,8 +78,16 @@ namespace OpenDiablo2.SDL2_
|
||||
// TODO: This is slow. Make fix.
|
||||
private void UpdateTextureData()
|
||||
{
|
||||
for (var i = 0; i < source.Frames.Count(); i++)
|
||||
LoadFrame(i, renderer);
|
||||
if (texture == IntPtr.Zero)
|
||||
{
|
||||
texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, Pow2(FrameSize.Width), Pow2(FrameSize.Height));
|
||||
|
||||
if (texture == IntPtr.Zero)
|
||||
throw new ApplicationException("Unaple to initialize texture.");
|
||||
|
||||
Frame = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: Less dumb color correction
|
||||
@ -97,39 +99,41 @@ namespace OpenDiablo2.SDL2_
|
||||
(byte)Math.Min((float)source.B * 1.2, 255)
|
||||
);
|
||||
|
||||
object bob = new object();
|
||||
private void LoadFrame(int index, IntPtr renderer)
|
||||
private unsafe void LoadFrame(int index)
|
||||
{
|
||||
var frame = source.Frames[index];
|
||||
|
||||
if (textures[index] == IntPtr.Zero)
|
||||
textures[index] = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_TARGET, Pow2(FrameSize.Width), Pow2(FrameSize.Height));
|
||||
IntPtr pixels;
|
||||
int pitch;
|
||||
var fullRect = new SDL.SDL_Rect { x = 0, y = 0, w = FrameSize.Width, h = FrameSize.Height };
|
||||
SDL.SDL_SetTextureBlendMode(texture, blend ? SDL.SDL_BlendMode.SDL_BLENDMODE_ADD : SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
|
||||
if (textures[index] == IntPtr.Zero)
|
||||
throw new ApplicationException("Unaple to initialize texture.");
|
||||
|
||||
SDL.SDL_SetTextureBlendMode(textures[index], SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
SDL.SDL_SetRenderTarget(renderer, textures[index]);
|
||||
SDL.SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL.SDL_RenderFillRect(renderer, IntPtr.Zero);
|
||||
SDL.SDL_SetRenderTarget(renderer, IntPtr.Zero);
|
||||
|
||||
var binaryData = new UInt32[frame.Width * frame.Height];
|
||||
for (var y = 0; y < frame.Height; y++)
|
||||
SDL.SDL_LockTexture(texture, IntPtr.Zero, out pixels, out pitch);
|
||||
try
|
||||
{
|
||||
for (int x = 0; x < frame.Width; x++)
|
||||
UInt32* data = (UInt32*)pixels;
|
||||
var frameOffset = FrameSize.Height - frame.Height;
|
||||
for (var y = 0; y < FrameSize.Height; y++)
|
||||
{
|
||||
var palColor = frame.GetColor(x, (int)y, CurrentPalette);
|
||||
//var col = AdjustColor(palColor);
|
||||
binaryData[x + y * frame.Width] = (uint)palColor.ToArgb();
|
||||
for (int x = 0; x < FrameSize.Width; x++)
|
||||
{
|
||||
if ((x >= frame.Width) || (y < frameOffset))
|
||||
{
|
||||
data[x + (y * (pitch / 4))] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
var palColor = frame.GetColor(x, (int)(y - frameOffset), CurrentPalette);
|
||||
//var col = AdjustColor(palColor);
|
||||
data[x + (y * (pitch / 4))] = palColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var rect = new SDL.SDL_Rect { x = 0, y = FrameSize.Height - (int)frame.Height, w = (int)frame.Width, h = (int)frame.Height };
|
||||
GCHandle pinnedArray = GCHandle.Alloc(binaryData, GCHandleType.Pinned);
|
||||
SDL.SDL_UpdateTexture(textures[index], ref rect, pinnedArray.AddrOfPinnedObject(), (int)frame.Width * 4);
|
||||
pinnedArray.Free();
|
||||
finally
|
||||
{
|
||||
SDL.SDL_UnlockTexture(texture);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -144,10 +148,7 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var texture in textures)
|
||||
{
|
||||
SDL.SDL_DestroyTexture(texture);
|
||||
}
|
||||
SDL.SDL_DestroyTexture(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user