Example #1
0
        private void OpenClick(object sender, EventArgs e)
        {
            try
            {
                var dlg = openFileDialog.ShowDialog();
                if (dlg != DialogResult.OK)
                    return;

                var file = openFileDialog.OpenFile();

                using (var blp = new BlpFile(file))
                {
                    bmp = blp.GetBitmap(0);
                }

                var graphics = panel1.CreateGraphics();
                graphics.Clear(panel1.BackColor);
                graphics.DrawImage(bmp, 0, 0);

                button3.Enabled = true;                
            }
            catch (FileNotFoundException fe)
            {
                MessageBox.Show("The 'example.blp' was not found!");
            }
        }
Example #2
0
        public override void Work()
        {
            bool success = false;

            try
            {
                foreach (string path in paths)
                {
                    string newFile = Path.Combine(dest, Path.GetFileNameWithoutExtension(path) + ".png");
                    Log.Write("Exporting {0} -> {1}", path, newFile);

                    using (BlpFile blp = new BlpFile(File.OpenRead(path)))
                    {
                        Bitmap bmp = blp.GetBitmap(0);
                        bmp.Save(newFile, ImageFormat.Png);
                        bmp.Dispose();
                    }
                }
                success = true;
            }
            catch (Exception e)
            {
                // We have failed, the elders will be disappointed.
                Log.Write("BLP to PNG export failed: {0}.", e.Message);
            }

            EventManager.Trigger_ExportBLPtoPNGComplete(success);
        }
Example #3
0
        private void displayImage(string file)
        {
            currentImage = null;
            UI_PreviewStatus.Hide();

            using (var blp = new BlpFile(File.OpenRead(file)))
                currentImage = blp.GetBitmap(0);

            Graphics gfx = UI_ImagePreview.CreateGraphics();
            gfx.Clear(UI_ImagePreview.BackColor);
            gfx.DrawImage(currentImage, 0, 0);
            UI_ExportButton.Show();

            currentImageName = file;
        }
Example #4
0
        public void addTexture(int extID, string file)
        {
            int width = 0;
            int height = 0;
            byte[] data = null;

            fileMapping.Add(extID, file);

            using (BlpFile raw = new BlpFile(File.OpenRead(file)))
            {
                Bitmap bitmap = raw.GetBitmap(0);
                width = bitmap.Width;
                height = bitmap.Height;

                int length = width * height * 4;
                var rawData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                data = new byte[length];

                Marshal.Copy(rawData.Scan0, data, 0, length);
                bitmap.UnlockBits(rawData);
                bitmap.Dispose();
            }

            uint[] intID = new uint[1];
            gl.GenTextures(1, intID);

            gl.BindTexture(OpenGL.GL_TEXTURE_2D, intID[0]);
            gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA, width, height, 0, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, data);

            gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR);
            gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR_MIPMAP_LINEAR);

            mapping.Add(extID, intID);
            gl.GenerateMipmapEXT(OpenGL.GL_TEXTURE_2D);

            Log.Write("TextureManager: {0} assigned to GL with @ {1}", file, intID[0]);
        }
