Skip to content

Commit

Permalink
Multithreading & fixing protobuf attributes.
Browse files Browse the repository at this point in the history
- Introducing multithreading to decrease processing time.
- fixed attributes where 0 meant something (i.e an item is ground but it's speed is 0)
- fixed memory leak and used propper functions
- introduced attributes

-- PS: this commit is yet restricted to 1098 client version.
  • Loading branch information
slavidodo committed Feb 18, 2019
1 parent f32b7a4 commit 294f5b1
Show file tree
Hide file tree
Showing 7 changed files with 2,253 additions and 997 deletions.
65 changes: 65 additions & 0 deletions OpenTibiaUnity/AsyncGraphics.cs
@@ -0,0 +1,65 @@
using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;

namespace OpenTibiaUnity
{
public class AsyncGraphics
{
Bitmap m_Bitmap;
Graphics m_Graphics;
List<Task> m_DrawTasks = new List<Task>();

// mutex
object m_DrawLock = new object();

public AsyncGraphics(Bitmap bitmap) {
m_Bitmap = bitmap ?? throw new System.ArgumentNullException("Invalid bitmap");
m_Graphics = Graphics.FromImage(m_Bitmap);
}

public void DrawImage(Image image, int x, int y) => m_DrawTasks.Add(Task.Run(() => InternalDraw(image, x, y)));
public void DrawImage(Image image, Point point) => m_DrawTasks.Add(Task.Run(() => InternalDraw(image, point.X, point.Y)));
public void DrawImage(Image image, int x, int y, int w, int h) => m_DrawTasks.Add(Task.Run(() => InternalDraw(image, x, y, w, h)));
public void DrawImage(Image image, Rectangle rect) => m_DrawTasks.Add(Task.Run(() => InternalDraw(image, rect.X, rect.Y, rect.Width, rect.Height)));

public void DrawImages(List<Image> images, List<Point> points) {
if (images.Count != points.Count)
throw new System.ArgumentException("Invalid draw call: points.Count != image.Count");

for (int i = 0; i < images.Count; i++) {
var image = images[i];
var point = points[i];

DrawImage(image, point);
}
}

void InternalDraw(Image image, int x, int y) {
lock (m_DrawLock) {
m_Graphics.DrawImage(image, x, y);
image.Dispose();
}
}

void InternalDraw(Image image, int x, int y, int w, int h) {
lock (m_DrawLock) {
m_Graphics.DrawImage(image, x, y, w, h);
image.Dispose();
}
}

public async Task DisposeOnDone(IEnumerable<Bitmap> bitmaps) {
await Task.WhenAll(m_DrawTasks);
foreach (var bitmap in bitmaps)
bitmap.Dispose();
}

public async Task SaveAndDispose(string filename) {
await Task.WhenAll(m_DrawTasks);
m_Bitmap.Save(filename);
m_Bitmap.Dispose();
m_Graphics.Dispose();
}
}
}
10 changes: 6 additions & 4 deletions OpenTibiaUnity/Core/Sprites/ContentData.cs
Expand Up @@ -18,13 +18,15 @@ public enum ThingCategory : byte
public sealed class ContentData
{
Net.InputMessage m_BinaryReader;
int m_ClientVersion;

public uint DatSignature { get; private set; }
public ushort ContentRevision { get; private set; }
public ThingTypesDict[] ThingTypes { get; private set; } = new ThingTypesDict[(int)ThingCategory.LastCategory];
public ThingTypesDict[] ThingTypeDictionaries { get; private set; } = new ThingTypesDict[(int)ThingCategory.LastCategory];

public ContentData(byte[] buffer) {
public ContentData(byte[] buffer, int clientVersion) {
m_BinaryReader = new Net.InputMessage(buffer);
m_ClientVersion = clientVersion;
}

public void Parse() {
Expand All @@ -43,10 +45,10 @@ public sealed class ContentData
firstId = 100;
}

ThingTypes[category] = new ThingTypesDict();
ThingTypeDictionaries[category] = new ThingTypesDict();
for (ushort id = firstId; id < counts[category]; id++) {
ThingType thingType = ThingType.Serialize(id, (ThingCategory)category, ref m_BinaryReader);
ThingTypes[category][id] = thingType;
ThingTypeDictionaries[category][id] = thingType;
}
}
}
Expand Down
30 changes: 13 additions & 17 deletions OpenTibiaUnity/Core/Sprites/ContentSprites.cs
@@ -1,19 +1,19 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing;

namespace OpenTibiaUnity.Core.Sprites
{
public class ContentSprites
{
Net.InputMessage m_BinaryReader;
bool m_UseAlpha = false;

public uint Signature { get; private set; } = 0;
public uint SpritesCount { get; private set; } = 0;
public int SpritesOffset { get; private set; } = 0;

public ContentSprites(byte[] buffer) {
public ContentSprites(byte[] buffer, bool alpha = false) {
m_BinaryReader = new Net.InputMessage(buffer);
m_UseAlpha = alpha;
}

public void Parse() {
Expand All @@ -23,10 +23,11 @@ public class ContentSprites
}

public Bitmap GetSprite(uint id) {
return RawGetSprite(id);
lock (m_BinaryReader)
return RawGetSprite(id);
}

internal Bitmap RawGetSprite(uint id) {
private Bitmap RawGetSprite(uint id) {
m_BinaryReader.Seek((int)((id-1) * 4) + SpritesOffset);

uint spriteAddress = m_BinaryReader.GetU32();
Expand All @@ -41,11 +42,9 @@ public class ContentSprites

int writePos = 0;
int read = 0;
bool useAlpha = false;
byte channels = (byte)(useAlpha ? 4 : 3);
byte channels = (byte)(m_UseAlpha ? 4 : 3);

Bitmap bitmap = new Bitmap(32, 32);
Graphics gfx = Graphics.FromImage(bitmap);
Color transparentColor = Color.Transparent;

while (read < pixelDataSize && writePos < 4096) {
Expand All @@ -57,23 +56,21 @@ public class ContentSprites
int x = pixel % 32;
int y = pixel / 32;

SolidBrush brush = new SolidBrush(transparentColor);
gfx.FillRectangle(brush, x, y, 1, 1);
bitmap.SetPixel(x, y, transparentColor);
writePos += 4;
}

for (int i = 0; i < coloredPixels && writePos < 4096; i++) {
int r = m_BinaryReader.GetU8();
int g = m_BinaryReader.GetU8();
int b = m_BinaryReader.GetU8();
int a = useAlpha ? m_BinaryReader.GetU8() : 0xFF;
int a = m_UseAlpha ? m_BinaryReader.GetU8() : 0xFF;

int pixel = writePos / 4;
int x = pixel % 32;
int y = pixel / 32;

SolidBrush brush = new SolidBrush(Color.FromArgb(a, r, g, b));
gfx.FillRectangle(brush, x, y, 1, 1);
bitmap.SetPixel(x, y, Color.FromArgb(a, r, g, b));
writePos += 4;
}

Expand All @@ -85,11 +82,10 @@ public class ContentSprites
int x = pixel % 32;
int y = pixel / 32;

SolidBrush brush = new SolidBrush(transparentColor);
gfx.FillRectangle(brush, x, y, 1, 1);
bitmap.SetPixel(x, y, transparentColor);
writePos += 4;
}

return bitmap;
}
}
Expand Down

0 comments on commit 294f5b1

Please sign in to comment.