private void SaveStaticBitmaps(RepeatedField <uint> sprites, ref int start, Assets.ContentSprites sprParser, int width, int height)
        {
            DrawBitmapsDelegate drawFunc;
            int parts      = 0;
            int spritetype = 1;

            if (width == 32 && height == 32)
            {
                drawFunc = DrawBitmap32x32From1_32x32;
                parts    = 1;
            }
            else if (width == 32 && height == 64)
            {
                drawFunc   = DrawBitmap32x64From2_32x32;
                parts      = 2;
                spritetype = 2;
            }
            else if (width == 64 && height == 32)
            {
                drawFunc   = DrawBitmap64x32From2_32x32;
                parts      = 2;
                spritetype = 3;
            }
            else
            {
                drawFunc   = DrawBitmap64x64From4_32x32;
                parts      = 4;
                spritetype = 4;
            }

            int amountInBitmap = Program.BITMAP_SIZE / (32 * 32);
            int totalBitmaps   = (int)Math.Ceiling((double)sprites.Count / amountInBitmap);

            if (totalBitmaps == 0)
            {
                return;
            }

            int localStart = start;

            start += sprites.Count / parts;

            m_Tasks.Add(m_TaskFactory.StartNew(() => InternalSaveStaticBitmaps(sprites, drawFunc, parts, spritetype, localStart, sprParser, width, height)));
        }
        private void SaveSprites(RepeatedField <Appearance> appearances, ref int start, Assets.ContentSprites sprParser)
        {
            RepeatedField <uint>[] sprites = new RepeatedField <uint> [4];
            for (int i = 0; i < 4; i++)
            {
                sprites[i] = new RepeatedField <uint>();
            }
            DeploySprites(appearances, sprites);

            SaveStaticBitmaps(sprites[0], ref start, sprParser, 32, 32);
            SaveStaticBitmaps(sprites[1], ref start, sprParser, 32, 64);
            SaveStaticBitmaps(sprites[2], ref start, sprParser, 64, 32);
            SaveStaticBitmaps(sprites[3], ref start, sprParser, 64, 64);
        }
        public async Task <bool> BeginProcessing()
        {
            string datFile = Path.Combine(m_ClientVersion.ToString(), "Tibia.dat");
            string sprFile = Path.Combine(m_ClientVersion.ToString(), "Tibia.spr");

            if (!File.Exists(datFile) || !File.Exists(sprFile))
            {
                Console.WriteLine("Tibia.dat or Tibia.spr doesn't exist");
                return(false);
            }

            Console.Write("Processing Appearances...");
            var appearances = GenerateAppearances();

            Console.WriteLine("\rProcessing Appearances: Done!");

            // loading tibia.spr into chunks
            Assets.ContentSprites contentSprites;
            try {
                var rawContentSprites = File.ReadAllBytes(sprFile);
                contentSprites = new Assets.ContentSprites(rawContentSprites, m_ClientVersion, m_UseAlpha);
            } catch (Exception e) {
                Console.WriteLine(e.Message + '\n' + e.StackTrace);
                return(false);
            }

            Console.Write("Processing Spritesheets...");
            Directory.CreateDirectory(Path.Combine(m_ClientVersion.ToString(), "result", "sprites"));

            int start = 0;

            SaveSprites(appearances.Outfits, ref start, contentSprites);
            SaveSprites(appearances.Effects, ref start, contentSprites);
            SaveSprites(appearances.Missles, ref start, contentSprites);
            SaveSprites(appearances.Objects, ref start, contentSprites);

            await Task.WhenAll(m_Tasks.ToArray());

            Console.WriteLine("\rProcessing Spritesheets: Done!");

            // saving appearances.dat (with the respective version)
            using (var stream = File.Create(Path.Combine(m_ClientVersion.ToString(), "result", "appearances.dat"))) {
                appearances.WriteTo(stream);
            }

            // saving spritesheets information (catalog-content)
            using (FileStream file = File.Create(Path.Combine(m_ClientVersion.ToString(), "result", "catalog-content.json"))) {
                m_JsonTokens.Sort(ITokenItemSort);

                var catalogJson = new JArray();
                foreach (var token in m_JsonTokens)
                {
                    catalogJson.Add(token.GetJObject());
                }

                string str = catalogJson.ToString();
                file.Write(Encoding.ASCII.GetBytes(str), 0, str.Length);
            }

            return(true);
        }
        private void InternalSaveStaticBitmaps(RepeatedField <uint> sprites, DrawBitmapsDelegate drawFunc, int parts, int spriteType, int localStart, Assets.ContentSprites sprParser, int width, int height)
        {
            int singleSize = width * height;

            AsyncGraphics gfx = new AsyncGraphics(new Bitmap(Program.SEGMENT_DIMENTION, Program.SEGMENT_DIMENTION));
            string        filename;

            int x = 0, y = 0, z = 0;

            for (int i = 0; i < sprites.Count;)
            {
                Bitmap[] bitmapParts = new Bitmap[parts];
                for (int m = 0; m < parts; m++)
                {
                    if (i + m >= sprites.Count)
                    {
                        break;
                    }

                    bitmapParts[m] = sprParser.GetSprite(sprites[i + m]);
                }

                if (y >= Program.SEGMENT_DIMENTION)
                {
                    filename = string.Format("sprites-{0}-{1}.png", localStart, localStart + (Program.BITMAP_SIZE / singleSize) - 1);
                    m_Tasks.Add(gfx.SaveAndDispose(Path.Combine(m_ClientVersion.ToString(), "result", "sprites", filename)));

                    m_JsonTokens.Add(new SpritesToken()
                    {
                        file          = filename,
                        spritetype    = spriteType,
                        firstspriteid = localStart,
                        lastspriteid  = localStart + (Program.BITMAP_SIZE / singleSize) - 1
                    });

                    localStart += Program.BITMAP_SIZE / singleSize;

                    gfx = new AsyncGraphics(new Bitmap(Program.SEGMENT_DIMENTION, Program.SEGMENT_DIMENTION));
                    x   = y = z = 0;
                }

                var tmpSmallBitmaps = bitmapParts;
                drawFunc(gfx, bitmapParts, x, y);
                m_Tasks.Add(gfx.DisposeOnDone(bitmapParts));

                x += width;
                if (x >= Program.SEGMENT_DIMENTION)
                {
                    y += height;
                    x  = 0;
                }

                if (i == sprites.Count)
                {
                    break;
                }

                i = Math.Min(i + parts, sprites.Count);
                z++;
            }

            // save the last gfx
            int end = localStart + z;

            filename = string.Format("sprites-{0}-{1}.png", localStart, end - 1);
            m_Tasks.Add(gfx.SaveAndDispose(Path.Combine(m_ClientVersion.ToString(), "result", "sprites", filename)));

            m_JsonTokens.Add(new SpritesToken()
            {
                file          = filename,
                spritetype    = spriteType,
                firstspriteid = localStart,
                lastspriteid  = end - 1
            });
        }
        public async Task <bool> BeginProcessing()
        {
            string datFile = Path.Combine(m_ClientVersion.ToString(), "Tibia.dat");
            string sprFile = Path.Combine(m_ClientVersion.ToString(), "Tibia.spr");

            if (!File.Exists(datFile) || !File.Exists(sprFile))
            {
                Console.WriteLine("Tibia.dat or Tibia.spr doesn't exist");
                return(false);
            }

            Console.Write("Processing Appearances...");
            var appearances = GenerateAppearances();

            Console.WriteLine("\rProcessing Appearances: Done!");

            // loading tibia.spr into chunks
            Assets.ContentSprites contentSprites;
            try {
                var rawContentSprites = File.ReadAllBytes(sprFile);
                contentSprites = new Assets.ContentSprites(rawContentSprites, m_ClientVersion, m_UseAlpha);
            } catch (Exception e) {
                Console.WriteLine(e.Message + '\n' + e.StackTrace);
                return(false);
            }

            string resultPath = Path.Combine(m_ClientVersion.ToString(), "result");

            Console.Write("Processing Spritesheets...");
            Directory.CreateDirectory(Path.Combine(resultPath, "sprites"));

            int start = 0;

            SaveSprites(appearances.Outfits, ref start, contentSprites);
            SaveSprites(appearances.Effects, ref start, contentSprites);
            SaveSprites(appearances.Missles, ref start, contentSprites);
            SaveSprites(appearances.Objects, ref start, contentSprites);

            await Task.WhenAll(m_Tasks.ToArray());

            Console.WriteLine("\rProcessing Spritesheets: Done!");

            // saving appearances.dat (with the respective version)
            using (var stream = File.Create(Path.Combine(resultPath, "appearances.otud"))) {
                appearances.WriteTo(stream);
            }

            // save spritesheets
            using (var spriteStream = new FileStream(Path.Combine(resultPath, "assets.otus"), FileMode.Create))
                using (var binaryWriter = new BinaryWriter(spriteStream)) {
                    m_SpriteSheet.Sort((a, b) => {
                        return(a.FirstSpriteID.CompareTo(b.FirstSpriteID));
                    });

                    binaryWriter.Write((uint)m_SpriteSheet.Count);
                    uint index = 0;
                    foreach (var spriteType in m_SpriteSheet)
                    {
                        spriteType.AtlasID = index++;

                        var buffer = File.ReadAllBytes(Path.Combine(resultPath, "sprites", spriteType.File));
                        binaryWriter.Write(spriteType.AtlasID);
                        binaryWriter.Write((ushort)spriteType.SpriteType);
                        binaryWriter.Write(spriteType.FirstSpriteID);
                        binaryWriter.Write(spriteType.LastSpriteID);

                        binaryWriter.Write((uint)buffer.Length);
                        binaryWriter.Write(buffer);
                    }
                }

            Directory.Delete(Path.Combine(resultPath, "sprites"), true);
            return(true);
        }