Example #5
0
        public async void UpdateMainWindowIcons(double margin)
        {
            if (adapter == null || main.selectedID == 0)               // adapter.query below caused unhandled exception with main.selectedID as 0.
            {
                return;
            }

            DataRow res;

            try
            {
                res = adapter.query(string.Format("SELECT `SpellIconID`,`ActiveIconID` FROM `{0}` WHERE `ID` = '{1}'", adapter.Table, main.selectedID)).Rows[0];
            }
            catch (Exception)
            {
                return;
            }
            UInt32 iconInt        = UInt32.Parse(res[0].ToString());
            UInt32 iconActiveInt  = UInt32.Parse(res[1].ToString());
            UInt32 selectedRecord = UInt32.MaxValue;

            for (UInt32 i = 0; i < header.RecordCount; ++i)
            {
                if (body.records[i].ID == iconInt)
                {
                    selectedRecord = i;

                    break;
                }

                if (body.records[i].ID == iconActiveInt)
                {
                    selectedRecord = i;

                    break;
                }
            }

            string icon = "";

            int offset = 0;

            try
            {
                if (selectedRecord == UInt32.MaxValue)
                {
                    throw new Exception("The icon for this spell does not exist in the SpellIcon.dbc");
                }

                offset = (int)body.records[selectedRecord].Name;

                while (body.StringBlock[offset] != '\0')
                {
                    icon += body.StringBlock[offset++];
                }

                if (!File.Exists(icon + ".blp"))
                {
                    throw new Exception("File could not be found: " + "Icons\\" + icon + ".blp");
                }
            }

            catch (Exception ex)
            {
                main.Dispatcher.Invoke(new Action(() => main.HandleErrorMessage(ex.Message)));

                return;
            }

            FileStream fileStream = new FileStream(icon + ".blp", FileMode.Open);

            SereniaBLPLib.BlpFile image;

            image = new SereniaBLPLib.BlpFile(fileStream);

            Bitmap bit = image.getBitmap(0);

            await Task.Factory.StartNew(() =>
            {
                main.CurrentIcon.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bit.GetHbitmap(), IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(bit.Width, bit.Height));
            }, CancellationToken.None, TaskCreationOptions.None, main.UIScheduler);

            image.close();
            fileStream.Close();

            if (!loadedAllIcons)
            {
                loadedAllIcons = true;

                int currentOffset = 1;

                string[] icons = body.StringBlock.Split('\0');

                int iconIndex   = 0;
                int columnsUsed = icons.Length / 11;
                int rowsToDo    = columnsUsed / 2;

                for (int j = -rowsToDo; j <= rowsToDo; ++j)
                {
                    for (int i = -5; i < 6; ++i)
                    {
                        ++iconIndex;
                        if (iconIndex >= icons.Length - 1)
                        {
                            break;
                        }
                        int this_icons_offset = currentOffset;

                        currentOffset += icons[iconIndex].Length + 1;

                        if (!File.Exists(icons[iconIndex] + ".blp"))
                        {
                            Console.WriteLine("Warning: Icon not found: " + icons[iconIndex] + ".blp");

                            continue;
                        }

                        bool loaded = false;
                        try
                        {
                            fileStream = new FileStream(icons[iconIndex] + ".blp", FileMode.Open);
                            image      = new BlpFile(fileStream);
                            bit        = image.getBitmap(0);
                            loaded     = true;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"Error loading image, unsupported BLP format: {icons[iconIndex]}.blp\n{e.Message}\n{e}");
                        }
                        if (!loaded)
                        {
                            image?.close();
                            fileStream?.Close();
                            continue;
                        }

                        await Task.Factory.StartNew(() =>
                        {
                            System.Windows.Controls.Image temp = new System.Windows.Controls.Image();

                            temp.Width               = iconSize == null ? 32 : iconSize.Value;
                            temp.Height              = iconSize == null ? 32 : iconSize.Value;
                            temp.Margin              = iconMargin == null ? new System.Windows.Thickness(margin, 0, 0, 0) : iconMargin.Value;
                            temp.VerticalAlignment   = VerticalAlignment.Top;
                            temp.HorizontalAlignment = HorizontalAlignment.Left;
                            temp.Source              = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bit.GetHbitmap(), IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(bit.Width, bit.Height));
                            temp.Name       = "Index_" + this_icons_offset;
                            temp.ToolTip    = icons[iconIndex];
                            temp.MouseDown += this.ImageDown;

                            main.IconGrid.Children.Add(temp);
                        }, CancellationToken.None, TaskCreationOptions.None, main.UIScheduler);

                        image.close();
                        fileStream.Close();
                    }
                }
            }
        }
Example #6
0
    static int RunAndReturnExitCode(Options opts)
    {
        if (!Directory.Exists(opts.OutputPath))
        {
            Directory.CreateDirectory(opts.OutputPath);
        }

        CASCHandler cascHandler;

        if (opts.UseOnline)
        {
            cascHandler = CASCHandler.OpenOnlineStorage(opts.OnlineProduct, opts.OnlineRegion);
        }
        else if (opts.StoragePath != null)
        {
            cascHandler = CASCHandler.OpenLocalStorage(opts.StoragePath);
        }
        else
        {
            throw new Exception("StoragePath required if not using online mode!");
        }
        cascHandler.Root.SetFlags(LocaleFlags.All_WoW, ContentFlags.None);

        foreach (var map in opts.Maps)
        {
            try
            {
                Console.WriteLine("-- processing {0}", map);

                System.Drawing.Bitmap[,] tiles = new System.Drawing.Bitmap[64, 64];
                bool[,] had_tile        = new bool[64, 64];
                bool[,] wdt_claims_tile = new bool[64, 64];

                var wdt_name = Path.Combine("world", "maps", map, String.Format("{0}.wdt", map));
                try
                {
                    using (Stream stream = cascHandler.OpenFile(wdt_name))
                    {
                        using (BinaryReader reader = new BinaryReader(stream))
                        {
                            while (reader.BaseStream.Position != reader.BaseStream.Length)
                            {
                                var magic = reader.ReadUInt32();
                                var size  = reader.ReadUInt32();
                                var pos   = reader.BaseStream.Position;

                                if (magic == mk("MPHD"))
                                {
                                    var flags = reader.ReadUInt32();

                                    if ((flags & 1) == 1)
                                    {
                                        throw new Exception("map claims to be WMO only, skipping!");
                                    }
                                }
                                else if (magic == mk("MAIN"))
                                {
                                    for (int x = 0; x < 64; ++x)
                                    {
                                        for (int y = 0; y < 64; ++y)
                                        {
                                            wdt_claims_tile[y, x] = (reader.ReadUInt32() & 1) == 1;
                                            reader.ReadUInt32();
                                        }
                                    }
                                }

                                reader.BaseStream.Position = pos + size;
                            }
                        }
                    }
                }
                catch (FileNotFoundException)
                {
                    throw new Exception(String.Format("failed loading {0}, skipping!", wdt_name));
                }

                var tile_size = 256;

                for (int x = 0; x < 64; ++x)
                {
                    for (int y = 0; y < 64; ++y)
                    {
                        had_tile[x, y] = false;

                        try
                        {
                            var blp_name = Path.Combine("world", "minimaps", map, String.Format("map{0:00}_{1:00}.blp", x, y));
                            using (Stream stream = cascHandler.OpenFile(blp_name))
                            {
                                var blp = new SereniaBLPLib.BlpFile(stream);
                                tiles[x, y] = blp.GetBitmap(0);

                                if (tiles[x, y].Height != tiles[x, y].Width)
                                {
                                    throw new Exception("non-square minimap?!");
                                }
                            }
                            had_tile[x, y] = true;
                        }
                        catch (FileNotFoundException)
                        {
                            tiles[x, y] = new System.Drawing.Bitmap(tile_size, tile_size);
                        }

                        var size_per_mcnk = tiles[x, y].Height / 16f;

                        var g = System.Drawing.Graphics.FromImage(tiles[x, y]);

                        var impassable_brush = new System.Drawing.Drawing2D.HatchBrush
                                                   (System.Drawing.Drawing2D.HatchStyle.DiagonalCross
                                                   , System.Drawing.Color.FromArgb(255 / 2, System.Drawing.Color.Yellow)
                                                   , System.Drawing.Color.FromArgb(255 / 2, System.Drawing.Color.Red)
                                                   );
                        var wdt_border_brush = new System.Drawing.Drawing2D.HatchBrush
                                                   (System.Drawing.Drawing2D.HatchStyle.DiagonalCross
                                                   , System.Drawing.Color.FromArgb(255 / 2, System.Drawing.Color.DarkBlue)
                                                   , System.Drawing.Color.FromArgb(255 / 2, System.Drawing.Color.Red)
                                                   );
                        var wdt_border_pen = new System.Drawing.Pen
                                                 (wdt_border_brush, size_per_mcnk);
                        var unreferenced_brush = new System.Drawing.Drawing2D.HatchBrush
                                                     (System.Drawing.Drawing2D.HatchStyle.DiagonalCross
                                                     , System.Drawing.Color.FromArgb(255 / 2, System.Drawing.Color.DarkBlue)
                                                     , System.Drawing.Color.FromArgb(255 / 2, System.Drawing.Color.Green)
                                                     );

                        try
                        {
                            var adt_name = Path.Combine("World", "Maps", map, String.Format("{0}_{1}_{2}.adt", map, x, y));
                            using (Stream stream = cascHandler.OpenFile(adt_name))
                            {
                                using (BinaryReader reader = new BinaryReader(stream))
                                {
                                    while (reader.BaseStream.Position != reader.BaseStream.Length)
                                    {
                                        var magic = reader.ReadUInt32();
                                        var size  = reader.ReadUInt32();
                                        var pos   = reader.BaseStream.Position;

                                        if (magic == mk("MCNK"))
                                        {
                                            var flags = reader.ReadUInt32();
                                            var sub_x = reader.ReadUInt32();
                                            var sub_y = reader.ReadUInt32();
                                            if ((flags & 2) == 2)
                                            {
                                                g.FillRectangle(impassable_brush, size_per_mcnk * sub_x, size_per_mcnk * sub_y, size_per_mcnk, size_per_mcnk);
                                            }
                                        }

                                        reader.BaseStream.Position = pos + size;
                                    }
                                }
                            }
                            had_tile[x, y] = true;
                        }
                        catch (FileNotFoundException)
                        {
                            g.FillRectangle(wdt_border_brush, 0, 0, tiles[x, y].Height, tiles[x, y].Height);
                        }

                        if (wdt_claims_tile[x, y])
                        {
                            if (x == 0 || !wdt_claims_tile[x - 1, y])
                            {
                                g.DrawLine(wdt_border_pen, 0, 0, 0, tiles[x, y].Height);
                            }
                            if (x == 63 || !wdt_claims_tile[x + 1, y])
                            {
                                g.DrawLine(wdt_border_pen, tiles[x, y].Height, 0, tiles[x, y].Height, tiles[x, y].Height);
                            }
                            if (y == 0 || !wdt_claims_tile[x, y - 1])
                            {
                                g.DrawLine(wdt_border_pen, 0, 0, tiles[x, y].Height, 0);
                            }
                            if (y == 63 || !wdt_claims_tile[x, y + 1])
                            {
                                g.DrawLine(wdt_border_pen, 0, tiles[x, y].Height, tiles[x, y].Height, tiles[x, y].Height);
                            }
                        }
                        else if (had_tile[x, y])
                        {
                            g.FillRectangle(unreferenced_brush, 0, 0, tiles[x, y].Height, tiles[x, y].Height);
                        }
                    }
                }

                int min_x = 64;
                int min_y = 64;
                int max_x = -1;
                int max_y = -1;

                for (int x = 0; x < 64; ++x)
                {
                    for (int y = 0; y < 64; ++y)
                    {
                        if (had_tile[x, y])
                        {
                            min_x = Math.Min(min_x, x);
                            min_y = Math.Min(min_y, y);
                            max_x = Math.Max(max_x, x + 1);
                            max_y = Math.Max(max_y, y + 1);
                        }
                    }
                }

                var overall          = new System.Drawing.Bitmap(tile_size * (max_x - min_x), tile_size * (max_y - min_y));
                var overall_graphics = System.Drawing.Graphics.FromImage(overall);

                for (int x = min_x; x <= max_x; ++x)
                {
                    for (int y = min_y; y <= max_y; ++y)
                    {
                        if (had_tile[x, y])
                        {
                            overall_graphics.DrawImage(tiles[x, y], (x - min_x) * tile_size, (y - min_y) * tile_size, tile_size, tile_size);
                        }
                    }
                }

                var output_file = Path.Combine(opts.OutputPath, String.Format("{0}.png", map));
                System.IO.File.Delete(output_file);
                overall.Save(output_file, System.Drawing.Imaging.ImageFormat.Png);
            }
            catch (Exception ex)
            {
                Console.WriteLine("--- {0}", ex.Message);
            }
        }

        return(0);
    }
Example #7
0
 private void PreviewBlp(CASCFile file)
 {
     using (var stream = _casc.OpenFile(file.Hash))
     {
         var blp = new BlpFile(stream);
         var bitmap = blp.GetBitmap(0);
         var form = new ImagePreviewForm(bitmap);
         form.Show();
     }
 }
Example #8
0
        public override void Work()
        {
            LogWrite("Beginning export of {0}...", mapName);

            TextureBox texProvider = new TextureBox();
            WaveFrontWriter ob = new WaveFrontWriter(fileName, texProvider, true, true, false);

            try
            {
                if (!Program.IsCASCReady)
                    throw new MapExportException("CASC file engine is not loaded.");

                string wdtPath = string.Format(@"World\Maps\{0}\{0}.wdt", mapName);
                Program.CASCEngine.SaveFileTo(wdtPath, Constants.TEMP_DIRECTORY);

                WDTFile headerFile = new WDTFile(Path.Combine(Constants.TEMP_DIRECTORY, wdtPath));
                headerFile.parse();

                if (!headerFile.Chunks.Any(c => c.ChunkID == Formats.WDT.Chunk_MPHD.Magic))
                    throw new MapExportException("Invalid map header (WDT)");

                // ToDo: Check if world WMO exists and load it.

                // Ensure we have a MAIN chunk before trying to process terrain.
                Formats.WDT.Chunk_MAIN mainChunk = (Formats.WDT.Chunk_MAIN)headerFile.Chunks.Where(c => c.ChunkID == Formats.WDT.Chunk_MAIN.Magic).FirstOrDefault();
                Formats.WDT.Chunk_MPHD headerChunk = (Formats.WDT.Chunk_MPHD)headerFile.Chunks.Where(c => c.ChunkID == Formats.WDT.Chunk_MPHD.Magic).FirstOrDefault();

                if (mainChunk != null && headerChunk != null)
                {
                    // Pre-calculate UV mapping for terrain.
                    UV[,,] uvMaps = new UV[8,8,5];
                    for (int x = 0; x < 8; x++)
                    {
                        for (int y = 0; y < 8; y++)
                        {
                            float uTL = 1 - (0.125f * x);
                            float vTL = 1 - (0.125f * y);
                            float uBR = uTL - 0.125f;
                            float vBR = vTL - 0.125f;

                            int aX = 7 - x;
                            uvMaps[aX, y, 0] = new UV(uBR, vTL); // TL
                            uvMaps[aX, y, 1] = new UV(uBR, vBR); // TR
                            uvMaps[aX, y, 2] = new UV(uTL, vTL); // BL
                            uvMaps[aX, y, 3] = new UV(uTL, vBR); // BR
                            uvMaps[aX, y, 4] = new UV(uTL - 0.0625f, vTL - 0.0625f);
                        }
                    }

                    int meshIndex = 1;
                    int wmoIndex = 1;

                    // Create a directory for map data (alpha maps, etc).
                    string dataDirRaw = string.Format("{0}.data", Path.GetFileNameWithoutExtension(fileName));
                    string dataDir = Path.Combine(Path.GetDirectoryName(fileName), dataDirRaw);

                    if (!Directory.Exists(dataDir))
                        Directory.CreateDirectory(dataDir);

                    Dictionary<byte[], uint> texCache = new Dictionary<byte[], uint>(new ByteArrayComparer());

                    for (int y = 0; y < 64; y++)
                    {
                        for (int x = 0; x < 64; x++)
                        {
                            if (mainChunk.map[x, y] && ShouldInclude(x, y))
                            {
                                string pathBase = string.Format(@"World\Maps\{0}\{0}_{1}_{2}", mapName, x, y);
                                string adtPath = pathBase + ".adt";
                                string texPath = pathBase + "_tex0.adt";
                                string objPath = pathBase + "_obj0.adt";

                                Program.CASCEngine.SaveFileTo(adtPath, Constants.TEMP_DIRECTORY);
                                Program.CASCEngine.SaveFileTo(texPath, Constants.TEMP_DIRECTORY);
                                Program.CASCEngine.SaveFileTo(objPath, Constants.TEMP_DIRECTORY);

                                string adtTempPath = Path.Combine(Constants.TEMP_DIRECTORY, adtPath);
                                string texTempPath = Path.Combine(Constants.TEMP_DIRECTORY, texPath);
                                string objTempPath = Path.Combine(Constants.TEMP_DIRECTORY, objPath);

                                try
                                {
                                    ADTFile adt = new ADTFile(adtTempPath, ADTFileType.ROOT);
                                    adt.parse();

                                    ADTFile tex = new ADTFile(texTempPath, ADTFileType.TEX);
                                    tex.parse();

                                    ADTFile obj = new ADTFile(objTempPath, ADTFileType.OBJ);
                                    obj.parse();

                                    // Textures
                                    Chunk_MTEX texChunk = (Chunk_MTEX)tex.getChunk(Chunk_MTEX.Magic);

                                    uint texIndex = 0;
                                    Bitmap[] textureData = new Bitmap[texChunk.textures.count()];
                                    foreach (KeyValuePair<int, string> texture in texChunk.textures.raw())
                                    {
                                        string texFile = texture.Value;
                                        string tempPath = Path.Combine(Constants.TEMP_DIRECTORY, texFile);

                                        if (!File.Exists(tempPath))
                                            Program.CASCEngine.SaveFileTo(texFile, Constants.TEMP_DIRECTORY);

                                        using (BlpFile blp = new BlpFile(File.OpenRead(tempPath)))
                                            textureData[texIndex] = blp.GetBitmap(0);

                                        texIndex++;
                                    }

                                    Chunk_MCNK[] soupChunks = adt.getChunksByID(Chunk_MCNK.Magic).Cast<Chunk_MCNK>().ToArray();
                                    Chunk_MCNK[] layerChunks = tex.getChunksByID(Chunk_MCNK.Magic).Cast<Chunk_MCNK>().ToArray();

                                    // Terrain
                                    for (int i = 0; i < 256; i++)
                                    {
                                        Chunk_MCNK soupChunk = soupChunks[i];
                                        Chunk_MCNK layerChunk = layerChunks[i];

                                        // Terrain chunks
                                        Chunk_MCVT hmChunk = (Chunk_MCVT)soupChunk.getChunk(Chunk_MCVT.Magic);
                                        Chunk_MCNR nChunk = (Chunk_MCNR)soupChunk.getChunk(Chunk_MCNR.Magic);

                                        // Texture chunks
                                        Chunk_MCLY layers = (Chunk_MCLY)layerChunk.getChunk(Chunk_MCLY.Magic);

                                        // Alpha mapping
                                        Chunk_MCAL alphaMapChunk = (Chunk_MCAL)layerChunk.getChunk(Chunk_MCAL.Magic, false);

                                        string texFileName = string.Format("baked_{0}_{1}_{2}.png", x, y, i);
                                        string texFilePath = Path.Combine(dataDir, texFileName);

                                        EventManager.Trigger_LoadingPrompt(string.Format("Rendering tile {0} at {1},{2}...", i + 1, x, y));
                                        uint texFaceIndex = 0;

                                        if (!File.Exists(texFilePath))
                                        {
                                            Bitmap bmpBase = new Bitmap(layers.layers.Length > 0 ? textureData[layers.layers[0].textureID] : blank);
                                            using (Graphics baseG = Graphics.FromImage(bmpBase))
                                            using (ImageAttributes att = new ImageAttributes())
                                            {
                                                att.SetWrapMode(WrapMode.TileFlipXY);
                                                baseG.CompositingQuality = CompositingQuality.HighQuality;
                                                baseG.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                                baseG.CompositingMode = CompositingMode.SourceOver;

                                                for (int mI = 1; mI < layers.layers.Length; mI++) // First layer never has an alpha map
                                                {
                                                    byte[,] alphaMap;
                                                    MCLYLayer layer = layers.layers[mI];
                                                    bool headerFlagSet = ((headerChunk.flags & 0x4) == 0x4) || ((headerChunk.flags & 0x80) == 0x80);
                                                    bool layerFlagSet = ((layer.flags & 0x200) == 0x200);
                                                    bool fixAlphaMap = !((soupChunk.flags & 0x200) == 0x200);

                                                    if (layerFlagSet)
                                                        alphaMap = alphaMapChunk.parse(Chunk_MCAL.CompressType.COMPRESSED, layer.ofsMCAL, fixAlphaMap);
                                                    else
                                                        alphaMap = alphaMapChunk.parse(headerFlagSet ? Chunk_MCAL.CompressType.UNCOMPRESSED_4096 : Chunk_MCAL.CompressType.UNCOMPRESSED_2048, layer.ofsMCAL, fixAlphaMap);

                                                    Bitmap bmpRawTex = textureData[layer.textureID];
                                                    Bitmap bmpAlphaMap = new Bitmap(64, 64);
                                                    for (int drawX = 0; drawX < 64; drawX++)
                                                        for (int drawY = 0; drawY < 64; drawY++)
                                                            bmpAlphaMap.SetPixel(drawX, drawY, Color.FromArgb(alphaMap[drawX, drawY], 0, 0, 0));

                                                    Bitmap bmpAlphaMapScaled = new Bitmap(bmpRawTex.Width, bmpRawTex.Height);
                                                    using (Graphics g = Graphics.FromImage(bmpAlphaMapScaled))
                                                    {
                                                        g.CompositingQuality = CompositingQuality.HighQuality;
                                                        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                                        g.CompositingMode = CompositingMode.SourceCopy;
                                                        g.DrawImage(bmpAlphaMap, new Rectangle(0, 0, bmpAlphaMapScaled.Width, bmpAlphaMapScaled.Height), 0, 0, bmpAlphaMap.Width, bmpAlphaMap.Height, GraphicsUnit.Pixel, att);
                                                    }
                                                    bmpAlphaMap.Dispose();

                                                    Bitmap bmpTex = new Bitmap(bmpRawTex.Width, bmpRawTex.Height);
                                                    for (int drawX = 0; drawX < bmpRawTex.Width; drawX++)
                                                    {
                                                        for (int drawY = 0; drawY < bmpRawTex.Height; drawY++)
                                                        {
                                                            // Hacky fix to flip the texture.
                                                            // Remove this if we fix the terrain read-order.
                                                            int sourceX = (bmpRawTex.Width - 1) - drawX;
                                                            //int sourceY = (bmpRawTex.Height - 1) - drawY;

                                                            bmpTex.SetPixel(sourceX, drawY, Color.FromArgb(
                                                                bmpAlphaMapScaled.GetPixel(drawX, drawY).A,
                                                                bmpRawTex.GetPixel(drawX, drawY).R,
                                                                bmpRawTex.GetPixel(drawX, drawY).G,
                                                                bmpRawTex.GetPixel(drawX, drawY).B
                                                            ));
                                                        }
                                                    }
                                                    bmpAlphaMapScaled.Dispose();
                                                    baseG.DrawImage(bmpTex, 0, 0, bmpBase.Width, bmpBase.Height);
                                                }

                                                using (MemoryStream str = new MemoryStream())
                                                using (MD5 md5 = MD5.Create())
                                                {
                                                    bmpBase.Save(str, ImageFormat.Png);
                                                    byte[] raw = md5.ComputeHash(str.ToArray());
                                                    uint cacheID;

                                                    if (texCache.TryGetValue(raw, out cacheID))
                                                    {
                                                        // Cache found, use that instead.
                                                        texFaceIndex = cacheID;
                                                    }
                                                    else
                                                    {
                                                        // No cache found, store new.
                                                        bmpBase.Save(texFilePath);
                                                        texProvider.addTexture(-1, Path.Combine(dataDirRaw, texFileName));
                                                        cacheID = (uint)texProvider.LastIndex;

                                                        texFaceIndex = cacheID;
                                                        texCache.Add(raw, cacheID);
                                                    }
                                                }
                                                bmpBase.Dispose();
                                            }
                                        }

                                        Mesh mesh = new Mesh("Terrain Mesh #" + meshIndex);
                                        meshIndex++;

                                        int v = 0;

                                        float pX = soupChunk.position.X;
                                        float pY = -soupChunk.position.Y;
                                        float pZ = soupChunk.position.Z;

                                        int ofs = 10;
                                        for (int sX = 8; sX > 0; sX--)
                                        {
                                            for (int sY = 1; sY < 9; sY++)
                                            {
                                                int cIndex = ofs - 1;
                                                int blIndex = cIndex - 9;
                                                int tlIndex = cIndex + 8;

                                                float tr = hmChunk.vertices[tlIndex + 1];
                                                float tl = hmChunk.vertices[tlIndex];
                                                float br = hmChunk.vertices[blIndex + 1];
                                                float bl = hmChunk.vertices[blIndex];
                                                float c = hmChunk.vertices[cIndex];

                                                float oX = pX + (sX * ADTFile.TILE_SIZE);
                                                float oY = pY + (sY * ADTFile.TILE_SIZE);

                                                // Apply UV mapping
                                                for (int uv = 0; uv < 5; uv++)
                                                    mesh.addUV(uvMaps[sX - 1, sY - 1, uv]);

                                                // Apply verts
                                                mesh.addVert(new Position(oX, tl + pZ, oY));
                                                mesh.addVert(new Position(oX, tr + pZ, oY + ADTFile.TILE_SIZE));
                                                mesh.addVert(new Position(oX + ADTFile.TILE_SIZE, bl + pZ, oY));
                                                mesh.addVert(new Position(oX + ADTFile.TILE_SIZE, br + pZ, oY + ADTFile.TILE_SIZE));
                                                mesh.addVert(new Position(oX + (ADTFile.TILE_SIZE / 2), c + pZ, oY + (ADTFile.TILE_SIZE / 2)));

                                                // Normals
                                                mesh.addNormal(nChunk.normals[tlIndex]);
                                                mesh.addNormal(nChunk.normals[tlIndex + 1]);
                                                mesh.addNormal(nChunk.normals[blIndex]);
                                                mesh.addNormal(nChunk.normals[blIndex + 1]);
                                                mesh.addNormal(nChunk.normals[cIndex]);

                                                // Faces
                                                mesh.addFace(texFaceIndex, v, v + 2, v + 4);
                                                mesh.addFace(texFaceIndex, v + 1, v + 3, v + 4);
                                                mesh.addFace(texFaceIndex, v, v + 1, v + 4);
                                                mesh.addFace(texFaceIndex, v + 2, v + 3, v + 4);

                                                v += 5;
                                                ofs += 1;
                                            }
                                            ofs += 9;
                                        }

                                        ob.addMesh(mesh);
                                    }

                                    // Parse WMO objects that appear in the world.
                                    EventManager.Trigger_LoadingPrompt("Constructing buildings...");

                                    Chunk_MWID wmoIndexChunk = (Chunk_MWID)obj.getChunk(Chunk_MWID.Magic, false);
                                    Chunk_MWMO wmoModelChunk = (Chunk_MWMO)obj.getChunk(Chunk_MWMO.Magic, false);
                                    Chunk_MODF wmoRefChunk = (Chunk_MODF)obj.getChunk(Chunk_MODF.Magic, false);

                                    if (wmoIndexChunk != null && wmoModelChunk != null && wmoRefChunk != null)
                                    {
                                        foreach (Chunk_MODF.MODFEntry entry in wmoRefChunk.entries)
                                        {
                                            string wmoModel = wmoModelChunk.objects.get((int)wmoIndexChunk.offsets[entry.entry]);
                                            List<CASCFile> groupSearch = CASCSearch.Search(Path.Combine(Path.GetDirectoryName(wmoModel), Path.GetFileNameWithoutExtension(wmoModel)), CASCSearch.SearchType.STARTS_WITH);

                                            if (groupSearch.Count > 0)
                                            {
                                                // Set-up root/group files for the WMO.
                                                WMOFile wmo = null;
                                                List<WMOFile> groupFiles = new List<WMOFile>(groupSearch.Count - 1);
                                                string rootName = Path.GetFileName(wmoModel).ToLower();

                                                foreach (CASCFile file in groupSearch)
                                                {
                                                    Program.CASCEngine.SaveFileTo(file.FullName, Constants.TEMP_DIRECTORY);
                                                    string tempPath = Path.Combine(Constants.TEMP_DIRECTORY, file.FullName);

                                                    if (file.FullName.ToLower().EndsWith(rootName))
                                                        wmo = new WMOFile(tempPath, true);
                                                    else
                                                        groupFiles.Add(new WMOFile(tempPath, false));
                                                }

                                                foreach (WMOFile groupFile in groupFiles)
                                                    wmo.addGroupFile(groupFile);

                                                groupFiles.Clear();
                                                wmo.parse();

                                                // Export/register textures needed for this WMO.
                                                Formats.WMO.Chunk_MOTX wmoTexChunk = (Formats.WMO.Chunk_MOTX)wmo.getChunk(Formats.WMO.Chunk_MOTX.Magic);
                                                Dictionary<int, int> wmoTexMap = new Dictionary<int, int>();

                                                foreach (KeyValuePair<int, string> node in wmoTexChunk.textures.raw())
                                                {
                                                    string tempPath = Path.Combine(Constants.TEMP_DIRECTORY, node.Value);
                                                    string dumpPath = Path.Combine(Path.GetDirectoryName(node.Value), Path.GetFileNameWithoutExtension(node.Value) + ".png");

                                                    // Extract
                                                    if (!File.Exists(tempPath))
                                                        Program.CASCEngine.SaveFileTo(node.Value, Constants.TEMP_DIRECTORY);

                                                    // Convert
                                                    using (BlpFile blp = new BlpFile(File.OpenRead(tempPath)))
                                                    using (Bitmap bmp = blp.GetBitmap(0))
                                                    {
                                                        string dumpLoc = Path.Combine(dataDir, dumpPath);
                                                        Directory.CreateDirectory(Path.GetDirectoryName(dumpLoc));
                                                        bmp.Save(dumpLoc);
                                                    }

                                                    // Register
                                                    texProvider.addTexture(-1, Path.Combine(dataDirRaw, dumpPath));
                                                    wmoTexMap.Add(node.Key, texProvider.LastIndex);
                                                }

                                                Formats.WMO.Chunk_MOGN wmoNameChunk = (Formats.WMO.Chunk_MOGN)wmo.getChunk(Formats.WMO.Chunk_MOGN.Magic);
                                                Formats.WMO.Chunk_MOMT wmoMatChunk = (Formats.WMO.Chunk_MOMT)wmo.getChunk(Formats.WMO.Chunk_MOMT.Magic);

                                                foreach (Chunk_Base rawChunk in wmo.getChunksByID(Formats.WMO.Chunk_MOGP.Magic))
                                                {
                                                    Formats.WMO.Chunk_MOGP chunk = (Formats.WMO.Chunk_MOGP)rawChunk;
                                                    string meshName = wmoNameChunk.data.get((int)chunk.groupNameIndex);

                                                    // Skip antiportals.
                                                    if (meshName.ToLower().Equals("antiportal"))
                                                        continue;

                                                    Mesh mesh = new Mesh(string.Format("WMO{0}_{1}", wmoIndex, meshName));

                                                    // Populate mesh with vertices.
                                                    Formats.WMO.Chunk_MOVT vertChunk = (Formats.WMO.Chunk_MOVT)chunk.getChunk(Formats.WMO.Chunk_MOVT.Magic);
                                                    foreach (Position vertPos in vertChunk.vertices)
                                                        mesh.addVert(new Position(entry.position.X + vertPos.X, entry.position.Y + vertPos.Y, entry.position.Z + vertPos.Z));

                                                    // Populate mesh with UVs.
                                                    Formats.WMO.Chunk_MOTV uvChunk = (Formats.WMO.Chunk_MOTV)chunk.getChunk(Formats.WMO.Chunk_MOTV.Magic);
                                                    foreach (UV uv in uvChunk.uvData)
                                                        mesh.addUV(uv);

                                                    // Populate mesh with normals.
                                                    Formats.WMO.Chunk_MONR normChunk = (Formats.WMO.Chunk_MONR)chunk.getChunk(Formats.WMO.Chunk_MONR.Magic);
                                                    foreach (Position norm in normChunk.normals)
                                                        mesh.addNormal(norm);

                                                    // Populate mesh with triangles (faces).
                                                    Formats.WMO.Chunk_MOVI faceChunk = (Formats.WMO.Chunk_MOVI)chunk.getChunk(Formats.WMO.Chunk_MOVI.Magic);
                                                    Formats.WMO.Chunk_MOPY faceMatChunk = (Formats.WMO.Chunk_MOPY)chunk.getChunk(Formats.WMO.Chunk_MOPY.Magic);

                                                    for (int i = 0; i < faceChunk.positions.Length; i++)
                                                    {
                                                        Formats.WMO.FacePosition position = faceChunk.positions[i];
                                                        Formats.WMO.FaceInfo info = faceMatChunk.faceInfo[i];

                                                        if (info.materialID != 0xFF) // 0xFF (255) identifies a collision face.
                                                        {
                                                            Material mat = wmoMatChunk.materials[info.materialID];
                                                            uint texID = (uint)wmoTexMap[(int)mat.texture1.offset];

                                                            mesh.addFace(texID, mat.texture2.colour, position.point1, position.point2, position.point3);
                                                        }
                                                    }

                                                    Log.Write("CreateWMOMesh (ADT): " + mesh.ToAdvancedString());
                                                    ob.addMesh(mesh);
                                                }
                                            }
                                        }
                                    }
                                }
                                catch (ADTException ex)
                                {
                                    LogWrite("Unable to process tile {0},{1} due to exception: {2}", x, y, ex.Message);
                                    LogWrite(ex.StackTrace);
                                }
                            }
                        }
                    }

                    EventManager.Trigger_LoadingPrompt(new Random().Next(100) == 42 ? "Reticulating splines..." : "Writing terrain data to file...");

                    ob.Write();
                    ob.Close();
                }

                // Job's done.
                EventManager.Trigger_MapExportDone(true);
            }
            catch (Exception e)
            {
                ob.Close();
                EventManager.Trigger_MapExportDone(false, e.Message + e.StackTrace);
            }
        }
Example #9
0
 private void PreviewBlp(string fullName)
 {
     var stream = cascHandler.OpenFile(fullName, LocaleFlags.All);
     var blp = new BlpFile(stream);
     var bitmap = blp.GetBitmap(0);
     var form = new ImagePreviewForm(bitmap);
     form.Show();
 }
Example #10
0
        public override void Work()
        {
            MapCanvasTile[,] tiles = canvas.Images;
            int rowCount = tiles.GetLength(1);
            int colCount = tiles.GetLength(0);

            ImageInfo info = new ImageInfo((colCount * canvas.MaxTiles) * 256, (rowCount * canvas.MaxTiles) * 256, 8, false);
            PngWriter writer = new PngWriter(File.OpenWrite(fileName), info);

            int lineOfs = 0;
            int tileLines = 256 * canvas.MaxTiles;
            int canvasCols = (colCount * canvas.MaxTiles) * 256;

            for (int tileY = 0; tileY < rowCount; tileY++)
            {
                Color[,] rows = new Color[tileLines, canvasCols];
                for (int tileX = 0; tileX < colCount; tileX++)
                {
                    List<MapCanvasTile.SubTile> subTiles = tiles[tileX, tileY].tiles;
                    subTiles.Sort((a, b) => a.CompareTo(b));

                    for (int subTileY = 0; subTileY < canvas.MaxTiles; subTileY++)
                    {
                        for (int subTileX = 0; subTileX < canvas.MaxTiles; subTileX++)
                        {
                            int subTileIndex = (subTileX * canvas.MaxTiles) + subTileY;

                            if (subTileIndex < subTiles.Count)
                            {
                                using (BlpFile blp = new BlpFile(File.OpenRead(subTiles[subTileIndex].File)))
                                using (Bitmap bmp = blp.GetBitmap(0))
                                {
                                    for (int pY = 0; pY < 256; pY++)
                                        for (int pX = 0; pX < 256; pX++)
                                            rows[pY + (subTileY * 256), pX + (subTileX * 256) + (tileX * (256 * canvas.MaxTiles))] = bmp.GetPixel(pX, pY);
                                }
                            }
                        }
                    }
                }

                for (int iLine = 0; iLine < tileLines; iLine++)
                {
                    byte[] compRow = new byte[canvasCols * 3];
                    for (int iCol = 0; iCol < canvasCols; iCol++)
                    {
                        Color color = rows[iLine, iCol];
                        int ofs = 3 * iCol;

                        compRow[ofs] = color.R;
                        compRow[ofs + 1] = color.G;
                        compRow[ofs + 2] = color.B;
                    }

                    writer.WriteRowByte(compRow, lineOfs);
                    lineOfs++;
                }
            }

            writer.End();
            EventManager.Trigger_MapExportDone2D();
        }